Prepare LLInt code to support pointer profiling.
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Mar 2018 06:44:46 +0000 (06:44 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Mar 2018 06:44:46 +0000 (06:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=183387
<rdar://problem/38199678>

Reviewed by JF Bastien.

Source/JavaScriptCore:

1. Introduced PtrTag enums for supporting pointer profiling later.

2. Also introduced tagging, untagging, retagging, and tag removal placeholder
   template functions for the same purpose.

3. Prepare the offlineasm for supporting pointer profiling later.

4. Tagged some pointers in LLInt asm code.  Currently, these should have no
   effect on behavior.

5. Removed returnToThrowForThrownException() because it is not used anywhere.

6. Added the offlineasm folder to JavaScriptCore Xcode project so that it's
   easier to view and edit these files in Xcode.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/LLIntCallLinkInfo.h:
(JSC::LLIntCallLinkInfo::unlink):
* llint/LLIntData.cpp:
(JSC::LLInt::initialize):
* llint/LLIntData.h:
* llint/LLIntExceptions.cpp:
(JSC::LLInt::returnToThrowForThrownException): Deleted.
* llint/LLIntExceptions.h:
* llint/LLIntOfflineAsmConfig.h:
* llint/LLIntOffsetsExtractor.cpp:
* llint/LLIntPCRanges.h:
(JSC::LLInt::isLLIntPC):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
(JSC::LLInt::handleHostCall):
(JSC::LLInt::setUpCall):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* offlineasm/ast.rb:
* offlineasm/instructions.rb:
* offlineasm/risc.rb:
* runtime/PtrTag.h: Added.
(JSC::uniquePtrTagID):
(JSC::ptrTag):
(JSC::tagCodePtr):
(JSC::untagCodePtr):
(JSC::retagCodePtr):
(JSC::removeCodePtrTag):

Source/WTF:

* wtf/Platform.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@229354 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/bytecode/LLIntCallLinkInfo.h
Source/JavaScriptCore/llint/LLIntData.cpp
Source/JavaScriptCore/llint/LLIntData.h
Source/JavaScriptCore/llint/LLIntExceptions.cpp
Source/JavaScriptCore/llint/LLIntExceptions.h
Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
Source/JavaScriptCore/llint/LLIntPCRanges.h
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
Source/JavaScriptCore/offlineasm/ast.rb
Source/JavaScriptCore/offlineasm/instructions.rb
Source/JavaScriptCore/offlineasm/risc.rb
Source/JavaScriptCore/runtime/PtrTag.h [new file with mode: 0644]
Source/WTF/ChangeLog
Source/WTF/wtf/Platform.h

index eda5eeb..0419500 100644 (file)
@@ -838,6 +838,7 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS
     runtime/Operations.h
     runtime/Options.h
     runtime/ParseInt.h
+    runtime/PtrTag.h
     runtime/PrivateName.h
     runtime/ProgramExecutable.h
     runtime/PromiseDeferredTimer.h
index 5acfda2..20b5994 100644 (file)
@@ -1,3 +1,58 @@
+2018-03-06  Mark Lam  <mark.lam@apple.com>
+
+        Prepare LLInt code to support pointer profiling.
+        https://bugs.webkit.org/show_bug.cgi?id=183387
+        <rdar://problem/38199678>
+
+        Reviewed by JF Bastien.
+
+        1. Introduced PtrTag enums for supporting pointer profiling later.
+
+        2. Also introduced tagging, untagging, retagging, and tag removal placeholder
+           template functions for the same purpose.
+
+        3. Prepare the offlineasm for supporting pointer profiling later.
+
+        4. Tagged some pointers in LLInt asm code.  Currently, these should have no
+           effect on behavior.
+
+        5. Removed returnToThrowForThrownException() because it is not used anywhere.
+
+        6. Added the offlineasm folder to JavaScriptCore Xcode project so that it's
+           easier to view and edit these files in Xcode.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/LLIntCallLinkInfo.h:
+        (JSC::LLIntCallLinkInfo::unlink):
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::initialize):
+        * llint/LLIntData.h:
+        * llint/LLIntExceptions.cpp:
+        (JSC::LLInt::returnToThrowForThrownException): Deleted.
+        * llint/LLIntExceptions.h:
+        * llint/LLIntOfflineAsmConfig.h:
+        * llint/LLIntOffsetsExtractor.cpp:
+        * llint/LLIntPCRanges.h:
+        (JSC::LLInt::isLLIntPC):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        (JSC::LLInt::handleHostCall):
+        (JSC::LLInt::setUpCall):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * offlineasm/ast.rb:
+        * offlineasm/instructions.rb:
+        * offlineasm/risc.rb:
+        * runtime/PtrTag.h: Added.
+        (JSC::uniquePtrTagID):
+        (JSC::ptrTag):
+        (JSC::tagCodePtr):
+        (JSC::untagCodePtr):
+        (JSC::retagCodePtr):
+        (JSC::removeCodePtrTag):
+
 2018-03-06  Dominik Infuehr  <dinfuehr@igalia.com>
 
         [ARM] Assembler warnings: "use of r13 is deprecated"
index 9dd2b98..232e1c4 100644 (file)
                FE63DD541EA9B61E00103A69 /* Printer.h in Headers */ = {isa = PBXBuildFile; fileRef = FE63DD531EA9B60E00103A69 /* Printer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FE6491371D78F01D00A694D4 /* ExceptionScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6491361D78F01300A694D4 /* ExceptionScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FE68C6371B90DE040042BCB3 /* MacroAssemblerPrinter.h in Headers */ = {isa = PBXBuildFile; fileRef = FE68C6361B90DDD90042BCB3 /* MacroAssemblerPrinter.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               FE6C1E4A20366F0100BDC2B7 /* PtrTag.h in Headers */ = {isa = PBXBuildFile; fileRef = FE9AE1C82032C887002B6934 /* PtrTag.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FE6F56DE1E64EAD600D17801 /* VMTraps.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6F56DD1E64E92000D17801 /* VMTraps.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FE7C41961B97FC4B00F4D598 /* PingPongStackOverflowTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEDA50D41B97F442009A3B4F /* PingPongStackOverflowTest.cpp */; };
                FE80C1971D775CDD008510C0 /* CatchScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80C1961D775B27008510C0 /* CatchScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FE98B5B61BB9AE110073E7A6 /* JITSubGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITSubGenerator.h; sourceTree = "<group>"; };
                FE99B2471C24B6D300C82159 /* JITNegGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITNegGenerator.cpp; sourceTree = "<group>"; };
                FE99B2481C24B6D300C82159 /* JITNegGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITNegGenerator.h; sourceTree = "<group>"; };
+               FE9AE1C82032C887002B6934 /* PtrTag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PtrTag.h; sourceTree = "<group>"; };
                FEA0861E182B7A0400F6D851 /* Breakpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Breakpoint.h; sourceTree = "<group>"; };
                FEA0861F182B7A0400F6D851 /* DebuggerPrimitives.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerPrimitives.h; sourceTree = "<group>"; };
                FEA0C4001CDD7D0E00481991 /* FunctionWhitelist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionWhitelist.cpp; sourceTree = "<group>"; };
                FEDA50D51B97F4D9009A3B4F /* PingPongStackOverflowTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PingPongStackOverflowTest.h; path = API/tests/PingPongStackOverflowTest.h; sourceTree = "<group>"; };
                FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompareAndSwapTest.cpp; path = API/tests/CompareAndSwapTest.cpp; sourceTree = "<group>"; };
                FEF040521AAEC4ED00BD28B0 /* CompareAndSwapTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompareAndSwapTest.h; path = API/tests/CompareAndSwapTest.h; sourceTree = "<group>"; };
+               FEF3475220362B1B00B7C0EF /* parser.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = parser.rb; sourceTree = "<group>"; };
+               FEF3475320362B1B00B7C0EF /* risc.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = risc.rb; sourceTree = "<group>"; };
+               FEF3475420362B1B00B7C0EF /* self_hash.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = self_hash.rb; sourceTree = "<group>"; };
+               FEF3475520362B1C00B7C0EF /* arm.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = arm.rb; sourceTree = "<group>"; };
+               FEF3475620362B1C00B7C0EF /* backends.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = backends.rb; sourceTree = "<group>"; };
+               FEF3475720362B1D00B7C0EF /* registers.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = registers.rb; sourceTree = "<group>"; };
+               FEF3475820362B1D00B7C0EF /* ast.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = ast.rb; sourceTree = "<group>"; };
+               FEF3475920362B1D00B7C0EF /* asm.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = asm.rb; sourceTree = "<group>"; };
+               FEF3475A20362B1E00B7C0EF /* cloop.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = cloop.rb; sourceTree = "<group>"; };
+               FEF3475B20362B1E00B7C0EF /* x86.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = x86.rb; sourceTree = "<group>"; };
+               FEF3475C20362B1E00B7C0EF /* mips.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = mips.rb; sourceTree = "<group>"; };
+               FEF3475D20362B1F00B7C0EF /* config.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = config.rb; sourceTree = "<group>"; };
+               FEF3475E20362B1F00B7C0EF /* instructions.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = instructions.rb; sourceTree = "<group>"; };
+               FEF3475F20362B2000B7C0EF /* opt.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = opt.rb; sourceTree = "<group>"; };
+               FEF3476020362B2100B7C0EF /* transform.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = transform.rb; sourceTree = "<group>"; };
+               FEF3476120362B2100B7C0EF /* offsets.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = offsets.rb; sourceTree = "<group>"; };
+               FEF3476220362B2200B7C0EF /* arm64.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = arm64.rb; sourceTree = "<group>"; };
+               FEF3476320362B2300B7C0EF /* settings.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = settings.rb; sourceTree = "<group>"; };
+               FEF3476420362B2300B7C0EF /* generate_offset_extractor.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = generate_offset_extractor.rb; sourceTree = "<group>"; };
                FEF49AA91EB947FE00653BDB /* MultithreadedMultiVMExecutionTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MultithreadedMultiVMExecutionTest.cpp; path = API/tests/MultithreadedMultiVMExecutionTest.cpp; sourceTree = "<group>"; };
                FEF49AAA1EB947FE00653BDB /* MultithreadedMultiVMExecutionTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MultithreadedMultiVMExecutionTest.h; path = API/tests/MultithreadedMultiVMExecutionTest.h; sourceTree = "<group>"; };
                FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringInlines.h; sourceTree = "<group>"; };
                                1429D77A0ED20D7300B89619 /* interpreter */,
                                1429D92C0ED22D7000B89619 /* jit */,
                                0F46809C14BA7F4D00BFE272 /* llint */,
+                               FEF347512036291300B7C0EF /* offlineasm */,
                                7E39D8370EC3A388003AF11A /* parser */,
                                034768DFFF38A50411DB9C8B /* Products */,
                                95AB831A0DA42C6900BC83F3 /* profiler */,
                                79B00CBB1C6AB07E0088C65D /* ProxyObject.h */,
                                79160DBB1C8E3EC8008C085A /* ProxyRevoke.cpp */,
                                79160DBC1C8E3EC8008C085A /* ProxyRevoke.h */,
+                               FE9AE1C82032C887002B6934 /* PtrTag.h */,
                                0F5780A118FE1E98001E72D9 /* PureNaN.h */,
                                0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */,
                                147B84620E6DE6B1004775A4 /* PutPropertySlot.h */,
                        path = domjit;
                        sourceTree = "<group>";
                };
+               FEF347512036291300B7C0EF /* offlineasm */ = {
+                       isa = PBXGroup;
+                       children = (
+                               FEF3475520362B1C00B7C0EF /* arm.rb */,
+                               FEF3476220362B2200B7C0EF /* arm64.rb */,
+                               FEF3475920362B1D00B7C0EF /* asm.rb */,
+                               FEF3475820362B1D00B7C0EF /* ast.rb */,
+                               FEF3475620362B1C00B7C0EF /* backends.rb */,
+                               FEF3475A20362B1E00B7C0EF /* cloop.rb */,
+                               FEF3475D20362B1F00B7C0EF /* config.rb */,
+                               FEF3476420362B2300B7C0EF /* generate_offset_extractor.rb */,
+                               FEF3475E20362B1F00B7C0EF /* instructions.rb */,
+                               FEF3475C20362B1E00B7C0EF /* mips.rb */,
+                               FEF3476120362B2100B7C0EF /* offsets.rb */,
+                               FEF3475F20362B2000B7C0EF /* opt.rb */,
+                               FEF3475220362B1B00B7C0EF /* parser.rb */,
+                               FEF3475720362B1D00B7C0EF /* registers.rb */,
+                               FEF3475320362B1B00B7C0EF /* risc.rb */,
+                               FEF3475420362B1B00B7C0EF /* self_hash.rb */,
+                               FEF3476320362B2300B7C0EF /* settings.rb */,
+                               FEF3476020362B2100B7C0EF /* transform.rb */,
+                               FEF3475B20362B1E00B7C0EF /* x86.rb */,
+                       );
+                       path = offlineasm;
+                       sourceTree = "<group>";
+               };
 /* End PBXGroup section */
 
 /* Begin PBXHeadersBuildPhase section */
                                0FEC85721BDACDC70080FF74 /* AirBasicBlock.h in Headers */,
                                0F2C63BC1E63440C00C13839 /* AirBlockInsertionSet.h in Headers */,
                                0FB3878E1BFBC44D00E3AB1E /* AirBlockWorklist.h in Headers */,
+                               FE6C1E4A20366F0100BDC2B7 /* PtrTag.h in Headers */,
                                0F79C7CA1E74C93B00EB34D1 /* AirBreakCriticalEdges.h in Headers */,
                                0F61832A1C45BF070072450B /* AirCCallingConvention.h in Headers */,
                                0FEC85741BDACDC70080FF74 /* AirCCallSpecial.h in Headers */,
index 8d0b860..b41e2ca 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -27,6 +27,7 @@
 
 #include "JSFunction.h"
 #include "MacroAssemblerCodeRef.h"
+#include "PtrTag.h"
 #include <wtf/SentinelLinkedList.h>
 
 namespace JSC {
@@ -50,6 +51,7 @@ struct LLIntCallLinkInfo : public BasicRawSentinelNode<LLIntCallLinkInfo> {
     {
         callee.clear();
         machineCodeTarget = MacroAssemblerCodePtr();
+        callPtrTag = NoPtrTag;
         if (isOnList())
             remove();
     }
@@ -57,6 +59,7 @@ struct LLIntCallLinkInfo : public BasicRawSentinelNode<LLIntCallLinkInfo> {
     WriteBarrier<JSObject> callee;
     WriteBarrier<JSObject> lastSeenCallee;
     MacroAssemblerCodePtr machineCodeTarget;
+    PtrTag callPtrTag { NoPtrTag };
 };
 
 } // namespace JSC
index 3a1ea37..a27fbc1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -63,9 +63,46 @@ void initialize()
 #else // ENABLE(JIT)
     llint_entry(&Data::s_opcodeMap);
 
+    for (int i = 0; i < NUMBER_OF_BYTECODE_IDS; ++i) {
+        PtrTag tag = (i == op_catch) ? ExceptionHandlerPtrTag : BytecodePtrTag;
+        Data::s_opcodeMap[i] = tagCodePtr(Data::s_opcodeMap[i], tag);
+    }
+
+    if (VM::canUseJIT()) {
+        for (int i = NUMBER_OF_BYTECODE_IDS; i < NUMBER_OF_BYTECODE_IDS + NUMBER_OF_BYTECODE_HELPER_IDS; ++i)
+            Data::s_opcodeMap[i] = tagCodePtr(Data::s_opcodeMap[i], ptrTag(BytecodeHelperPtrTag, i));
+    } else {
+        static const PtrTag tagsForOpcode[] = {
+            CodeEntryPtrTag, // llint_program_prologue
+            CodeEntryPtrTag, // llint_eval_prologue
+            CodeEntryPtrTag, // llint_module_program_prologue
+            CodeEntryPtrTag, // llint_function_for_call_prologue
+            CodeEntryPtrTag, // llint_function_for_construct_prologue
+            CodeEntryWithArityCheckPtrTag, // llint_function_for_call_arity_check
+            CodeEntryWithArityCheckPtrTag, // llint_function_for_construct_arity_check
+            CodeEntryPtrTag, // llint_generic_return_point
+            BytecodePtrTag, // llint_throw_from_slow_path_trampoline
+            CodeEntryPtrTag, // llint_throw_during_call_trampoline
+            NativeCodePtrTag, // llint_native_call_trampoline
+            NativeCodePtrTag, // llint_native_construct_trampoline
+            InternalFunctionPtrTag, // llint_internal_function_call_trampoline
+            InternalFunctionPtrTag, // llint_internal_function_construct_trampoline
+            ExceptionHandlerPtrTag, // handleUncaughtException
+        };
+
+        static_assert(sizeof(tagsForOpcode) / sizeof(tagsForOpcode[0]) == NUMBER_OF_BYTECODE_HELPER_IDS, "");
+        static_assert(static_cast<uintptr_t>(llint_program_prologue) == NUMBER_OF_BYTECODE_IDS, "");
+
+        for (int i = 0; i < NUMBER_OF_BYTECODE_HELPER_IDS; ++i) {
+            int opcodeID = i + NUMBER_OF_BYTECODE_IDS;
+            Data::s_opcodeMap[opcodeID] = tagCodePtr(Data::s_opcodeMap[opcodeID], tagsForOpcode[i]);
+        }
+    }
+
+    void* handler = LLInt::getCodePtr(llint_throw_from_slow_path_trampoline);
     for (int i = 0; i < maxOpcodeLength + 1; ++i)
-        Data::s_exceptionInstructions[i].u.pointer =
-            LLInt::getCodePtr(llint_throw_from_slow_path_trampoline);
+        Data::s_exceptionInstructions[i].u.pointer = handler;
+
 #endif // ENABLE(JIT)
 
 #if ENABLE(LLINT_STATS)
index 301d077..3fe6626 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "JSCJSValue.h"
 #include "Opcode.h"
+#include "PtrTag.h"
 #include <array>
 #include <wtf/PointerPreparations.h>
 
index e0fbf8b..e6490d7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC { namespace LLInt {
 
-Instruction* returnToThrowForThrownException(ExecState* exec)
-{
-    UNUSED_PARAM(exec);
-    return LLInt::exceptionInstructions();
-}
-
 Instruction* returnToThrow(ExecState* exec)
 {
     UNUSED_PARAM(exec);
index 149f4e8..2b73602 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,10 +34,6 @@ struct Instruction;
 
 namespace LLInt {
 
-// Tells you where to jump to if you want to return-to-throw, after you've already
-// set up all information needed to throw the exception.
-Instruction* returnToThrowForThrownException(ExecState*);
-
 // Gives you a PC that you can tell the interpreter to go to, which when advanced
 // between 1 and 9 slots will give you an "instruction" that threads to the
 // interpreter's exception handler.
index e4f0203..21c2a94 100644 (file)
 #define OFFLINE_ASM_EXECUTION_TRACING 0
 #endif
 
+#if USE(POINTER_PROFILING)
+#define OFFLINE_ASM_POINTER_PROFILING 1
+#else
+#define OFFLINE_ASM_POINTER_PROFILING 0
+#endif
+
 #define OFFLINE_ASM_GIGACAGE_ENABLED GIGACAGE_ENABLED
index 56aced7..30f6054 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2015-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -51,6 +51,7 @@
 #include "MarkedSpace.h"
 #include "NativeExecutable.h"
 #include "ProtoCallFrame.h"
+#include "PtrTag.h"
 #include "ShadowChicken.h"
 #include "Structure.h"
 #include "StructureChain.h"
index 7be54ed..0ef0aa8 100644 (file)
@@ -25,7 +25,7 @@
 
 #pragma once
 
-#include <wtf/PointerPreparations.h>
+#include "PtrTag.h"
 
 namespace JSC {
 
@@ -40,8 +40,8 @@ extern "C" {
 ALWAYS_INLINE bool isLLIntPC(void* pc)
 {
     uintptr_t pcAsInt = bitwise_cast<uintptr_t>(pc);
-    uintptr_t llintStart = bitwise_cast<uintptr_t>(WTF_PREPARE_FUNCTION_POINTER_FOR_EXECUTION(llintPCRangeStart));
-    uintptr_t llintEnd = bitwise_cast<uintptr_t>(WTF_PREPARE_FUNCTION_POINTER_FOR_EXECUTION(llintPCRangeEnd));
+    uintptr_t llintStart = untagCodePtr<uintptr_t>(llintPCRangeStart, CFunctionPtrTag);
+    uintptr_t llintEnd = untagCodePtr<uintptr_t>(llintPCRangeEnd, CFunctionPtrTag);
     RELEASE_ASSERT(llintStart < llintEnd);
     return llintStart <= pcAsInt && pcAsInt <= llintEnd;
 }
index 7b3601c..add62b9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -159,12 +159,13 @@ namespace JSC { namespace LLInt {
         JSValue::encode(value);                  \
     } while (false)
 
-#define LLINT_CALL_END_IMPL(exec, callTarget) LLINT_RETURN_TWO((callTarget), (exec))
+#define LLINT_CALL_END_IMPL(exec, callTarget, callTargetTag) \
+    LLINT_RETURN_TWO(retagCodePtr((callTarget), callTargetTag, SlowPathPtrTag), (exec))
 
 #define LLINT_CALL_THROW(exec, exceptionToThrow) do {                   \
         ExecState* __ct_exec = (exec);                                  \
         throwException(__ct_exec, throwScope, exceptionToThrow);        \
-        LLINT_CALL_END_IMPL(0, callToThrow(__ct_exec));                 \
+        LLINT_CALL_END_IMPL(0, callToThrow(__ct_exec), ExceptionHandlerPtrTag);                 \
     } while (false)
 
 #define LLINT_CALL_CHECK_EXCEPTION(exec, execCallee) do {               \
@@ -172,15 +173,15 @@ namespace JSC { namespace LLInt {
         ExecState* __cce_execCallee = (execCallee);                     \
         doExceptionFuzzingIfEnabled(__cce_exec, throwScope, "LLIntSlowPaths/call", nullptr); \
         if (UNLIKELY(throwScope.exception()))                           \
-            LLINT_CALL_END_IMPL(0, callToThrow(__cce_execCallee));      \
+            LLINT_CALL_END_IMPL(0, callToThrow(__cce_execCallee), ExceptionHandlerPtrTag); \
     } while (false)
 
-#define LLINT_CALL_RETURN(exec, execCallee, callTarget) do {            \
+#define LLINT_CALL_RETURN(exec, execCallee, callTarget, callTargetTag) do { \
         ExecState* __cr_exec = (exec);                                  \
         ExecState* __cr_execCallee = (execCallee);                      \
         void* __cr_callTarget = (callTarget);                           \
         LLINT_CALL_CHECK_EXCEPTION(__cr_exec, __cr_execCallee);         \
-        LLINT_CALL_END_IMPL(__cr_execCallee, __cr_callTarget);          \
+        LLINT_CALL_END_IMPL(__cr_execCallee, __cr_callTarget, callTargetTag); \
     } while (false)
 
 #define LLINT_RETURN_CALLEE_FRAME(execCallee) do {                      \
@@ -283,7 +284,7 @@ LLINT_SLOW_PATH_DECL(trace)
             opcodeNames[opcodeID], pc);
     if (opcodeID == op_enter) {
         dataLogF("Frame will eventually return to %p\n", exec->returnPC().value());
-        *bitwise_cast<volatile char*>(exec->returnPC().value());
+        *removeCodePtrTag<volatile char*>(exec->returnPC().value());
     }
     if (opcodeID == op_ret) {
         dataLogF("Will be returning to %p\n", exec->returnPC().value());
@@ -1325,7 +1326,7 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc,
             vm.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
             
             PoisonedMasmPtr::assertIsNotPoisoned(LLInt::getCodePtr(getHostCallReturnValue));
-            LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
+            LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue), CFunctionPtrTag);
         }
         
 #if LLINT_SLOW_PATH_TRACING
@@ -1349,7 +1350,7 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc,
         vm.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
 
         PoisonedMasmPtr::assertIsNotPoisoned(LLInt::getCodePtr(getHostCallReturnValue));
-        LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
+        LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue), CFunctionPtrTag);
     }
     
 #if LLINT_SLOW_PATH_TRACING
@@ -1387,10 +1388,11 @@ inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, Code
                 callLinkInfo->callee.set(vm, callerCodeBlock, internalFunction);
                 callLinkInfo->lastSeenCallee.set(vm, callerCodeBlock, internalFunction);
                 callLinkInfo->machineCodeTarget = codePtr;
+                callLinkInfo->callPtrTag = InternalFunctionPtrTag;
             }
 
             PoisonedMasmPtr::assertIsNotPoisoned(codePtr.executableAddress());
-            LLINT_CALL_RETURN(exec, execCallee, codePtr.executableAddress());
+            LLINT_CALL_RETURN(exec, execCallee, codePtr.executableAddress(), InternalFunctionPtrTag);
         }
         throwScope.release();
         return handleHostCall(execCallee, pc, calleeAsValue, kind);
@@ -1399,10 +1401,12 @@ inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, Code
     JSScope* scope = callee->scopeUnchecked();
     ExecutableBase* executable = callee->executable();
 
+    PtrTag callPtrTag = NoPtrTag;
     MacroAssemblerCodePtr codePtr;
     CodeBlock* codeBlock = 0;
     if (executable->isHostFunction()) {
         codePtr = executable->entrypointFor(kind, MustCheckArity);
+        callPtrTag = NativeCodePtrTag;
     } else {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
 
@@ -1417,10 +1421,13 @@ inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, Code
         codeBlock = *codeBlockSlot;
         ASSERT(codeBlock);
         ArityCheckMode arity;
-        if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
+        if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters())) {
             arity = MustCheckArity;
-        else
+            callPtrTag = CodeEntryWithArityCheckPtrTag;
+        } else {
             arity = ArityCheckNotRequired;
+            callPtrTag = CodeEntryPtrTag;
+        }
         codePtr = functionExecutable->entrypointFor(kind, arity);
     }
 
