[Re-landing] Prepare LLInt code to support pointer profiling.
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Mar 2018 21:35:17 +0000 (21:35 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Mar 2018 21:35:17 +0000 (21:35 +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@229481 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 83da610..e92475d 100644 (file)
@@ -1,5 +1,60 @@
 2018-03-09  Mark Lam  <mark.lam@apple.com>
 
+        [Re-landing] 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-09  Mark Lam  <mark.lam@apple.com>
+
         Remove unused LLINT_STATS feature.
         https://bugs.webkit.org/show_bug.cgi?id=183522
         <rdar://problem/38313139>
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 e72d3eb..2a025a6 100644 (file)
@@ -58,9 +58,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)
 }
 
index 6cec5fe..63605df 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "JSCJSValue.h"
 #include "Opcode.h"
-#include <wtf/PointerPreparations.h>
+#include "PtrTag.h"
 
 namespace JSC {
 
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 69708e3..9069938 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 03db18a..533a3da 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
@@ -1386,10 +1387,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);
@@ -1398,10 +1400,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);
 
@@ -1416,10 +1420,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);
     }
 
@@ -1435,12 +1442,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)
@@ -1580,7 +1589,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 d2770a1..76cb1ff 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
@@ -834,22 +845,22 @@ macro traceExecution()
     end
 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
@@ -884,6 +895,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
 
@@ -893,8 +909,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)
@@ -904,9 +921,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
 
@@ -988,6 +1009,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
@@ -1022,7 +1044,7 @@ macro prologue(codeBlockGetter, codeBlockSetter, osrSlowPath, traceSlowPath)
         else
             pop cfr
         end
-        jmp r0
+        jmp r0, CodeEntryPtrTag
     .recover:
         codeBlockGetter(t1, t2)
     .continue:
@@ -1140,7 +1162,7 @@ else
     global _vmEntryToJavaScript
     _vmEntryToJavaScript:
 end
-    doVMEntry(makeJavaScriptCall)
+    doVMEntry(makeJavaScriptCall, CodeEntryPtrTag, CodeEntryWithArityCheckPtrTag)
 
 
 if C_LOOP
@@ -1149,13 +1171,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
@@ -1173,7 +1196,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]
@@ -1182,6 +1205,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 8401e0a..3144341 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 0280d0c..60ff43d 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..eed35f5
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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 f65ef77..23e349c 100644 (file)
@@ -1,3 +1,13 @@
+2018-03-09  Mark Lam  <mark.lam@apple.com>
+
+        [Re-landing] 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-08  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r229354 and r229364.
index 0ab46ab..921a108 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))