Changeset 37086 in webkit for trunk/JavaScriptCore/VM/Machine.h


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/Machine.h

    r37050 r37086  
    103103        JSValue* retrieveCaller(ExecState*, InternalFunction*) const;
    104104        void retrieveLastCaller(ExecState* exec, int& lineNumber, int& sourceId, UString& sourceURL, JSValue*& function) const;
     105       
     106        static ScopeChainNode* scopeChain(const Register* r) { return r[RegisterFile::ScopeChain].scopeChain(); }
     107        static CodeBlock* codeBlock(const Register* r) { return r[RegisterFile::CodeBlock].codeBlock(); }
    105108
    106109        void getArgumentsData(Register* callFrame, JSFunction*&, int& firstParameterIndex, Register*& argv, int& argc);
     
    241244        bool isJSString(JSValue* v) { return !JSImmediate::isImmediate(v) && v->asCell()->vptr() == m_jsStringVptr; }
    242245       
     246        ALWAYS_INLINE static void initializeCallFrame(Register* callFrame, CodeBlock*, Instruction*, ScopeChainNode*, Register* r, int returnValueRegister, int argc, JSValue* function);
     247
    243248    private:
    244249        enum ExecutionFlag { Normal, InitializeAndReturn };
     
    247252        JSValue* execute(EvalNode*, ExecState*, JSObject* thisObj, int registerOffset, ScopeChainNode*, JSValue** exception);
    248253
    249         ALWAYS_INLINE static void initializeCallFrame(Register* callFrame, CodeBlock*, Instruction*, ScopeChainNode*, Register* r, int returnValueRegister, int argc, JSValue* function);
    250 
    251         ALWAYS_INLINE static void setScopeChain(ExecState* exec, ScopeChainNode*&, ScopeChainNode*);
    252         NEVER_INLINE void debug(ExecState*, ScopeChainNode*, Register*, DebugHookID, int firstLine, int lastLine);
    253 
    254         NEVER_INLINE bool resolve(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain, JSValue*& exceptionValue);
    255         NEVER_INLINE bool resolveSkip(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain, JSValue*& exceptionValue);
     254        NEVER_INLINE void debug(ExecState*, Register*, DebugHookID, int firstLine, int lastLine);
     255
     256        NEVER_INLINE bool resolve(ExecState* exec, Instruction* vPC, Register* r, JSValue*& exceptionValue);
     257        NEVER_INLINE bool resolveSkip(ExecState* exec, Instruction* vPC, Register* r, JSValue*& exceptionValue);
    256258        NEVER_INLINE bool resolveGlobal(ExecState* exec, Instruction* vPC, Register* r, JSValue*& exceptionValue);
    257         NEVER_INLINE void resolveBase(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain);
    258         NEVER_INLINE bool resolveBaseAndProperty(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain, JSValue*& exceptionValue);
    259         NEVER_INLINE ScopeChainNode* createExceptionScope(ExecState* exec, const Instruction* vPC, Register* r, ScopeChainNode* scopeChain);
    260 
    261         NEVER_INLINE bool unwindCallFrame(ExecState*, JSValue*, const Instruction*&, CodeBlock*&, ScopeChainNode*&, Register*&);
    262         NEVER_INLINE Instruction* throwException(ExecState*, JSValue*&, const Instruction*, ScopeChainNode*&, Register*&, bool);
    263         NEVER_INLINE bool resolveBaseAndFunc(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain, JSValue*& exceptionValue);
     259        NEVER_INLINE void resolveBase(ExecState* exec, Instruction* vPC, Register* r);
     260        NEVER_INLINE bool resolveBaseAndProperty(ExecState* exec, Instruction* vPC, Register* r, JSValue*& exceptionValue);
     261        NEVER_INLINE ScopeChainNode* createExceptionScope(ExecState* exec, const Instruction* vPC, Register* r);
     262
     263        NEVER_INLINE bool unwindCallFrame(ExecState*, JSValue*, const Instruction*&, CodeBlock*&, Register*&);
     264        NEVER_INLINE Instruction* throwException(ExecState*, JSValue*&, const Instruction*, Register*&, bool);
     265        NEVER_INLINE bool resolveBaseAndFunc(ExecState* exec, Instruction* vPC, Register* r, JSValue*& exceptionValue);
    264266
    265267        Register* callFrame(ExecState*, InternalFunction*) const;
    266268
    267         JSValue* privateExecute(ExecutionFlag, ExecState* = 0, RegisterFile* = 0, Register* = 0, ScopeChainNode* = 0, JSValue** exception = 0);
    268 
    269         void dumpCallFrame(ScopeChainNode*, const RegisterFile*, const Register*);
     269        JSValue* privateExecute(ExecutionFlag, ExecState* = 0, RegisterFile* = 0, Register* = 0, JSValue** exception = 0);
     270
     271        void dumpCallFrame(const RegisterFile*, const Register*);
    270272        void dumpRegisters(const RegisterFile*, const Register*);
    271273
     
    311313    };
    312314
     315    ALWAYS_INLINE void Machine::initializeCallFrame(Register* callFrame, CodeBlock* codeBlock, Instruction* vPC, ScopeChainNode* scopeChain, Register* r, int returnValueRegister, int argc, JSValue* function)
     316    {
     317        callFrame[RegisterFile::CodeBlock] = codeBlock;
     318        callFrame[RegisterFile::ScopeChain] = scopeChain;
     319        callFrame[RegisterFile::CallerRegisters] = r;
     320        callFrame[RegisterFile::ReturnPC] = vPC;
     321        callFrame[RegisterFile::ReturnValueRegister] = returnValueRegister;
     322        callFrame[RegisterFile::ArgumentCount] = argc; // original argument count (for the sake of the "arguments" object)
     323        callFrame[RegisterFile::Callee] = function;
     324        callFrame[RegisterFile::OptionalCalleeActivation] = nullJSValue;
     325        callFrame[RegisterFile::OptionalCalleeArguments] = nullJSValue;
     326    }
     327
    313328} // namespace JSC
    314329
Note: See TracChangeset for help on using the changeset viewer.