@@ -1436,12 +1443,14 @@ inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, Code
         callLinkInfo->callee.set(vm, callerCodeBlock, callee);
         callLinkInfo->lastSeenCallee.set(vm, callerCodeBlock, callee);
         callLinkInfo->machineCodeTarget = codePtr;
+        RELEASE_ASSERT(callPtrTag != NoPtrTag);
+        callLinkInfo->callPtrTag = callPtrTag;
         if (codeBlock)
             codeBlock->linkIncomingCall(exec, callLinkInfo);
     }
 
     PoisonedMasmPtr::assertIsNotPoisoned(codePtr.executableAddress());
-    LLINT_CALL_RETURN(exec, execCallee, codePtr.executableAddress());
+    LLINT_CALL_RETURN(exec, execCallee, codePtr.executableAddress(), callPtrTag);
 }
 
 inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
@@ -1581,7 +1590,7 @@ LLINT_SLOW_PATH_DECL(slow_path_call_eval)
     }
     
     vm.hostCallReturnValue = eval(execCallee);
-    LLINT_CALL_RETURN(exec, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
+    LLINT_CALL_RETURN(exec, execCallee, LLInt::getCodePtr(getHostCallReturnValue), CFunctionPtrTag);
 }
 
 LLINT_SLOW_PATH_DECL(slow_path_strcat)
