Changeset 37086 in webkit for trunk/JavaScriptCore/VM/CTI.cpp


Ignore:
Timestamp:
Sep 29, 2008, 5:46:25 PM (17 years ago)
Author:
[email protected]
Message:

JavaScriptCore:

2008-09-29 Geoffrey Garen <[email protected]>

Reviewed by Cameron Zwarich.


Store the callee ScopeChain, not the caller ScopeChain, in the call frame
header. Nix the "scopeChain" local variable and ExecState::m_scopeChain, and
access the callee ScopeChain through the call frame header instead.

Profit: call + return are simpler, because they don't have to update the
"scopeChain" local variable, or ExecState::m_scopeChain.


Because CTI keeps "r" in a register, reading the callee ScopeChain relative
to "r" can be very fast, in any cases we care to optimize.

0% speedup on empty function call benchmark. (5.5% speedup in bytecode.)
0% speedup on SunSpider. (7.5% speedup on controlflow-recursive.)
2% speedup on SunSpider --v8.
2% speedup on v8 benchmark.

  • VM/CTI.cpp: Changed scope chain access to read the scope chain from the call frame header. Sped up op_ret by changing it not to fuss with the "scopeChain" local variable or ExecState::m_scopeChain.
  • VM/CTI.h: Updated CTI trampolines not to take a ScopeChainNode* argument, since that's stored in the call frame header now.
  • VM/Machine.cpp: Access "scopeChain" and "codeBlock" through new helper functions that read from the call frame header. Updated functions operating on ExecState::m_callFrame to account for / take advantage of the fact that Exec:m_callFrame is now never NULL.


Fixed a bug in op_construct, where it would use the caller's default
object prototype, rather than the callee's, when constructing a new object.

  • VM/Machine.h: Made some helper functions available. Removed ScopeChainNode* arguments to a lot of functions, since the ScopeChainNode* is now stored in the call frame header.
  • VM/RegisterFile.h: Renamed "CallerScopeChain" to "ScopeChain", since that's what it is now.
  • kjs/DebuggerCallFrame.cpp: Updated for change to ExecState signature.
  • kjs/ExecState.cpp:
  • kjs/ExecState.h: Nixed ExecState::m_callFrame, along with the unused isGlobalObject function.
  • kjs/JSGlobalObject.cpp:
  • kjs/JSGlobalObject.h: Gave the global object a fake call frame in which to store the global scope chain, since our code now assumes that it can always read the scope chain out of the ExecState's call frame.

JavaScriptGlue:

2008-09-29 Geoffrey Garen <[email protected]>

Not reviewed.


Forwarding headers to fix the build.

  • ForwardingHeaders/kjs/CTI.h: Copied from ForwardingHeaders/kjs/ExecState.h.
  • ForwardingHeaders/kjs/ustring.h: Copied from ForwardingHeaders/kjs/ExecState.h.
  • ForwardingHeaders/masm: Added.
  • ForwardingHeaders/masm/X86Assembler.h: Added.
  • ForwardingHeaders/profiler: Added.
  • ForwardingHeaders/profiler/Profiler.h: Added.

LayoutTests:

2008-09-29 Geoffrey Garen <[email protected]>

Reviewed by Cameron Zwarich.


Test case for which prototype is used when calling "new" across windows.

  • fast/js/construct-global-object-expected.txt: Added.
  • fast/js/construct-global-object.html: Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/VM/CTI.cpp

    r37050 r37086  
    101101{
    102102   
    103     __declspec(naked) JSValue* ctiTrampoline(void* code, ExecState* exec, RegisterFile* registerFile, Register* r, ScopeChainNode* scopeChain, JSValue** exception, Profiler**)
     103    __declspec(naked) JSValue* ctiTrampoline(void* code, ExecState* exec, RegisterFile* registerFile, Register* r, JSValue** exception, Profiler**)
    104104    {
    105105        __asm {
     
    145145
    146146// get arg puts an arg from the SF register array into a h/w register
    147 ALWAYS_INLINE void CTI::emitGetArg(unsigned src, X86Assembler::RegisterID dst)
     147ALWAYS_INLINE void CTI::emitGetArg(int src, X86Assembler::RegisterID dst)
    148148{
    149149    // TODO: we want to reuse values that are already in registers if we can - add a register allocator!
     
    11631163            int skip = instruction[i + 3].u.operand + m_codeBlock->needsFullScopeChain;
    11641164
    1165             emitGetCTIParam(CTI_ARGS_scopeChain, X86::eax);
     1165            emitGetArg(RegisterFile::ScopeChain, X86::eax);
    11661166            while (skip--)
    11671167                m_jit.movl_mr(OBJECT_OFFSET(ScopeChainNode, next), X86::eax, X86::eax);
     
    11761176            int skip = instruction[i + 2].u.operand + m_codeBlock->needsFullScopeChain;
    11771177
    1178             emitGetCTIParam(CTI_ARGS_scopeChain, X86::edx);
     1178            emitGetArg(RegisterFile::ScopeChain, X86::edx);
    11791179            emitGetArg(instruction[i + 3].u.operand, X86::eax);
    11801180            while (skip--)
     
    12051205            emitGetArg(instruction[i + 1].u.operand, X86::eax);
    12061206
    1207             // Restore the scope chain.
    1208             m_jit.movl_mr(RegisterFile::CallerScopeChain * static_cast<int>(sizeof(Register)), X86::edi, X86::edx);
     1207            // Grab the return address.
     1208            emitGetArg(RegisterFile::ReturnPC, X86::edx);
     1209
     1210            // Restore our caller's "r".
    12091211            emitGetCTIParam(CTI_ARGS_exec, X86::ecx);
    1210             emitPutCTIParam(X86::edx, CTI_ARGS_scopeChain);
    1211             m_jit.movl_rm(X86::edx, OBJECT_OFFSET(ExecState, m_scopeChain), X86::ecx);
    1212 
    1213             // Restore ExecState::m_callFrame.
     1212            emitGetArg(RegisterFile::CallerRegisters, X86::edi);
     1213            emitPutCTIParam(X86::edi, CTI_ARGS_r);
    12141214            m_jit.movl_rm(X86::edi, OBJECT_OFFSET(ExecState, m_callFrame), X86::ecx);
    12151215
    1216             // Grab the return address.
    1217             m_jit.movl_mr(RegisterFile::ReturnPC * static_cast<int>(sizeof(Register)), X86::edi, X86::ecx);
    1218 
    1219             // Restore the machine return addess from the callframe, roll the callframe back to the caller callframe,
    1220             // and preserve a copy of r on the stack at CTI_ARGS_r.
    1221             m_jit.movl_mr(RegisterFile::CallerRegisters * static_cast<int>(sizeof(Register)), X86::edi, X86::edi);
    1222             emitPutCTIParam(X86::edi, CTI_ARGS_r);
    1223 
    1224             m_jit.pushl_r(X86::ecx);
     1216            // Return.
     1217            m_jit.pushl_r(X86::edx);
    12251218            m_jit.ret();
    12261219
Note: See TracChangeset for help on using the changeset viewer.