We should have one calleeSaveRegistersBuffer per VMEntryFrame, not one per VM.
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 May 2016 20:16:29 +0000 (20:16 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 May 2016 20:16:29 +0000 (20:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=157537
<rdar://problem/24794845>

Reviewed by Michael Saboff.

Source/JavaScriptCore:

The pre-existing code behaves this way:

1. When JS code throws an exception, it saves callee save registers in
   the VM calleeSaveRegistersBuffer.  These values are meant to be restored
   to the callee save registers later either at the catch handler or at the
   uncaught exception handler.

2. If the Inspector is enable, the VM will invoke inspector C++ code to inspect
   the exception.  That C++ code can change the values of the callee save
   registers.

   The inspector code in turn re-enters the VM to execute JS inspector code.

   The JS inspector code can run hot enough that we do an enterOptimizationCheck
   on it.  The enterOptimizationCheck first saves all callee save registers
   into the VM calleeSaveRegistersBuffer.

   This effectively overwrites the values in the VM calleeSaveRegistersBuffer
   from (1).

3. Eventually, execution returns to the catch handler or the uncaught exception
   handler which restores the overwritten values in the VM
   calleeSaveRegistersBuffer to the callee save registers.

   When execution returns to the C++ code that entered the VM before (1), the
   values in the callee registers are not what that code expects, and badness
   and/or crashes ensues.

This patch applies the following fix:

1. Allocate space in the VMEntryFrame for the calleeSaveRegistersBuffer.
   This ensures that each VM entry session has its own buffer to use, and will
   not corrupt the one from the previous VM entry session.

   Delete the VM calleeSaveRegistersBuffer.

2. Change all locations that uses the VM calleeSaveRegistersBuffer to use the
   calleeSaveRegistersBuffer in the current VMEntryFrame.

3. Renamed all uses of the term "VMCalleeSavesBuffer" to
   "VMEntryFrameCalleeSavesBuffer".

This fix has been tested on the following configurations:
1. JSC and layout tests on a debug ASan build for 64-bit x86_64.
2. JSC tests on a release ASan build for 32-bit x86.
3. JSC tests on a release normal (non-ASan) build for ARM64.
4. JSC tests on a release normal (non-ASan) build for ARMv7 and ARMv7s.
5. JSC tests on a release ASan CLOOP build for x86_64.

These test runs did not produce any new crashes.  The ASan CLOOP has some
pre-existing crashes which are not due to this patch.

This bug can be tested by running the inspector/debugger/regress-133182.html test
on an ASan build.

* bytecode/PolymorphicAccess.cpp:
(JSC::AccessGenerationState::emitExplicitExceptionHandler):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileExceptionHandlers):
* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* dfg/DFGOSRExitCompiler.cpp:
* dfg/DFGOSRExitCompiler32_64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompiler64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGThunks.cpp:
(JSC::DFG::osrEntryThunkGenerator):
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::lower):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* interpreter/Interpreter.cpp:
(JSC::UnwindFunctor::operator()):
(JSC::UnwindFunctor::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
(JSC::UnwindFunctor::copyCalleeSavesToVMCalleeSavesBuffer): Deleted.
* interpreter/Interpreter.h:
(JSC::NativeCallFrameTracer::NativeCallFrameTracer):
* interpreter/VMEntryRecord.h:
(JSC::VMEntryRecord::calleeSaveRegistersBufferOffset):
(JSC::VMEntryRecord::prevTopCallFrame):
(JSC::VMEntryRecord::unsafePrevTopCallFrame):
(JSC::VMEntryFrame::vmEntryRecordOffset):
(JSC::VMEntryFrame::calleeSaveRegistersBufferOffset):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::emitRandomThunk):
(JSC::AssemblyHelpers::restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::restoreCalleeSavesFromVMCalleeSavesBuffer): Deleted.
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::emitRestoreSavedTagRegisters):
(JSC::AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToVMEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesToVMCalleeSavesBuffer): Deleted.
(JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToVMCalleeSavesBuffer): Deleted.
* jit/JIT.cpp:
(JSC::JIT::emitEnterOptimizationCheck):
(JSC::JIT::privateCompileExceptionHandlers):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
(JSC::JIT::emitSlow_op_loop_hint):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_throw):
(JSC::JIT::emit_op_catch):
* jit/ThunkGenerators.cpp:
(JSC::throwExceptionFromCallSlowPathGenerator):
(JSC::nativeForGenerator):
* llint/LLIntThunks.cpp:
(JSC::vmEntryRecord):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/VM.h:
(JSC::VM::getCTIStub):
(JSC::VM::calleeSaveRegistersBufferOffset): Deleted.
* wasm/WASMFunctionCompiler.h:
(JSC::WASMFunctionCompiler::endFunction):

LayoutTests:

* inspector/debugger/regress-133182-expected.txt:
- Rebased test results to update line numbers.
* platform/mac/TestExpectations:
- Unskip the test.

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

29 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/debugger/regress-133182-expected.txt
LayoutTests/platform/mac/TestExpectations
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp
Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
Source/JavaScriptCore/dfg/DFGOSREntry.cpp
Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
Source/JavaScriptCore/dfg/DFGThunks.cpp
Source/JavaScriptCore/ftl/FTLCompile.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/interpreter/Interpreter.h
Source/JavaScriptCore/interpreter/VMEntryRecord.h
Source/JavaScriptCore/jit/AssemblyHelpers.cpp
Source/JavaScriptCore/jit/AssemblyHelpers.h
Source/JavaScriptCore/jit/JIT.cpp
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/jit/ThunkGenerators.cpp
Source/JavaScriptCore/llint/LLIntThunks.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
Source/JavaScriptCore/runtime/VM.h
Source/JavaScriptCore/wasm/WASMFunctionCompiler.h