index e3dd008..098e4c4 100644 (file)
@@ -260,6 +260,16 @@ const ArithProfileNumberInt = 0x880000
 const ArithProfileNumberNumber = 0x900000
 const ArithProfileIntNumber = 0x500000
 
+# Pointer Tags
+const BytecodePtrTag = constexpr BytecodePtrTag
+const CodeEntryPtrTag = constexpr CodeEntryPtrTag
+const CodeEntryWithArityCheckPtrTag = constexpr CodeEntryWithArityCheckPtrTag
+const ExceptionHandlerPtrTag = constexpr ExceptionHandlerPtrTag
+const InternalFunctionPtrTag = constexpr InternalFunctionPtrTag
+const NativeCodePtrTag = constexpr NativeCodePtrTag
+const NoPtrTag = constexpr NoPtrTag
+const SlowPathPtrTag = constexpr SlowPathPtrTag
+
 # Some register conventions.
 if JSVALUE64
     # - Use a pair of registers to represent the PC: one register for the
@@ -785,6 +795,7 @@ macro unpoison(poison, field, scratch)
 end
 
 macro functionPrologue()
+    tagReturnAddress sp
     if X86 or X86_WIN or X86_64 or X86_64_WIN
         push cfr
     elsif ARM64
@@ -848,22 +859,22 @@ macro callOpcodeSlowPath(slowPath)
     callSlowPath(slowPath)
 end
 
-macro callTargetFunction(callee)
+macro callTargetFunction(callee, callPtrTag)
     if C_LOOP
         cloopCallJSFunction callee
     else
-        call callee
+        call callee, callPtrTag
     end
     restoreStackPointerAfterCall()
     dispatchAfterCall()
 end
 
-macro prepareForRegularCall(callee, temp1, temp2, temp3)
+macro prepareForRegularCall(callee, temp1, temp2, temp3, prepareCallPtrTag)
     addp CallerFrameAndPCSize, sp
 end
 
 # sp points to the new frame
-macro prepareForTailCall(callee, temp1, temp2, temp3)
+macro prepareForTailCall(callee, temp1, temp2, temp3, prepareCallPtrTag)
     restoreCalleeSavesUsedByLLInt()
 
     loadi PayloadOffset + ArgumentCount[cfr], temp2
@@ -898,6 +909,11 @@ macro prepareForTailCall(callee, temp1, temp2, temp3)
         storep temp3, [sp]
     end
 
+    if POINTER_PROFILING
+        addp 16, cfr, temp3
+        untagReturnAddress temp3
+    end
+
     subp temp2, temp1
     loadp [cfr], cfr
 
@@ -907,8 +923,9 @@ macro prepareForTailCall(callee, temp1, temp2, temp3)
     storep temp3, [temp1, temp2, 1]
     btinz temp2, .copyLoop
 