index 97ea223..af61375 100644 (file)
@@ -1,3 +1,16 @@
+2016-05-13  Mark Lam  <mark.lam@apple.com>
+
+        We should have one calleeSaveRegistersBuffer per VMEntryFrame, not one per VM.
+        https://bugs.webkit.org/show_bug.cgi?id=157537
+        <rdar://problem/24794845>
+
+        Reviewed by Michael Saboff.
+
+        * inspector/debugger/regress-133182-expected.txt:
+        - Rebased test results to update line numbers.
+        * platform/mac/TestExpectations:
+        - Unskip the test.
+
 2016-05-13  Doug Russell  <d_russell@apple.com>
 
         AX: Regressions in undo/redo accessibility from Bug 153361
index c5fdf72..6c8b12a 100644 (file)
@@ -1,44 +1,44 @@
-CONSOLE MESSAGE: line 47: [1] Testing statement '({}).a.b.c.d;'
-CONSOLE MESSAGE: line 48: [1] Paused and about to step
-CONSOLE MESSAGE: line 60: [1] Resumed
-CONSOLE MESSAGE: line 52: [1] Paused after stepping
-CONSOLE MESSAGE: line 60: [1] Resumed
+CONSOLE MESSAGE: line 56: [1] Testing statement '({}).a.b.c.d;'
+CONSOLE MESSAGE: line 57: [1] Paused and about to step
+CONSOLE MESSAGE: line 69: [1] Resumed
+CONSOLE MESSAGE: line 61: [1] Paused after stepping
+CONSOLE MESSAGE: line 69: [1] Resumed
 CONSOLE MESSAGE: line 1: TypeError: undefined is not an object (evaluating '({}).a.b')
-CONSOLE MESSAGE: line 47: [2] Testing statement 'exceptionBasic();'
-CONSOLE MESSAGE: line 48: [2] Paused and about to step
-CONSOLE MESSAGE: line 60: [2] Resumed
-CONSOLE MESSAGE: line 52: [2] Paused after stepping
-CONSOLE MESSAGE: line 60: [2] Resumed
+CONSOLE MESSAGE: line 56: [2] Testing statement 'exceptionBasic();'
+CONSOLE MESSAGE: line 57: [2] Paused and about to step
+CONSOLE MESSAGE: line 69: [2] Resumed
+CONSOLE MESSAGE: line 61: [2] Paused after stepping
+CONSOLE MESSAGE: line 69: [2] Resumed
 CONSOLE MESSAGE: line 3: TypeError: undefined is not an object (evaluating '({}).a.b')
-CONSOLE MESSAGE: line 47: [3] Testing statement 'exceptionDOM();'
-CONSOLE MESSAGE: line 48: [3] Paused and about to step
-CONSOLE MESSAGE: line 60: [3] Resumed
-CONSOLE MESSAGE: line 52: [3] Paused after stepping
-CONSOLE MESSAGE: line 60: [3] Resumed
+CONSOLE MESSAGE: line 56: [3] Testing statement 'exceptionDOM();'
+CONSOLE MESSAGE: line 57: [3] Paused and about to step
+CONSOLE MESSAGE: line 69: [3] Resumed
+CONSOLE MESSAGE: line 61: [3] Paused after stepping
+CONSOLE MESSAGE: line 69: [3] Resumed
 CONSOLE MESSAGE: line 8: NotFoundError: DOM Exception 8: An attempt was made to reference a Node in a context where it does not exist.
-CONSOLE MESSAGE: line 47: [4] Testing statement 'exceptionInHostFunction();'
-CONSOLE MESSAGE: line 48: [4] Paused and about to step
-CONSOLE MESSAGE: line 60: [4] Resumed
-CONSOLE MESSAGE: line 52: [4] Paused after stepping
-CONSOLE MESSAGE: line 60: [4] Resumed
+CONSOLE MESSAGE: line 56: [4] Testing statement 'exceptionInHostFunction();'
+CONSOLE MESSAGE: line 57: [4] Paused and about to step
+CONSOLE MESSAGE: line 69: [4] Resumed
+CONSOLE MESSAGE: line 61: [4] Paused after stepping
+CONSOLE MESSAGE: line 69: [4] Resumed
 CONSOLE MESSAGE: line 24: exception in host function
-CONSOLE MESSAGE: line 47: [5] Testing statement 'throwString();'
-CONSOLE MESSAGE: line 48: [5] Paused and about to step
-CONSOLE MESSAGE: line 60: [5] Resumed
-CONSOLE MESSAGE: line 52: [5] Paused after stepping
-CONSOLE MESSAGE: line 60: [5] Resumed
+CONSOLE MESSAGE: line 56: [5] Testing statement 'throwString();'
+CONSOLE MESSAGE: line 57: [5] Paused and about to step
+CONSOLE MESSAGE: line 69: [5] Resumed
+CONSOLE MESSAGE: line 61: [5] Paused after stepping
+CONSOLE MESSAGE: line 69: [5] Resumed
 CONSOLE MESSAGE: line 13: exception string
-CONSOLE MESSAGE: line 47: [6] Testing statement 'throwParam({x:1});'
-CONSOLE MESSAGE: line 48: [6] Paused and about to step
-CONSOLE MESSAGE: line 60: [6] Resumed
-CONSOLE MESSAGE: line 52: [6] Paused after stepping
-CONSOLE MESSAGE: line 60: [6] Resumed
+CONSOLE MESSAGE: line 56: [6] Testing statement 'throwParam({x:1});'
+CONSOLE MESSAGE: line 57: [6] Paused and about to step
+CONSOLE MESSAGE: line 69: [6] Resumed
+CONSOLE MESSAGE: line 61: [6] Paused after stepping
+CONSOLE MESSAGE: line 69: [6] Resumed
 CONSOLE MESSAGE: line 18: [object Object]
-CONSOLE MESSAGE: line 47: [7] Testing statement 'throwParam(new Error('error message'));'
-CONSOLE MESSAGE: line 48: [7] Paused and about to step
-CONSOLE MESSAGE: line 60: [7] Resumed
-CONSOLE MESSAGE: line 52: [7] Paused after stepping
-CONSOLE MESSAGE: line 60: [7] Resumed
+CONSOLE MESSAGE: line 56: [7] Testing statement 'throwParam(new Error('error message'));'
+CONSOLE MESSAGE: line 57: [7] Paused and about to step
+CONSOLE MESSAGE: line 69: [7] Resumed
+CONSOLE MESSAGE: line 61: [7] Paused after stepping
+CONSOLE MESSAGE: line 69: [7] Resumed
 CONSOLE MESSAGE: line 18: Error: error message
 Regression test for https://bugs.webkit.org/show_bug.cgi?id=133182
 
index d0a5ed1..0382aeb 100644 (file)
@@ -731,7 +731,6 @@ inspector/debugger/setBreakpoint-dfg-callee-and-examine-dfg-local.html
 inspector/debugger/didSampleProbe-multiple-probes.html
 inspector/debugger/nested-inspectors.html
 inspector/debugger/pause-reason.html
-inspector/debugger/regress-133182.html
 
 webkit.org/b/124311 compositing/regions/transform-transparent-positioned-video-inside-region.html [ ImageOnlyFailure ]
 
index 79601b9..0e76d7b 100644 (file)
@@ -1,3 +1,131 @@
+2016-05-13  Mark Lam  <mark.lam@apple.com>
+
+        We should have one calleeSaveRegistersBuffer per VMEntryFrame, not one per VM.
+        https://bugs.webkit.org/show_bug.cgi?id=157537
+        <rdar://problem/24794845>
+
+        Reviewed by Michael Saboff.
+
+        The pre-existing code behaves this way:
+
+        1. When JS code throws an exception, it saves callee save registers in
+           the VM calleeSaveRegistersBuffer.  These values are meant to be restored
+           to the callee save registers later either at the catch handler or at the
+           uncaught exception handler.
+
+        2. If the Inspector is enable, the VM will invoke inspector C++ code to inspect
+           the exception.  That C++ code can change the values of the callee save
+           registers.
+
+           The inspector code in turn re-enters the VM to execute JS inspector code.
+
+           The JS inspector code can run hot enough that we do an enterOptimizationCheck
+           on it.  The enterOptimizationCheck first saves all callee save registers
+           into the VM calleeSaveRegistersBuffer.
+
+           This effectively overwrites the values in the VM calleeSaveRegistersBuffer
+           from (1).
+
+        3. Eventually, execution returns to the catch handler or the uncaught exception
+           handler which restores the overwritten values in the VM
+           calleeSaveRegistersBuffer to the callee save registers.
+
+           When execution returns to the C++ code that entered the VM before (1), the
+           values in the callee registers are not what that code expects, and badness
+           and/or crashes ensues.
+
+        This patch applies the following fix:
+        
+        1. Allocate space in the VMEntryFrame for the calleeSaveRegistersBuffer.
+           This ensures that each VM entry session has its own buffer to use, and will
+           not corrupt the one from the previous VM entry session.
+
+           Delete the VM calleeSaveRegistersBuffer.
+
+        2. Change all locations that uses the VM calleeSaveRegistersBuffer to use the
+           calleeSaveRegistersBuffer in the current VMEntryFrame.
+
+        3. Renamed all uses of the term "VMCalleeSavesBuffer" to
+           "VMEntryFrameCalleeSavesBuffer".
+
+        This fix has been tested on the following configurations:
+        1. JSC and layout tests on a debug ASan build for 64-bit x86_64.
+        2. JSC tests on a release ASan build for 32-bit x86.
+        3. JSC tests on a release normal (non-ASan) build for ARM64.
+        4. JSC tests on a release normal (non-ASan) build for ARMv7 and ARMv7s.
+        5. JSC tests on a release ASan CLOOP build for x86_64.
+
+        These test runs did not produce any new crashes.  The ASan CLOOP has some
+        pre-existing crashes which are not due to this patch.
+
+        This bug can be tested by running the inspector/debugger/regress-133182.html test
+        on an ASan build.
+
+        * bytecode/PolymorphicAccess.cpp:
+        (JSC::AccessGenerationState::emitExplicitExceptionHandler):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::compileExceptionHandlers):
+        * dfg/DFGOSREntry.cpp:
+        (JSC::DFG::prepareOSREntry):
+        * dfg/DFGOSRExitCompiler.cpp:
+        * dfg/DFGOSRExitCompiler32_64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGThunks.cpp:
+        (JSC::DFG::osrEntryThunkGenerator):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::compile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::lower):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+        * interpreter/Interpreter.cpp:
+        (JSC::UnwindFunctor::operator()):
+        (JSC::UnwindFunctor::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
+        (JSC::UnwindFunctor::copyCalleeSavesToVMCalleeSavesBuffer): Deleted.
+        * interpreter/Interpreter.h:
+        (JSC::NativeCallFrameTracer::NativeCallFrameTracer):
+        * interpreter/VMEntryRecord.h:
+        (JSC::VMEntryRecord::calleeSaveRegistersBufferOffset):
+        (JSC::VMEntryRecord::prevTopCallFrame):
+        (JSC::VMEntryRecord::unsafePrevTopCallFrame):
+        (JSC::VMEntryFrame::vmEntryRecordOffset):
+        (JSC::VMEntryFrame::calleeSaveRegistersBufferOffset):
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::emitRandomThunk):
+        (JSC::AssemblyHelpers::restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer):
+        (JSC::AssemblyHelpers::restoreCalleeSavesFromVMCalleeSavesBuffer): Deleted.
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::emitRestoreSavedTagRegisters):
+        (JSC::AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
+        (JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToVMEntryFrameCalleeSavesBuffer):
+        (JSC::AssemblyHelpers::copyCalleeSavesToVMCalleeSavesBuffer): Deleted.
+        (JSC::AssemblyHelpers::copyCalleeSavesFromFrameOrRegisterToVMCalleeSavesBuffer): Deleted.
+        * jit/JIT.cpp:
+        (JSC::JIT::emitEnterOptimizationCheck):
+        (JSC::JIT::privateCompileExceptionHandlers):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_throw):
+        (JSC::JIT::emit_op_catch):
+        (JSC::JIT::emitSlow_op_loop_hint):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_throw):
+        (JSC::JIT::emit_op_catch):
+        * jit/ThunkGenerators.cpp:
+        (JSC::throwExceptionFromCallSlowPathGenerator):
+        (JSC::nativeForGenerator):
+        * llint/LLIntThunks.cpp:
+        (JSC::vmEntryRecord):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/VM.h:
+        (JSC::VM::getCTIStub):
+        (JSC::VM::calleeSaveRegistersBufferOffset): Deleted.
+        * wasm/WASMFunctionCompiler.h:
+        (JSC::WASMFunctionCompiler::endFunction):
+
 2016-05-13  Beth Dakin  <bdakin@apple.com>
 
         Add dyldSPI.h for linked on or after checks, and add one for link preview