+    prepareCallPtrTag(temp2)
     move temp1, sp
-    jmp callee
+    jmp callee, temp2
 end
 
 macro slowPathForCall(slowPath, prepareCall)
@@ -919,9 +936,13 @@ macro slowPathForCall(slowPath, prepareCall)
         macro (callee, calleeFramePtr)
             btpz calleeFramePtr, .dontUpdateSP
             move calleeFramePtr, sp
-            prepareCall(callee, t2, t3, t4)
+            prepareCall(callee, t2, t3, t4, macro (callPtrTagReg)
+                if POINTER_PROFILING
+                    move SlowPathPtrTag, callPtrTagReg
+                end
+            end)
         .dontUpdateSP:
-            callTargetFunction(callee)
+            callTargetFunction(callee, SlowPathPtrTag)
         end)
 end
 
@@ -1003,6 +1024,7 @@ end
 # in t1. May also trigger prologue entry OSR.
 macro prologue(codeBlockGetter, codeBlockSetter, osrSlowPath, traceSlowPath)
     # Set up the call frame and check if we should OSR.
+    tagReturnAddress sp
     preserveCallerPCAndCFR()
 
     if EXECUTION_TRACING
@@ -1037,7 +1059,7 @@ macro prologue(codeBlockGetter, codeBlockSetter, osrSlowPath, traceSlowPath)
         else
             pop cfr
         end
-        jmp r0
+        jmp r0, CodeEntryPtrTag
     .recover:
         codeBlockGetter(t1, t2)
     .continue:
@@ -1143,7 +1165,7 @@ else
     global _vmEntryToJavaScript
     _vmEntryToJavaScript:
 end
-    doVMEntry(makeJavaScriptCall)
+    doVMEntry(makeJavaScriptCall, CodeEntryPtrTag, CodeEntryWithArityCheckPtrTag)
 
 
 if C_LOOP
@@ -1152,13 +1174,14 @@ else
     global _vmEntryToNative
     _vmEntryToNative:
 end
-    doVMEntry(makeHostFunctionCall)
+    doVMEntry(makeHostFunctionCall, NativeCodePtrTag, NativeCodePtrTag)
 
 
 if not C_LOOP
     # void sanitizeStackForVMImpl(VM* vm)
     global _sanitizeStackForVMImpl
     _sanitizeStackForVMImpl:
+        tagReturnAddress sp
         # We need three non-aliased caller-save registers. We are guaranteed
         # this for a0, a1 and a2 on all architectures.
         if X86 or X86_WIN
@@ -1176,7 +1199,7 @@ if not C_LOOP
         storep zeroValue, [address]
         addp PtrSize, address
         bpa sp, address, .zeroFillLoop
-    
+
     .zeroFillDone:
         move sp, address
         storep address, VM::m_lastStackTop[vm]
@@ -1185,6 +1208,7 @@ if not C_LOOP
     # VMEntryRecord* vmEntryRecord(const EntryFrame* entryFrame)
     global _vmEntryRecord
     _vmEntryRecord:
+        tagReturnAddress sp
         if X86 or X86_WIN
             loadp 4[sp], a0
         end
index 223590a..387106a 100644 (file)
@@ -96,7 +96,7 @@ macro callSlowPath(slowPath)
     move r0, PC
 end
 
-macro doVMEntry(makeCall)
+macro doVMEntry(makeCall, unused1, unused2)
     functionPrologue()
     pushCalleeSaves()
 
@@ -1957,8 +1957,8 @@ macro doCall(slowPath, prepareCall)
     storei t2, ArgumentCount + PayloadOffset[t3]
     storei CellTag, Callee + TagOffset[t3]
     move t3, sp
-    prepareCall(LLIntCallLinkInfo::machineCodeTarget[t1], t2, t3, t4)
-    callTargetFunction(LLIntCallLinkInfo::machineCodeTarget[t1])
+    prepareCall(LLIntCallLinkInfo::machineCodeTarget[t1], t2, t3, t4, macro (callPtrTag) end)
+    callTargetFunction(LLIntCallLinkInfo::machineCodeTarget[t1], NoPtrTag)
 
 .opCallSlow:
     slowPathForCall(slowPath, prepareCall)
index c7f4701..dabdb0a 100644 (file)
@@ -24,7 +24,7 @@
 
 # Utilities.
 macro jumpToInstruction()