index b643ace..7067c49 100644 (file)
@@ -172,7 +172,7 @@ CallSiteIndex AccessGenerationState::originalCallSiteIndex() const { return stub
 void AccessGenerationState::emitExplicitExceptionHandler()
 {
     restoreScratch();
-    jit->copyCalleeSavesToVMCalleeSavesBuffer();
+    jit->copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
     if (needsToRestoreRegistersIfException()) {
         // To the JIT that produces the original exception handling
         // call site, they will expect the OSR exit to be arrived
index a9566ea..17c6a0b 100644 (file)
@@ -139,7 +139,7 @@ void JITCompiler::compileExceptionHandlers()
     if (!m_exceptionChecksWithCallFrameRollback.empty()) {
         m_exceptionChecksWithCallFrameRollback.link(this);
 
-        copyCalleeSavesToVMCalleeSavesBuffer();
+        copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
 
         // lookupExceptionHandlerFromCallerFrame is passed two arguments, the VM and the exec (the CallFrame*).
         move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
@@ -159,7 +159,7 @@ void JITCompiler::compileExceptionHandlers()
     if (!m_exceptionChecks.empty()) {
         m_exceptionChecks.link(this);
 
-        copyCalleeSavesToVMCalleeSavesBuffer();
+        copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
 
         // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
         move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
index b5cf7cc..c5fc47a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -316,13 +316,14 @@ void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIn
     RegisterSet dontSaveRegisters = RegisterSet(RegisterSet::stackRegisters(), RegisterSet::allFPRs());
 
     unsigned registerCount = registerSaveLocations->size();
+    VMEntryRecord* record = vmEntryRecord(vm->topVMEntryFrame);
     for (unsigned i = 0; i < registerCount; i++) {
         RegisterAtOffset currentEntry = registerSaveLocations->at(i);
         if (dontSaveRegisters.get(currentEntry.reg()))
             continue;
-        RegisterAtOffset* vmCalleeSavesEntry = allCalleeSaves->find(currentEntry.reg());
+        RegisterAtOffset* calleeSavesEntry = allCalleeSaves->find(currentEntry.reg());
         
-        *(bitwise_cast<intptr_t*>(pivot - 1) - currentEntry.offsetAsIndex()) = vm->calleeSaveRegistersBuffer[vmCalleeSavesEntry->offsetAsIndex()];
+        *(bitwise_cast<intptr_t*>(pivot - 1) - currentEntry.offsetAsIndex()) = record->calleeSaveRegistersBuffer[calleeSavesEntry->offsetAsIndex()];
     }
 #endif
     
index fceb710..985dc7b 100644 (file)
@@ -151,7 +151,7 @@ void compileOSRExit(ExecState* exec)
         if (exit.m_kind == GenericUnwind) {
             // We are acting as a defacto op_catch because we arrive here from genericUnwind().
             // So, we must restore our call frame and stack pointer.
-            jit.restoreCalleeSavesFromVMCalleeSavesBuffer();
+            jit.restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer();
             jit.loadPtr(vm->addressOfCallFrameForCatch(), GPRInfo::callFrameRegister);
             jit.addPtr(CCallHelpers::TrustedImm32(codeBlock->stackPointerOffset() * sizeof(Register)),
                 GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister);
index 2721f4f..b1a1359 100644 (file)
@@ -255,7 +255,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
     m_jit.emitSaveCalleeSavesFor(m_jit.baselineCodeBlock());
 
     if (exit.isExceptionHandler())
-        m_jit.copyCalleeSavesToVMCalleeSavesBuffer();
+        m_jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
 
     // Do all data format conversions and store the results into the stack.
     
index eb20ac6..bdfbf63 100644 (file)
@@ -265,7 +265,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
     m_jit.emitMaterializeTagCheckRegisters();
 
     if (exit.isExceptionHandler())
-        m_jit.copyCalleeSavesToVMCalleeSavesBuffer();
+        m_jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
 
     // Do all data format conversions and store the results into the stack.
     
index 0c61946..ddc2713 100644 (file)
@@ -135,7 +135,7 @@ MacroAssemblerCodeRef osrEntryThunkGenerator(VM* vm)
     jit.abortWithReason(DFGUnreasonableOSREntryJumpDestination);
 
     ok.link(&jit);
-    jit.restoreCalleeSavesFromVMCalleeSavesBuffer();
+    jit.restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer();
     jit.emitMaterializeTagCheckRegisters();
 
     jit.jump(GPRInfo::regT1);
index 2efbf8d..b45abce 100644 (file)
@@ -121,7 +121,7 @@ void compile(State& state, Safepoint::Result& safepointResult)
 
     // Emit the exception handler.
     *state.exceptionHandler = jit.label();
-    jit.copyCalleeSavesToVMCalleeSavesBuffer();
+    jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
     jit.move(MacroAssembler::TrustedImmPtr(jit.vm()), GPRInfo::argumentGPR0);
     jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
     CCallHelpers::Call call = jit.call();
index 8d2240d..75adbc8 100644 (file)
@@ -206,7 +206,7 @@ public:
                 // clobber scratch.
                 AllowMacroScratchRegisterUsage allowScratch(jit);
                 
-                jit.copyCalleeSavesToVMCalleeSavesBuffer();
+                jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
                 jit.move(CCallHelpers::TrustedImmPtr(jit.vm()), GPRInfo::argumentGPR0);
                 jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
                 CCallHelpers::Call call = jit.call();
index ef0598d..f261266 100644 (file)
@@ -186,7 +186,7 @@ static void compileStub(
     // The first thing we need to do is restablish our frame in the case of an exception.
     if (exit.isGenericUnwindHandler()) {
         RELEASE_ASSERT(vm->callFrameForCatch); // The first time we hit this exit, like at all other times, this field should be non-null.
-        jit.restoreCalleeSavesFromVMCalleeSavesBuffer();
+        jit.restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer();
         jit.loadPtr(vm->addressOfCallFrameForCatch(), MacroAssembler::framePointerRegister);
         jit.addPtr(CCallHelpers::TrustedImm32(codeBlock->stackPointerOffset() * sizeof(Register)),
             MacroAssembler::framePointerRegister, CCallHelpers::stackPointerRegister);
@@ -441,8 +441,10 @@ static void compileStub(
     RegisterAtOffsetList* baselineCalleeSaves = baselineCodeBlock->calleeSaveRegisters();
     RegisterAtOffsetList* vmCalleeSaves = vm->getAllCalleeSaveRegisterOffsets();
     RegisterSet vmCalleeSavesToSkip = RegisterSet::stackRegisters();
-    if (exit.isExceptionHandler())
-        jit.move(CCallHelpers::TrustedImmPtr(vm->calleeSaveRegistersBuffer), GPRInfo::regT1);
+    if (exit.isExceptionHandler()) {
+        jit.loadPtr(&vm->topVMEntryFrame, GPRInfo::regT1);
+        jit.addPtr(CCallHelpers::TrustedImm32(VMEntryFrame::calleeSaveRegistersBufferOffset()), GPRInfo::regT1);
+    }
 
     for (Reg reg = Reg::first(); reg <= Reg::last(); reg = reg.next()) {
         if (!allFTLCalleeSaves.get(reg)) {
index c2edbe7..8930ac3 100644 (file)
@@ -695,18 +695,18 @@ public:
             if (LegacyProfiler* profiler = vm.enabledProfiler())
                 profiler->exceptionUnwind(m_callFrame);
 
-            copyCalleeSavesToVMCalleeSavesBuffer(visitor);
+            copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(visitor);
 
             return StackVisitor::Done;
         }
 
-        copyCalleeSavesToVMCalleeSavesBuffer(visitor);
+        copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(visitor);
 
         return StackVisitor::Continue;
     }
 
 private:
-    void copyCalleeSavesToVMCalleeSavesBuffer(StackVisitor& visitor) const
+    void copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(StackVisitor& visitor) const
     {
 #if ENABLE(JIT) && NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
 
@@ -728,13 +728,14 @@ private:
         intptr_t* frame = reinterpret_cast<intptr_t*>(m_callFrame->registers());
 
         unsigned registerCount = currentCalleeSaves->size();
+        VMEntryRecord* record = vmEntryRecord(vm.topVMEntryFrame);
         for (unsigned i = 0; i < registerCount; i++) {
             RegisterAtOffset currentEntry = currentCalleeSaves->at(i);
             if (dontCopyRegisters.get(currentEntry.reg()))
                 continue;
-            RegisterAtOffset* vmCalleeSavesEntry = allCalleeSaves->find(currentEntry.reg());
+            RegisterAtOffset* calleeSavesEntry = allCalleeSaves->find(currentEntry.reg());
             
-            vm.calleeSaveRegistersBuffer[vmCalleeSavesEntry->offsetAsIndex()] = *(frame + currentEntry.offsetAsIndex());
+            record->calleeSaveRegistersBuffer[calleeSavesEntry->offsetAsIndex()] = *(frame + currentEntry.offsetAsIndex());
         }
 #else
         UNUSED_PARAM(visitor);
index 4d89784..6ea1f35 100644 (file)
@@ -145,7 +145,7 @@ namespace JSC {
         {
             ASSERT(vm);
             ASSERT(callFrame);
-            ASSERT(callFrame < vm->topVMEntryFrame);
+            ASSERT(reinterpret_cast<void*>(callFrame) < reinterpret_cast<void*>(vm->topVMEntryFrame));
             vm->topCallFrame = callFrame;
         }
     };
index 9726538..7e02be6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef VMEntryRecord_h
 #define VMEntryRecord_h
 
-namespace JSC {
+#include "GPRInfo.h"
 
-typedef void VMEntryFrame;
+namespace JSC {
 
+struct VMEntryFrame;
 class ExecState;
 class VM;
 
@@ -42,6 +43,10 @@ struct VMEntryRecord {
     ExecState* m_prevTopCallFrame;
     VMEntryFrame* m_prevTopVMEntryFrame;
 
+#if ENABLE(JIT) && NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
+    intptr_t calleeSaveRegistersBuffer[NUMBER_OF_CALLEE_SAVES_REGISTERS];
+#endif
+
     ExecState* prevTopCallFrame() { return m_prevTopCallFrame; }
     SUPPRESS_ASAN ExecState* unsafePrevTopCallFrame() { return m_prevTopCallFrame; }
 
@@ -51,6 +56,23 @@ struct VMEntryRecord {
 
 extern "C" VMEntryRecord* vmEntryRecord(VMEntryFrame*);
 
+struct VMEntryFrame {
+#if ENABLE(JIT) && NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
+    static ptrdiff_t vmEntryRecordOffset()
+    {
+        VMEntryFrame* fakeVMEntryFrame = reinterpret_cast<VMEntryFrame*>(0x1000);
+        VMEntryRecord* record = vmEntryRecord(fakeVMEntryFrame);
+        return static_cast<ptrdiff_t>(
+            reinterpret_cast<char*>(record) - reinterpret_cast<char*>(fakeVMEntryFrame));
+    }
+
+    static ptrdiff_t calleeSaveRegistersBufferOffset()
+    {
+        return vmEntryRecordOffset() + OBJECT_OFFSETOF(VMEntryRecord, calleeSaveRegistersBuffer);
+    }
+#endif
+};
+
 } // namespace JSC
 
 #endif // VMEntryRecord_h
index 21b9e8e..2d2b4e1 100644 (file)
@@ -566,24 +566,50 @@ void AssemblyHelpers::emitRandomThunk(GPRReg scratch0, GPRReg scratch1, GPRReg s
 }
 #endif
 
-void AssemblyHelpers::restoreCalleeSavesFromVMCalleeSavesBuffer()
+void AssemblyHelpers::restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer()
 {
 #if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
-    char* sourceBuffer = bitwise_cast<char*>(m_vm->calleeSaveRegistersBuffer);
-
     RegisterAtOffsetList* allCalleeSaves = m_vm->getAllCalleeSaveRegisterOffsets();
     RegisterSet dontRestoreRegisters = RegisterSet::stackRegisters();
     unsigned registerCount = allCalleeSaves->size();
-    
+
+    GPRReg scratch = InvalidGPRReg;
+    unsigned scratchGPREntryIndex = 0;
+
+    // Use the first GPR entry's register as our scratch.
+    for (unsigned i = 0; i < registerCount; i++) {
+        RegisterAtOffset entry = allCalleeSaves->at(i);
+        if (dontRestoreRegisters.get(entry.reg()))
+            continue;
+        if (entry.reg().isGPR()) {
+            scratchGPREntryIndex = i;
+            scratch = entry.reg().gpr();
+            break;
+        }
+    }
+    ASSERT(scratch != InvalidGPRReg);
+
+    loadPtr(&m_vm->topVMEntryFrame, scratch);
+    addPtr(TrustedImm32(VMEntryFrame::calleeSaveRegistersBufferOffset()), scratch);
+
+    // Restore all callee saves except for the scratch.
     for (unsigned i = 0; i < registerCount; i++) {
         RegisterAtOffset entry = allCalleeSaves->at(i);
         if (dontRestoreRegisters.get(entry.reg()))
             continue;
-        if (entry.reg().isGPR())
-            loadPtr(static_cast<void*>(sourceBuffer + entry.offset()), entry.reg().gpr());
-        else
-            loadDouble(TrustedImmPtr(sourceBuffer + entry.offset()), entry.reg().fpr());
+        if (entry.reg().isGPR()) {
+            if (i != scratchGPREntryIndex)
+                loadPtr(Address(scratch, entry.offset()), entry.reg().gpr());
+        } else
+            loadDouble(Address(scratch, entry.offset()), entry.reg().fpr());
     }
+
+    // Restore the callee save value of the scratch.
+    RegisterAtOffset entry = allCalleeSaves->at(scratchGPREntryIndex);
+    ASSERT(!dontRestoreRegisters.get(entry.reg()));
+    ASSERT(entry.reg().isGPR());
+    ASSERT(scratch == entry.reg().gpr());
+    loadPtr(Address(scratch, entry.offset()), scratch);
 #endif
 }
 
index db2f42f..e14306f 100644 (file)
@@ -313,12 +313,13 @@ public:
 #endif
     }
 
-    void copyCalleeSavesToVMCalleeSavesBuffer(const TempRegisterSet& usedRegisters = { RegisterSet::stubUnavailableRegisters() })
+    void copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(const TempRegisterSet& usedRegisters = { RegisterSet::stubUnavailableRegisters() })
     {
 #if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
         GPRReg temp1 = usedRegisters.getFreeGPR(0);
 
-        move(TrustedImmPtr(m_vm->calleeSaveRegistersBuffer), temp1);
+        loadPtr(&m_vm->topVMEntryFrame, temp1);
+        addPtr(TrustedImm32(VMEntryFrame::calleeSaveRegistersBufferOffset()), temp1);
 
         RegisterAtOffsetList* allCalleeSaves = m_vm->getAllCalleeSaveRegisterOffsets();
         RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
@@ -338,9 +339,9 @@ public:
 #endif
     }
 
-    void restoreCalleeSavesFromVMCalleeSavesBuffer();
+    void restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer();
 
-    void copyCalleeSavesFromFrameOrRegisterToVMCalleeSavesBuffer(const TempRegisterSet& usedRegisters = { RegisterSet::stubUnavailableRegisters() })
+    void copyCalleeSavesFromFrameOrRegisterToVMEntryFrameCalleeSavesBuffer(const TempRegisterSet& usedRegisters = { RegisterSet::stubUnavailableRegisters() })
     {
 #if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
         GPRReg temp1 = usedRegisters.getFreeGPR(0);
@@ -351,7 +352,8 @@ public:
         ASSERT(codeBlock());
 
         // Copy saved calleeSaves on stack or unsaved calleeSaves in register to vm calleeSave buffer
-        move(TrustedImmPtr(m_vm->calleeSaveRegistersBuffer), temp1);
+        loadPtr(&m_vm->topVMEntryFrame, temp1);
+        addPtr(TrustedImm32(VMEntryFrame::calleeSaveRegistersBufferOffset()), temp1);
 
         RegisterAtOffsetList* allCalleeSaves = m_vm->getAllCalleeSaveRegisterOffsets();
         RegisterAtOffsetList* currentCalleeSaves = codeBlock()->calleeSaveRegisters();
index f70988e..1d50aba 100644 (file)
@@ -96,7 +96,7 @@ void JIT::emitEnterOptimizationCheck()
     skipOptimize.append(branchAdd32(Signed, TrustedImm32(Options::executionCounterIncrementForEntry()), AbsoluteAddress(m_codeBlock->addressOfJITExecuteCounter())));
     ASSERT(!m_bytecodeOffset);
 
-    copyCalleeSavesFromFrameOrRegisterToVMCalleeSavesBuffer();
+    copyCalleeSavesFromFrameOrRegisterToVMEntryFrameCalleeSavesBuffer();
 
     callOperation(operationOptimize, m_bytecodeOffset);
     skipOptimize.append(branchTestPtr(Zero, returnValueGPR));
@@ -785,7 +785,7 @@ void JIT::privateCompileExceptionHandlers()
     if (!m_exceptionChecksWithCallFrameRollback.empty()) {
         m_exceptionChecksWithCallFrameRollback.link(this);
 
-        copyCalleeSavesToVMCalleeSavesBuffer();
+        copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
 
         // lookupExceptionHandlerFromCallerFrame is passed two arguments, the VM and the exec (the CallFrame*).
 
@@ -804,7 +804,7 @@ void JIT::privateCompileExceptionHandlers()
     if (!m_exceptionChecks.empty()) {
         m_exceptionChecks.link(this);
 
-        copyCalleeSavesToVMCalleeSavesBuffer();
+        copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
 
         // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
         move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
index 9acb530..f0a7519 100644 (file)
@@ -442,7 +442,7 @@ void JIT::emit_op_neq(Instruction* currentInstruction)
 void JIT::emit_op_throw(Instruction* currentInstruction)
 {
     ASSERT(regT0 == returnValueGPR);
-    copyCalleeSavesToVMCalleeSavesBuffer();
+    copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
     emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
     callOperationNoExceptionCheck(operationThrow, regT0);
     jumpToExceptionHandler();
@@ -518,7 +518,7 @@ void JIT::emit_op_to_string(Instruction* currentInstruction)
 
 void JIT::emit_op_catch(Instruction* currentInstruction)
 {
-    restoreCalleeSavesFromVMCalleeSavesBuffer();
+    restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer();
 
     move(TrustedImmPtr(m_vm), regT3);
     load64(Address(regT3, VM::callFrameForCatchOffset()), callFrameRegister);
@@ -935,7 +935,7 @@ void JIT::emitSlow_op_loop_hint(Instruction*, Vector<SlowCaseEntry>::iterator& i
     if (canBeOptimized()) {
         linkSlowCase(iter);
 
-        copyCalleeSavesFromFrameOrRegisterToVMCalleeSavesBuffer();
+        copyCalleeSavesFromFrameOrRegisterToVMEntryFrameCalleeSavesBuffer();
 
         callOperation(operationOptimize, m_bytecodeOffset);
         Jump noOptimizedEntry = branchTestPtr(Zero, returnValueGPR);
index 690e41c..cf04ca9 100644 (file)
@@ -787,7 +787,7 @@ void JIT::emit_op_neq_null(Instruction* currentInstruction)
 void JIT::emit_op_throw(Instruction* currentInstruction)
 {
     ASSERT(regT0 == returnValueGPR);
-    copyCalleeSavesToVMCalleeSavesBuffer();
+    copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
     emitLoad(currentInstruction[1].u.operand, regT1, regT0);
     callOperationNoExceptionCheck(operationThrow, regT1, regT0);
     jumpToExceptionHandler();
@@ -847,7 +847,7 @@ void JIT::emitSlow_op_to_string(Instruction* currentInstruction, Vector<SlowCase
 
 void JIT::emit_op_catch(Instruction* currentInstruction)
 {
-    restoreCalleeSavesFromVMCalleeSavesBuffer();
+    restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer();
 
     move(TrustedImmPtr(m_vm), regT3);
     // operationThrow returns the callFrame for the handler.
index 4690bc4..e6ee85a 100644 (file)
@@ -66,7 +66,7 @@ MacroAssemblerCodeRef throwExceptionFromCallSlowPathGenerator(VM* vm)
     // even though we won't use it.
     jit.preserveReturnAddressAfterCall(GPRInfo::nonPreservedNonReturnGPR);
 
-    jit.copyCalleeSavesToVMCalleeSavesBuffer();
+    jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
 
     jit.setupArguments(CCallHelpers::TrustedImmPtr(vm), GPRInfo::callFrameRegister);
     jit.move(CCallHelpers::TrustedImmPtr(bitwise_cast<void*>(lookupExceptionHandler)), GPRInfo::nonArgGPR0);
@@ -355,7 +355,7 @@ static MacroAssemblerCodeRef nativeForGenerator(VM* vm, CodeSpecializationKind k
     // Handle an exception
     exceptionHandler.link(&jit);
 
-    jit.copyCalleeSavesToVMCalleeSavesBuffer();
+    jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
     jit.storePtr(JSInterfaceJIT::callFrameRegister, &vm->topCallFrame);
 
 #if CPU(X86) && USE(JSVALUE32_64)
index af6884e..daaaef5 100644 (file)
@@ -116,7 +116,7 @@ extern "C" VMEntryRecord* vmEntryRecord(VMEntryFrame* entryFrame)
     // The C Loop doesn't have any callee save registers, so the VMEntryRecord is allocated at the base of the frame.
     intptr_t stackAlignment = stackAlignmentBytes();
     intptr_t VMEntryTotalFrameSize = (sizeof(VMEntryRecord) + (stackAlignment - 1)) & ~(stackAlignment - 1);
-    return reinterpret_cast<VMEntryRecord*>(static_cast<char*>(entryFrame) - VMEntryTotalFrameSize);
+    return reinterpret_cast<VMEntryRecord*>(reinterpret_cast<char*>(entryFrame) - VMEntryTotalFrameSize);
 }
 
 
index a2441de..43bf77e 100644 (file)
@@ -568,9 +568,11 @@ macro restoreCalleeSavesUsedByLLInt()
     end
 end
 
-macro copyCalleeSavesToVMCalleeSavesBuffer(vm, temp)
+macro copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(vm, temp)
     if ARM64 or X86_64 or X86_64_WIN
-        leap VM::calleeSaveRegistersBuffer[vm], temp
+        loadp VM::topVMEntryFrame[vm], temp
+        vmEntryRecord(temp, temp)
+        leap VMEntryRecord::calleeSaveRegistersBuffer[temp], temp
         if ARM64
             storep csr0, [temp]
             storep csr1, 8[temp]
@@ -608,9 +610,11 @@ macro copyCalleeSavesToVMCalleeSavesBuffer(vm, temp)
     end
 end
 
-macro restoreCalleeSavesFromVMCalleeSavesBuffer(vm, temp)
+macro restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(vm, temp)
     if ARM64 or X86_64 or X86_64_WIN
-        leap VM::calleeSaveRegistersBuffer[vm], temp
+        loadp VM::topVMEntryFrame[vm], temp
+        vmEntryRecord(temp, temp)
+        leap VMEntryRecord::calleeSaveRegistersBuffer[temp], temp
         if ARM64
             loadp [temp], csr0
             loadp 8[temp], csr1
index b0f5a3d..05325c2 100644 (file)
@@ -302,7 +302,7 @@ _handleUncaughtException:
     loadp Callee + PayloadOffset[cfr], t3
     andp MarkedBlockMask, t3
     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
-    restoreCalleeSavesFromVMCalleeSavesBuffer(t3, t0)
+    restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(t3, t0)
     loadp VM::callFrameForCatch[t3], cfr
     storep 0, VM::callFrameForCatch[t3]
 
@@ -1915,7 +1915,7 @@ _llint_op_catch:
     loadp Callee + PayloadOffset[cfr], t3
     andp MarkedBlockMask, t3
     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
-    restoreCalleeSavesFromVMCalleeSavesBuffer(t3, t0)
+    restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(t3, t0)
     loadp VM::callFrameForCatch[t3], cfr
     storep 0, VM::callFrameForCatch[t3]
     restoreStackPointerAfterCall()
@@ -1965,7 +1965,7 @@ _llint_throw_from_slow_path_trampoline:
     loadp Callee[cfr], t1
     andp MarkedBlockMask, t1
     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
-    copyCalleeSavesToVMCalleeSavesBuffer(t1, t2)
+    copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(t1, t2)
     jmp VM::targetMachinePCForThrow[t1]
 
 
index c602553..82fcb17 100644 (file)
@@ -274,7 +274,7 @@ _handleUncaughtException:
     loadp Callee[cfr], t3
     andp MarkedBlockMask, t3
     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
-    restoreCalleeSavesFromVMCalleeSavesBuffer(t3, t0)
+    restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(t3, t0)
     loadp VM::callFrameForCatch[t3], cfr
     storep 0, VM::callFrameForCatch[t3]
 
@@ -1794,7 +1794,7 @@ _llint_op_catch:
     loadp Callee[cfr], t3
     andp MarkedBlockMask, t3
     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
-    restoreCalleeSavesFromVMCalleeSavesBuffer(t3, t0)
+    restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(t3, t0)
     loadp VM::callFrameForCatch[t3], cfr
     storep 0, VM::callFrameForCatch[t3]
     restoreStackPointerAfterCall()
@@ -1840,7 +1840,7 @@ _llint_throw_from_slow_path_trampoline:
     loadp Callee[cfr], t1
     andp MarkedBlockMask, t1
     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
-    copyCalleeSavesToVMCalleeSavesBuffer(t1, t2)
+    copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(t1, t2)
 
     callSlowPath(_llint_slow_path_handle_exception)
 
index ba07c93..b43affb 100644 (file)
@@ -34,9 +34,6 @@
 #include "DateInstanceCache.h"
 #include "ExecutableAllocator.h"
 #include "FunctionHasExecutedCache.h"
-#if ENABLE(JIT)
-#include "GPRInfo.h"
-#endif
 #include "Heap.h"
 #include "Intrinsic.h"
 #include "JITThunks.h"
@@ -384,15 +381,6 @@ public:
     SourceProviderCacheMap sourceProviderCacheMap;
     Interpreter* interpreter;
 #if ENABLE(JIT)
-#if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
-    intptr_t calleeSaveRegistersBuffer[NUMBER_OF_CALLEE_SAVES_REGISTERS];
-
-    static ptrdiff_t calleeSaveRegistersBufferOffset()
-    {
-        return OBJECT_OFFSETOF(VM, calleeSaveRegistersBuffer);
-    }
-#endif // NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
-
     std::unique_ptr<JITThunks> jitStubs;
     MacroAssemblerCodeRef getCTIStub(ThunkGenerator generator)
     {
index 0f2f015..7b21391 100644 (file)
@@ -237,7 +237,7 @@ public:
         if (!m_exceptionChecks.empty()) {
             m_exceptionChecks.link(this);
 
-            copyCalleeSavesToVMCalleeSavesBuffer();
+            copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
 
             // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
             move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);