-    jmp [PB, PC, 8]
+    jmp [PB, PC, 8], BytecodePtrTag
 end
 
 macro dispatch(advance)
@@ -92,7 +92,7 @@ macro cCall2Void(function)
         # See http://msdn.microsoft.com/en-us/library/ms235286.aspx
         subp 32, sp 
         call function
-        addp 32, sp 
+        addp 32, sp
     else
         cCall2(function)
     end
@@ -115,7 +115,7 @@ macro cCall4(function)
     end
 end
 
-macro doVMEntry(makeCall)
+macro doVMEntry(makeCall, callTag, callWithArityCheckTag)
     functionPrologue()
     pushCalleeSaves()
 
@@ -225,7 +225,16 @@ macro doVMEntry(makeCall)
 
     checkStackPointerAlignment(extraTempReg, 0xbad0dc02)
 
-    makeCall(entry, t3)
+    if POINTER_PROFILING
+        btbnz ProtoCallFrame::hasArityMismatch[protoCallFrame], .doCallWithArityCheck
+        move callTag, t2
+        jmp .readyToCall
+    .doCallWithArityCheck:
+        move callWithArityCheckTag, t2
+    .readyToCall:
+    end
+
+    makeCall(entry, t3, t2)
 
     # We may have just made a call into a JS function, so we can't rely on sp
     # for anything but the fact that our own locals (ie the VMEntryRecord) are
@@ -249,18 +258,18 @@ macro doVMEntry(makeCall)
 end
 
 
-macro makeJavaScriptCall(entry, temp)
+macro makeJavaScriptCall(entry, temp, callTag)
     addp 16, sp
     if C_LOOP
         cloopCallJSFunction entry
     else
-        call entry
+        call entry, callTag
     end
     subp 16, sp
 end
 
 
-macro makeHostFunctionCall(entry, temp)
+macro makeHostFunctionCall(entry, temp, callTag)
     move entry, temp
     storep cfr, [sp]
     move sp, a0
@@ -270,10 +279,10 @@ macro makeHostFunctionCall(entry, temp)
     elsif X86_64_WIN
         # We need to allocate 32 bytes on the stack for the shadow space.
         subp 32, sp
-        call temp
+        call temp, callTag
         addp 32, sp
     else
-        call temp
+        call temp, callTag
     end
 end
 
@@ -370,7 +379,7 @@ macro checkSwitchToJITForLoop()
             cCall2(_llint_loop_osr)
             btpz r0, .recover
             move r1, sp
-            jmp r0
+            jmp r0, CodeEntryPtrTag
         .recover:
             loadi ArgumentCount + TagOffset[cfr], PC
         end)
@@ -543,6 +552,15 @@ macro functionArityCheck(doneLabel, slowPath)
     btiz t1, .continue
 
 .noExtraSlot:
+    if POINTER_PROFILING
+        if ARM64
+            loadp 8[cfr], lr
+        end
+
+        addp 16, cfr, t3
+        untagReturnAddress t3
+    end
+
     // Move frame up t1 slots
     negq t1
     move cfr, t3
@@ -566,6 +584,15 @@ macro functionArityCheck(doneLabel, slowPath)
     addp 8, t3
     baddinz 1, t2, .fillLoop
 
+    if POINTER_PROFILING
+        addp 16, cfr, t1
+        tagReturnAddress t1
+
+        if ARM64
+            storep lr, 8[cfr]
+        end
+    end
+
 .continue:
     # Reload CodeBlock and reset PC, since the slow_path clobbered them.
     loadp CodeBlock[cfr], t1
@@ -1956,6 +1983,9 @@ end
 macro doCall(slowPath, prepareCall)
     loadisFromInstruction(2, t0)
     loadpFromInstruction(5, t1)
+    if POINTER_PROFILING
+        move t1, t5
+    end
     loadp LLIntCallLinkInfo::callee[t1], t2
     loadConstantOrVariable(t0, t3)
     bqneq t3, t2, .opCallSlow
@@ -1971,11 +2001,25 @@ macro doCall(slowPath, prepareCall)
     if POISON
         loadp _g_JITCodePoison, t2
         xorp LLIntCallLinkInfo::machineCodeTarget[t1], t2
-        prepareCall(t2, t1, t3, t4)
-        callTargetFunction(t2)
+        prepareCall(t2, t1, t3, t4, macro (callPtrTag)
+            if POINTER_PROFILING
+                loadp LLIntCallLinkInfo::callPtrTag[t5], callPtrTag
+            end
+        end)
+               if POINTER_PROFILING
+                       loadp LLIntCallLinkInfo::callPtrTag[t5], t3
+               end
+        callTargetFunction(t2, t3)
     else
-        prepareCall(LLIntCallLinkInfo::machineCodeTarget[t1], t2, t3, t4)
-        callTargetFunction(LLIntCallLinkInfo::machineCodeTarget[t1])
+        prepareCall(LLIntCallLinkInfo::machineCodeTarget[t1], t2, t3, t4, macro (callPtrTag)
+            if POINTER_PROFILING
+                loadp LLIntCallLinkInfo::callPtrTag[t5], callPtrTag
+            end
+        end)
+               if POINTER_PROFILING
+                       loadp LLIntCallLinkInfo::callPtrTag[t5], t3
+               end
+        callTargetFunction(LLIntCallLinkInfo::machineCodeTarget[t1], t3)
     end
 
 .opCallSlow:
@@ -2075,7 +2119,7 @@ _llint_throw_from_slow_path_trampoline:
     loadp Callee[cfr], t1
     andp MarkedBlockMask, t1
     loadp MarkedBlockFooterOffset + MarkedBlock::Footer::m_vm[t1], t1
-    jmp VM::targetMachinePCForThrow[t1]
+    jmp VM::targetMachinePCForThrow[t1], ExceptionHandlerPtrTag
 
 
 _llint_throw_during_call_trampoline:
@@ -2106,12 +2150,12 @@ macro nativeCallTrampoline(executableOffsetToFunction)
     else
         if X86_64_WIN
             subp 32, sp
-            call executableOffsetToFunction[t1]
+            call executableOffsetToFunction[t1], NativeCodePtrTag
             addp 32, sp
         else
             loadp _g_NativeCodePoison, t2
             xorp executableOffsetToFunction[t1], t2
-            call t2
+            call t2, NativeCodePtrTag
         end
     end
 
@@ -2149,12 +2193,12 @@ macro internalFunctionCallTrampoline(offsetOfFunction)
     else
         if X86_64_WIN
             subp 32, sp
-            call offsetOfFunction[t1]
+            call offsetOfFunction[t1], InternalFunctionPtrTag
             addp 32, sp
         else
             loadp _g_NativeCodePoison, t2
             xorp offsetOfFunction[t1], t2
-            call t2
+            call t2, InternalFunctionPtrTag
         end
     end
 
index 7bbf053..dc92066 100644 (file)
@@ -929,6 +929,7 @@ class Instruction < Node
             $asm.putGlobalAnnotation
         when "emit"
             $asm.puts "#{operands[0].dump}"
+        when "tagReturnAddress", "untagReturnAddress"
         else
             raise "Unhandled opcode #{opcode} at #{codeOriginString}"
         end
index 9dd4dc7..72bebfe 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2011 Apple Inc. All rights reserved.
+# Copyright (C) 2011-2018 Apple Inc. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -249,7 +249,10 @@ MACRO_INSTRUCTIONS =
      "bnz",
      "leai",
      "leap",
-     "memfence"
+     "memfence",
+     "tagReturnAddress",
+     "untagReturnAddress",
+     "removeCodePtrTag"
     ]
 
 X86_INSTRUCTIONS =
index 2e06a8c..8b8de8d 100644 (file)
@@ -448,9 +448,15 @@ end
 
 def riscLowerMisplacedAddresses(list)
     newList = []
+    hasBackendSpecificLowering = Instruction.respond_to? "lowerMisplacedAddresses#{$activeBackend}"
     list.each {
         | node |
         if node.is_a? Instruction
+            if hasBackendSpecificLowering
+                wasHandled, newList = Instruction.send("lowerMisplacedAddresses#{$activeBackend}", node, newList)
+                next if wasHandled
+            end
+
             postInstructions = []
             annotation = node.annotation
             case node.opcode
diff --git a/Source/JavaScriptCore/runtime/PtrTag.h b/Source/JavaScriptCore/runtime/PtrTag.h
new file mode 100644 (file)
index 0000000..7f81d43
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/PointerPreparations.h>
+
+namespace JSC {
+
+enum PtrTag : uintptr_t {
+    NoPtrTag = 0,
+    NearCallPtrTag,
+    CFunctionPtrTag,
+
+    BytecodePtrTag,
+    BytecodeHelperPtrTag,
+    CodeEntryPtrTag,
+    CodeEntryWithArityCheckPtrTag,
+    ExceptionHandlerPtrTag,
+    InternalFunctionPtrTag,
+    JITCodePtrTag,
+    NativeCodePtrTag,
+    SlowPathPtrTag,
+};
+
+#if !USE(POINTER_PROFILING)
+inline uintptr_t uniquePtrTagID() { return 0; }
+
+template<typename... Arguments>
+inline constexpr PtrTag ptrTag(Arguments&&...) { return NoPtrTag; }
+
+template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
+inline constexpr T tagCodePtr(PtrType ptr, PtrTag) { return bitwise_cast<T>(ptr); }
+
+template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline constexpr PtrType tagCodePtr(PtrType ptr, PtrTag) { return ptr; }
+
+template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
+inline constexpr T untagCodePtr(PtrType ptr, PtrTag) { return bitwise_cast<T>(ptr); }
+
+template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline constexpr PtrType untagCodePtr(PtrType ptr, PtrTag) { return ptr; }
+
+template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
+inline constexpr T retagCodePtr(PtrType ptr, PtrTag, PtrTag) { return bitwise_cast<T>(ptr); }
+
+template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline constexpr PtrType retagCodePtr(PtrType ptr, PtrTag, PtrTag) { return ptr; }
+
+template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
+inline constexpr T removeCodePtrTag(PtrType ptr) { return bitwise_cast<T>(ptr); }
+
+template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline constexpr PtrType removeCodePtrTag(PtrType ptr) { return ptr; }
+
+#endif // !USE(POINTER_PROFILING)
+
+} // namespace JSC
+
+#if USE(APPLE_INTERNAL_SDK) && __has_include(<WebKitAdditions/PtrTagSupport.h>)
+#include <WebKitAdditions/PtrTagSupport.h>
+#endif
index 3cad798..4f82f2c 100644 (file)
@@ -1,3 +1,13 @@
+2018-03-06  Mark Lam  <mark.lam@apple.com>
+
+        Prepare LLInt code to support pointer profiling.
+        https://bugs.webkit.org/show_bug.cgi?id=183387
+        <rdar://problem/38199678>
+
+        Reviewed by JF Bastien.
+
+        * wtf/Platform.h:
+
 2018-03-06  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r229330.
index 7a01031..d8c407c 100644 (file)
 #define ENABLE_POISON 0
 #endif
 
+#if !defined(USE_POINTER_PROFILING) || USE(JSVALUE32_64) || !ENABLE(JIT)
+#undef USE_POINTER_PROFILING
+#define USE_POINTER_PROFILING 0
+#endif
+
 /* CSS Selector JIT Compiler */
 #if !defined(ENABLE_CSS_SELECTOR_JIT)
 #if (CPU(X86_64) || CPU(ARM64) || (CPU(ARM_THUMB2) && PLATFORM(IOS))) && ENABLE(JIT) && (OS(DARWIN) || PLATFORM(GTK) || PLATFORM(WPE))