Changeset 37297 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Oct 4, 2008, 2:12:54 PM (17 years ago)
Author:
Darin Adler
Message:

JavaScriptCore:

2008-10-04 Darin Adler <Darin Adler>

Reviewed by Cameron Zwarich.

10% faster on Richards; other v8 benchmarks faster too.
A wash on SunSpider.

This does the minimum necessary to get the speedup. Next step in
cleaning this up is to replace ExecState with a CallFrame class,
and be more judicious about when to pass a call frame and when
to pass a global data pointer, global object pointer, or perhaps
something else entirely.

  • VM/CTI.cpp: Remove the debug-only check of the exception in ctiVMThrowTrampoline -- already checked in the code the trampoline jumps to, so not all that useful. Removed the exec argument from ctiTrampoline. Removed emitDebugExceptionCheck -- no longer needed. (JSC::CTI::emitCall): Removed code to set ExecState::m_callFrame. (JSC::CTI::privateCompileMainPass): Removed code in catch to extract the exception from ExecState::m_exception; instead, the code that jumps into catch will make sure the exception is already in eax.
  • VM/CTI.h: Removed exec from the ctiTrampoline. Also removed the non-helpful "volatile". Temporarily left ARG_exec in as a synonym for ARG_r; I'll change that on a future cleanup pass when introducing more use of the CallFrame type. (JSC::CTI::execute): Removed the ExecState* argument.
  • VM/ExceptionHelpers.cpp: (JSC::InterruptedExecutionError::InterruptedExecutionError): Take JSGlobalData* instead of ExecState*. (JSC::createInterruptedExecutionException): Ditto.
  • VM/ExceptionHelpers.h: Ditto. Also removed an unneeded include.
  • VM/Machine.cpp: (JSC::slideRegisterWindowForCall): Removed the exec and exceptionValue arguments. Changed to return 0 when there's a stack overflow rather than using a separate exception argument to cut down on memory accesses in the calling convention. (JSC::Machine::unwindCallFrame): Removed the exec argument when constructing a DebuggerCallFrame. Also removed code to set ExecState::m_callFrame. (JSC::Machine::throwException): Removed the exec argument when construction a DebuggerCallFrame. (JSC::Machine::execute): Updated to use the register instead of ExecState and also removed various uses of ExecState. (JSC::Machine::debug): (JSC::Machine::privateExecute): Put globalData into a local variable so it can be used throughout the interpreter. Changed the VM_CHECK_EXCEPTION to get the exception in globalData instead of through ExecState. (JSC::Machine::retrieveLastCaller): Turn exec into a registers pointer by calling registers() instead of by getting m_callFrame. (JSC::Machine::callFrame): Ditto. Tweaked exception macros. Made new versions for when you know you have an exception. Get at global exception with ARG_globalData. Got rid of the need to pass in the return value type. (JSC::Machine::cti_op_add): Update to use new version of exception macros. (JSC::Machine::cti_op_pre_inc): Ditto. (JSC::Machine::cti_timeout_check): Ditto. (JSC::Machine::cti_op_instanceof): Ditto. (JSC::Machine::cti_op_new_func): Ditto. (JSC::Machine::cti_op_call_JSFunction): Optimized by using the ARG values directly instead of through local variables -- this gets rid of code that just shuffles things around in the stack frame. Also get rid of ExecState and update for the new way exceptions are handled in slideRegisterWindowForCall. (JSC::Machine::cti_vm_compile): Update to make exec out of r since they are both the same thing now. (JSC::Machine::cti_op_call_NotJSFunction): Ditto. (JSC::Machine::cti_op_init_arguments): Ditto. (JSC::Machine::cti_op_resolve): Ditto. (JSC::Machine::cti_op_construct_JSConstruct): Ditto. (JSC::Machine::cti_op_construct_NotJSConstruct): Ditto. (JSC::Machine::cti_op_resolve_func): Ditto. (JSC::Machine::cti_op_put_by_val): Ditto. (JSC::Machine::cti_op_put_by_val_array): Ditto. (JSC::Machine::cti_op_resolve_skip): Ditto. (JSC::Machine::cti_op_resolve_global): Ditto. (JSC::Machine::cti_op_post_inc): Ditto. (JSC::Machine::cti_op_resolve_with_base): Ditto. (JSC::Machine::cti_op_post_dec): Ditto. (JSC::Machine::cti_op_call_eval): Ditto. (JSC::Machine::cti_op_throw): Ditto. Also rearranged to return the exception value as the return value so it can be used by op_catch. (JSC::Machine::cti_op_push_scope): Ditto. (JSC::Machine::cti_op_in): Ditto. (JSC::Machine::cti_op_del_by_val): Ditto. (JSC::Machine::cti_vm_throw): Ditto. Also rearranged to return the exception value as the return value so it can be used by op_catch.
  • kjs/DebuggerCallFrame.cpp: (JSC::DebuggerCallFrame::functionName): Pass globalData. (JSC::DebuggerCallFrame::evaluate): Eliminated code to make a new ExecState.
  • kjs/DebuggerCallFrame.h: Removed ExecState argument from constructor.
  • kjs/ExecState.h: Eliminated all data members and made ExecState inherit privately from Register instead. Also added a typedef to the future name for this class, which is CallFrame. It's just a Register* that knows it's a pointer at a call frame. The new class can't be constructed or copied. Changed all functions to use the this pointer instead of m_callFrame. Changed exception-related functions to access an exception in JSGlobalData. Removed functions used by CTI to pass the return address to the throw machinery -- this is now done directly with a global in the global data.
  • kjs/FunctionPrototype.cpp: (JSC::functionProtoFuncToString): Pass globalData instead of exec.
  • kjs/InternalFunction.cpp: (JSC::InternalFunction::name): Take globalData instead of exec.
  • kjs/InternalFunction.h: Ditto.
  • kjs/JSGlobalData.cpp: Initialize the new exception global to 0.
  • kjs/JSGlobalData.h: Declare two new globals. One for the current exception and another for the return address used by CTI to implement the throw operation.
  • kjs/JSGlobalObject.cpp: (JSC::JSGlobalObject::init): Removed code to set up globalExec, which is now the same thing as globalCallFrame. (JSC::JSGlobalObject::reset): Get globalExec from our globalExec function so we don't have to repeat the logic twice. (JSC::JSGlobalObject::mark): Removed code to mark the exception; the exception is now stored in JSGlobalData and marked there. (JSC::JSGlobalObject::globalExec): Return a pointer to the end of the global call frame.
  • kjs/JSGlobalObject.h: Removed the globalExec data member.
  • kjs/JSObject.cpp: (JSC::JSObject::putDirectFunction): Pass globalData instead of exec.
  • kjs/collector.cpp: (JSC::Heap::collect): Mark the global exception.
  • profiler/ProfileGenerator.cpp: (JSC::ProfileGenerator::addParentForConsoleStart): Pass globalData instead of exec to createCallIdentifier.
  • profiler/Profiler.cpp: (JSC::Profiler::willExecute): Pass globalData instead of exec to createCallIdentifier. (JSC::Profiler::didExecute): Ditto. (JSC::Profiler::createCallIdentifier): Take globalData instead of exec. (JSC::createCallIdentifierFromFunctionImp): Ditto.
  • profiler/Profiler.h: Change interface to take a JSGlobalData instead of an ExecState.

WebKit/mac:

2008-10-04 Darin Adler <Darin Adler>

Reviewed by Cameron Zwarich.

  • WebView/WebScriptDebugger.mm: (WebScriptDebugger::WebScriptDebugger): Remove 0 passed for ExecState.
Location:
trunk/JavaScriptCore
Files:
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r37294 r37297  
     12008-10-04  Darin Adler  <[email protected]>
     2
     3        Reviewed by Cameron Zwarich.
     4
     5        - https://bugs.webkit.org/show_bug.cgi?id=21295
     6          Bug 21295: Replace ExecState with a call frame Register pointer
     7
     8        10% faster on Richards; other v8 benchmarks faster too.
     9        A wash on SunSpider.
     10
     11        This does the minimum necessary to get the speedup. Next step in
     12        cleaning this up is to replace ExecState with a CallFrame class,
     13        and be more judicious about when to pass a call frame and when
     14        to pass a global data pointer, global object pointer, or perhaps
     15        something else entirely.
     16
     17        * VM/CTI.cpp: Remove the debug-only check of the exception in
     18        ctiVMThrowTrampoline -- already checked in the code the trampoline
     19        jumps to, so not all that useful. Removed the exec argument from
     20        ctiTrampoline. Removed emitDebugExceptionCheck -- no longer needed.
     21        (JSC::CTI::emitCall): Removed code to set ExecState::m_callFrame.
     22        (JSC::CTI::privateCompileMainPass): Removed code in catch to extract
     23        the exception from ExecState::m_exception; instead, the code that
     24        jumps into catch will make sure the exception is already in eax.
     25        * VM/CTI.h: Removed exec from the ctiTrampoline. Also removed the
     26        non-helpful "volatile". Temporarily left ARG_exec in as a synonym
     27        for ARG_r; I'll change that on a future cleanup pass when introducing
     28        more use of the CallFrame type.
     29        (JSC::CTI::execute): Removed the ExecState* argument.
     30
     31        * VM/ExceptionHelpers.cpp:
     32        (JSC::InterruptedExecutionError::InterruptedExecutionError): Take
     33        JSGlobalData* instead of ExecState*.
     34        (JSC::createInterruptedExecutionException): Ditto.
     35        * VM/ExceptionHelpers.h: Ditto. Also removed an unneeded include.
     36
     37        * VM/Machine.cpp:
     38        (JSC::slideRegisterWindowForCall): Removed the exec and
     39        exceptionValue arguments. Changed to return 0 when there's a stack
     40        overflow rather than using a separate exception argument to cut
     41        down on memory accesses in the calling convention.
     42        (JSC::Machine::unwindCallFrame): Removed the exec argument when
     43        constructing a DebuggerCallFrame. Also removed code to set
     44        ExecState::m_callFrame.
     45        (JSC::Machine::throwException): Removed the exec argument when
     46        construction a DebuggerCallFrame.
     47        (JSC::Machine::execute): Updated to use the register instead of
     48        ExecState and also removed various uses of ExecState.
     49        (JSC::Machine::debug):
     50        (JSC::Machine::privateExecute): Put globalData into a local
     51        variable so it can be used throughout the interpreter. Changed
     52        the VM_CHECK_EXCEPTION to get the exception in globalData instead
     53        of through ExecState.
     54        (JSC::Machine::retrieveLastCaller): Turn exec into a registers
     55        pointer by calling registers() instead of by getting m_callFrame.
     56        (JSC::Machine::callFrame): Ditto.
     57        Tweaked exception macros. Made new versions for when you know
     58        you have an exception. Get at global exception with ARG_globalData.
     59        Got rid of the need to pass in the return value type.
     60        (JSC::Machine::cti_op_add): Update to use new version of exception
     61        macros.
     62        (JSC::Machine::cti_op_pre_inc): Ditto.
     63        (JSC::Machine::cti_timeout_check): Ditto.
     64        (JSC::Machine::cti_op_instanceof): Ditto.
     65        (JSC::Machine::cti_op_new_func): Ditto.
     66        (JSC::Machine::cti_op_call_JSFunction): Optimized by using the
     67        ARG values directly instead of through local variables -- this gets
     68        rid of code that just shuffles things around in the stack frame.
     69        Also get rid of ExecState and update for the new way exceptions are
     70        handled in slideRegisterWindowForCall.
     71        (JSC::Machine::cti_vm_compile): Update to make exec out of r since
     72        they are both the same thing now.
     73        (JSC::Machine::cti_op_call_NotJSFunction): Ditto.
     74        (JSC::Machine::cti_op_init_arguments): Ditto.
     75        (JSC::Machine::cti_op_resolve): Ditto.
     76        (JSC::Machine::cti_op_construct_JSConstruct): Ditto.
     77        (JSC::Machine::cti_op_construct_NotJSConstruct): Ditto.
     78        (JSC::Machine::cti_op_resolve_func): Ditto.
     79        (JSC::Machine::cti_op_put_by_val): Ditto.
     80        (JSC::Machine::cti_op_put_by_val_array): Ditto.
     81        (JSC::Machine::cti_op_resolve_skip): Ditto.
     82        (JSC::Machine::cti_op_resolve_global): Ditto.
     83        (JSC::Machine::cti_op_post_inc): Ditto.
     84        (JSC::Machine::cti_op_resolve_with_base): Ditto.
     85        (JSC::Machine::cti_op_post_dec): Ditto.
     86        (JSC::Machine::cti_op_call_eval): Ditto.
     87        (JSC::Machine::cti_op_throw): Ditto. Also rearranged to return
     88        the exception value as the return value so it can be used by
     89        op_catch.
     90        (JSC::Machine::cti_op_push_scope): Ditto.
     91        (JSC::Machine::cti_op_in): Ditto.
     92        (JSC::Machine::cti_op_del_by_val): Ditto.
     93        (JSC::Machine::cti_vm_throw): Ditto. Also rearranged to return
     94        the exception value as the return value so it can be used by
     95        op_catch.
     96
     97        * kjs/DebuggerCallFrame.cpp:
     98        (JSC::DebuggerCallFrame::functionName): Pass globalData.
     99        (JSC::DebuggerCallFrame::evaluate): Eliminated code to make a
     100        new ExecState.
     101        * kjs/DebuggerCallFrame.h: Removed ExecState argument from
     102        constructor.
     103
     104        * kjs/ExecState.h: Eliminated all data members and made ExecState
     105        inherit privately from Register instead. Also added a typedef to
     106        the future name for this class, which is CallFrame. It's just a
     107        Register* that knows it's a pointer at a call frame. The new class
     108        can't be constructed or copied. Changed all functions to use
     109        the this pointer instead of m_callFrame. Changed exception-related
     110        functions to access an exception in JSGlobalData. Removed functions
     111        used by CTI to pass the return address to the throw machinery --
     112        this is now done directly with a global in the global data.
     113
     114        * kjs/FunctionPrototype.cpp:
     115        (JSC::functionProtoFuncToString): Pass globalData instead of exec.
     116
     117        * kjs/InternalFunction.cpp:
     118        (JSC::InternalFunction::name): Take globalData instead of exec.
     119        * kjs/InternalFunction.h: Ditto.
     120
     121        * kjs/JSGlobalData.cpp: Initialize the new exception global to 0.
     122        * kjs/JSGlobalData.h: Declare two new globals. One for the current
     123        exception and another for the return address used by CTI to
     124        implement the throw operation.
     125
     126        * kjs/JSGlobalObject.cpp:
     127        (JSC::JSGlobalObject::init): Removed code to set up globalExec,
     128        which is now the same thing as globalCallFrame.
     129        (JSC::JSGlobalObject::reset): Get globalExec from our globalExec
     130        function so we don't have to repeat the logic twice.
     131        (JSC::JSGlobalObject::mark): Removed code to mark the exception;
     132        the exception is now stored in JSGlobalData and marked there.
     133        (JSC::JSGlobalObject::globalExec): Return a pointer to the end
     134        of the global call frame.
     135        * kjs/JSGlobalObject.h: Removed the globalExec data member.
     136
     137        * kjs/JSObject.cpp:
     138        (JSC::JSObject::putDirectFunction): Pass globalData instead of exec.
     139
     140        * kjs/collector.cpp:
     141        (JSC::Heap::collect): Mark the global exception.
     142
     143        * profiler/ProfileGenerator.cpp:
     144        (JSC::ProfileGenerator::addParentForConsoleStart): Pass globalData
     145        instead of exec to createCallIdentifier.
     146
     147        * profiler/Profiler.cpp:
     148        (JSC::Profiler::willExecute): Pass globalData instead of exec to
     149        createCallIdentifier.
     150        (JSC::Profiler::didExecute): Ditto.
     151        (JSC::Profiler::createCallIdentifier): Take globalData instead of
     152        exec.
     153        (JSC::createCallIdentifierFromFunctionImp): Ditto.
     154        * profiler/Profiler.h: Change interface to take a JSGlobalData
     155        instead of an ExecState.
     156
    11572008-10-04  Cameron Zwarich  <[email protected]>
    2158
  • trunk/JavaScriptCore/VM/CTI.cpp

    r37294 r37297  
    7575
    7676#if COMPILER(GCC) && PLATFORM(X86)
     77
    7778asm(
    7879".globl _ctiTrampoline" "\n"
     
    8283    "subl $0x24, %esp" "\n"
    8384    "movl $512, %esi" "\n"
    84     "call *0x30(%esp)" "\n" //Ox30 = 0x0C * 4, 0x0C = CTI_ARGS_code
     85    "call *0x30(%esp)" "\n" // Ox30 = 0x0C * 4, 0x0C = CTI_ARGS_code
    8586    "addl $0x24, %esp" "\n"
    8687    "popl %edi" "\n"
     
    9293".globl _ctiVMThrowTrampoline" "\n"
    9394"_ctiVMThrowTrampoline:" "\n"
    94 #ifndef NDEBUG
    95     "movl 0x34(%esp), %ecx" "\n" //Ox34 = 0x0D * 4, 0x0D = CTI_ARGS_exec
    96     "cmpl $0, 8(%ecx)" "\n"
    97     "jne 1f" "\n"
    98     "int3" "\n"
    99     "1:" "\n"
    100 #endif
    10195    "call __ZN3JSC7Machine12cti_vm_throwEPv" "\n"
    10296    "addl $0x24, %esp" "\n"
     
    107101   
    108102#elif COMPILER(MSVC)
    109 extern "C"
    110 {
     103
     104extern "C" {
    111105   
    112     __declspec(naked) JSValue* ctiTrampoline(void* code, ExecState* exec, RegisterFile* registerFile, Register* r, JSValue** exception, Profiler**, JSGlobalData*)
     106    __declspec(naked) JSValue* ctiTrampoline(void* code, RegisterFile*, Register*, JSValue** exception, Profiler**, JSGlobalData*)
    113107    {
    114108        __asm {
     
    129123    {
    130124        __asm {
    131            mov [esp], esp;
     125            mov [esp], esp;
    132126            call JSC::Machine::cti_vm_throw;
    133127            add esp, 0x24;
     
    247241}
    248242
    249 #ifdef NDEBUG
    250 
    251 ALWAYS_INLINE void CTI::emitDebugExceptionCheck()
    252 {
    253 }
    254 
    255 #else
    256 
    257 ALWAYS_INLINE void CTI::emitDebugExceptionCheck()
    258 {
    259     emitGetCTIParam(CTI_ARGS_exec, X86::ecx);
    260     m_jit.cmpl_i32m(0, OBJECT_OFFSET(ExecState, m_exception), X86::ecx);
    261     X86Assembler::JmpSrc noException = m_jit.emitUnlinkedJe();
    262     m_jit.emitInt3();
    263     m_jit.link(noException, m_jit.label());
    264 }
     243#ifndef NDEBUG
    265244
    266245void CTI::printOpcodeOperandTypes(unsigned src1, unsigned src2)
     
    305284    X86Assembler::JmpSrc call = m_jit.emitCall(r);
    306285    m_calls.append(CallRecord(call, opcodeIndex));
    307     emitDebugExceptionCheck();
    308286
    309287    return call;
     
    318296    X86Assembler::JmpSrc call = m_jit.emitCall();
    319297    m_calls.append(CallRecord(call, helper, opcodeIndex));
    320     emitDebugExceptionCheck();
    321298#if ENABLE(SAMPLING_TOOL)
    322299    m_jit.movl_i32m(0, &inCalledCode);
     
    334311    X86Assembler::JmpSrc call = m_jit.emitCall();
    335312    m_calls.append(CallRecord(call, helper, opcodeIndex));
    336     emitDebugExceptionCheck();
    337313#if ENABLE(SAMPLING_TOOL)
    338314    m_jit.movl_i32m(0, &inCalledCode);
     
    350326    X86Assembler::JmpSrc call = m_jit.emitCall();
    351327    m_calls.append(CallRecord(call, helper, opcodeIndex));
    352     emitDebugExceptionCheck();
    353328#if ENABLE(SAMPLING_TOOL)
    354329    m_jit.movl_i32m(0, &inCalledCode);
     
    366341    X86Assembler::JmpSrc call = m_jit.emitCall();
    367342    m_calls.append(CallRecord(call, helper, opcodeIndex));
    368     emitDebugExceptionCheck();
    369343#if ENABLE(SAMPLING_TOOL)
    370344    m_jit.movl_i32m(0, &inCalledCode);
     
    382356    X86Assembler::JmpSrc call = m_jit.emitCall();
    383357    m_calls.append(CallRecord(call, helper, opcodeIndex));
    384     emitDebugExceptionCheck();
    385358#if ENABLE(SAMPLING_TOOL)
    386359    m_jit.movl_i32m(0, &inCalledCode);
     
    12241197
    12251198            // Restore our caller's "r".
    1226             emitGetCTIParam(CTI_ARGS_exec, X86::ecx);
    12271199            emitGetArg(RegisterFile::CallerRegisters, X86::edi);
    12281200            emitPutCTIParam(X86::edi, CTI_ARGS_r);
    1229             m_jit.movl_rm(X86::edi, OBJECT_OFFSET(ExecState, m_callFrame), X86::ecx);
    12301201
    12311202            // Return.
     
    17871758        case op_catch: {
    17881759            emitGetCTIParam(CTI_ARGS_r, X86::edi); // edi := r
    1789             emitGetCTIParam(CTI_ARGS_exec, X86::ecx);
    1790             m_jit.movl_mr(OBJECT_OFFSET(ExecState, m_exception), X86::ecx, X86::eax);
    1791             m_jit.movl_i32m(0, OBJECT_OFFSET(ExecState, m_exception), X86::ecx);
    17921760            emitPutResult(instruction[i + 1].u.operand);
    17931761            i += 2;
  • trunk/JavaScriptCore/VM/CTI.h

    r37257 r37297  
    5353
    5454#define CTI_ARGS_code 0x0C
    55 #define CTI_ARGS_exec 0x0D
    56 #define CTI_ARGS_registerFile 0x0E
    57 #define CTI_ARGS_r 0x0F
    58 #define CTI_ARGS_exception 0x10
    59 #define CTI_ARGS_profilerReference 0x11
    60 #define CTI_ARGS_globalData 0x12
    61 #define ARG_exec ((ExecState*)(ARGS)[CTI_ARGS_exec])
     55#define CTI_ARGS_registerFile 0x0D
     56#define CTI_ARGS_r 0x0E
     57#define CTI_ARGS_exception 0x0F
     58#define CTI_ARGS_profilerReference 0x10
     59#define CTI_ARGS_globalData 0x11
    6260#define ARG_registerFile ((RegisterFile*)(ARGS)[CTI_ARGS_registerFile])
    6361#define ARG_r ((Register*)(ARGS)[CTI_ARGS_r])
     
    6664#define ARG_globalData ((JSGlobalData*)(ARGS)[CTI_ARGS_globalData])
    6765
    68 #define ARG_setR(newR) (*(volatile Register**)&(ARGS)[CTI_ARGS_r] = newR)
    69 #define ARG_set2ndResult(new2ndResult) (*(volatile JSValue**)&(ARGS)[CTI_ARGS_2ndResult] = new2ndResult)
     66#define ARG_exec CallFrame::create(ARG_r)
     67
     68#define ARG_setR(newR) (*(Register**)&(ARGS)[CTI_ARGS_r] = newR)
     69#define ARG_set2ndResult(new2ndResult) (*(JSValue**)&(ARGS)[CTI_ARGS_2ndResult] = new2ndResult)
    7070
    7171#define ARG_src1 ((JSValue*)((ARGS)[1]))
     
    235235
    236236    extern "C" {
    237         JSValue* ctiTrampoline(void* code, ExecState*, RegisterFile*, Register* callFrame, JSValue** exception, Profiler**, JSGlobalData*);
     237        JSValue* ctiTrampoline(void* code, RegisterFile*, Register* callFrame, JSValue** exception, Profiler**, JSGlobalData*);
    238238        void ctiVMThrowTrampoline();
    239239    };
     
    324324        }
    325325
    326         inline static JSValue* execute(void* code, ExecState* exec, RegisterFile* registerFile, Register* r, JSGlobalData* globalData, JSValue** exception)
    327         {
    328             JSValue* value = ctiTrampoline(code, exec, registerFile, r, exception, Profiler::enabledProfilerReference(), globalData);
     326        inline static JSValue* execute(void* code, RegisterFile* registerFile, Register* r, JSGlobalData* globalData, JSValue** exception)
     327        {
     328            JSValue* value = ctiTrampoline(code, registerFile, r, exception, Profiler::enabledProfilerReference(), globalData);
    329329#if ENABLE(SAMPLING_TOOL)
    330330            currentOpcodeID = static_cast<OpcodeID>(-1);
     
    394394        void emitTagAsBoolImmediate(X86Assembler::RegisterID reg);
    395395
    396         void emitDebugExceptionCheck();
    397 
    398396        X86Assembler::JmpSrc emitCall(unsigned opcodeIndex, X86::RegisterID);
    399397        X86Assembler::JmpSrc emitCall(unsigned opcodeIndex, CTIHelper_j);
  • trunk/JavaScriptCore/VM/ExceptionHelpers.cpp

    r37184 r37297  
    5151class InterruptedExecutionError : public JSObject {
    5252public:
    53     InterruptedExecutionError(ExecState* exec)
    54         : JSObject(exec->globalData().nullProtoStructureID)
     53    InterruptedExecutionError(JSGlobalData* globalData)
     54        : JSObject(globalData->nullProtoStructureID)
    5555    {
    5656    }
     
    5959};
    6060
    61 JSValue* createInterruptedExecutionException(ExecState* exec)
    62 {
    63     return new (exec) InterruptedExecutionError(exec);
     61JSValue* createInterruptedExecutionException(JSGlobalData* globalData)
     62{
     63    return new (globalData) InterruptedExecutionError(globalData);
    6464}
    6565
  • trunk/JavaScriptCore/VM/ExceptionHelpers.h

    r36604 r37297  
    3030#define ExceptionHelpers_h
    3131
    32 #include "JSObject.h"
    33 
    3432namespace JSC {
    3533
     34    class CodeBlock;
     35    class ExecState;
     36    class Identifier;
     37    class Instruction;
     38    class JSGlobalData;
     39    class JSNotAnObjectErrorStub;
     40    class JSObject;
     41    class JSValue;
    3642    class Node;
    37     class CodeBlock;
    38     class Instruction;
    39     class JSNotAnObjectErrorStub;
    4043
    41     JSValue* createInterruptedExecutionException(ExecState* exec);
     44    JSValue* createInterruptedExecutionException(JSGlobalData*);
    4245    JSValue* createStackOverflowError(ExecState*);
    4346    JSValue* createUndefinedVariableError(ExecState*, const Identifier&, const Instruction*, CodeBlock*);
  • trunk/JavaScriptCore/VM/Machine.cpp

    r37294 r37297  
    533533}
    534534
    535 ALWAYS_INLINE Register* slideRegisterWindowForCall(ExecState* exec, CodeBlock* newCodeBlock, RegisterFile* registerFile, Register* r, size_t registerOffset, int argc, JSValue*& exceptionValue)
     535ALWAYS_INLINE Register* slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, Register* r, size_t registerOffset, int argc)
    536536{
    537537    Register* newEnd = r + registerOffset + newCodeBlock->numCalleeRegisters;
    538538
    539     if (argc == newCodeBlock->numParameters) { // correct number of arguments
    540         if (!registerFile->grow(newEnd)) {
    541             exceptionValue = createStackOverflowError(exec);
    542             return r;
    543         }
     539    if (LIKELY(argc == newCodeBlock->numParameters)) { // correct number of arguments
     540        if (UNLIKELY(!registerFile->grow(newEnd)))
     541            return 0;
    544542        r += registerOffset;
    545543    } else if (argc < newCodeBlock->numParameters) { // too few arguments -- fill in the blanks
     
    547545        registerOffset += omittedArgCount;
    548546        newEnd += omittedArgCount;
    549         if (!registerFile->grow(newEnd)) {
    550             exceptionValue = createStackOverflowError(exec);
    551             return r;
    552         }
     547        if (!registerFile->grow(newEnd))
     548            return 0;
    553549        r += registerOffset;
    554550
     
    561557        newEnd += numParameters;
    562558
    563         if (!registerFile->grow(newEnd)) {
    564             exceptionValue = createStackOverflowError(exec);
    565             return r;
    566         }
     559        if (!registerFile->grow(newEnd))
     560            return 0;
    567561        r += registerOffset;
    568562
     
    627621{
    628622    initTimeout();
    629     privateExecute(InitializeAndReturn);
     623    privateExecute(InitializeAndReturn, 0, 0, 0);
    630624   
    631625    // Bizarrely, calling fastMalloc here is faster than allocating space on the stack.
     
    768762
    769763    if (Debugger* debugger = exec->dynamicGlobalObject()->debugger()) {
    770         DebuggerCallFrame debuggerCallFrame(exec, exec->dynamicGlobalObject(), codeBlock, scopeChain, r, exceptionValue);
     764        DebuggerCallFrame debuggerCallFrame(exec->dynamicGlobalObject(), codeBlock, scopeChain, r, exceptionValue);
    771765        if (r[RegisterFile::Callee].jsValue(exec))
    772766            debugger->returnEvent(debuggerCallFrame, codeBlock->ownerNode->sourceID(), codeBlock->ownerNode->lastLine());
     
    799793        return false;
    800794
    801     exec->m_callFrame = r;
    802795    codeBlock = this->codeBlock(r);
    803796    vPC = vPCForPC(codeBlock, returnPC);
     
    850843    if (Debugger* debugger = exec->dynamicGlobalObject()->debugger()) {
    851844        ScopeChainNode* scopeChain = this->scopeChain(r);
    852         DebuggerCallFrame debuggerCallFrame(exec, exec->dynamicGlobalObject(), codeBlock, scopeChain, r, exceptionValue);
     845        DebuggerCallFrame debuggerCallFrame(exec->dynamicGlobalObject(), codeBlock, scopeChain, r, exceptionValue);
    853846        debugger->exception(debuggerCallFrame, codeBlock->ownerNode->sourceID(), codeBlock->lineNumberForVPC(vPC));
    854847    }
     
    905898        scopeChain = scopeChain->copy();
    906899
    907     ExecState newExec(r);
    908 
    909900    Profiler** profiler = Profiler::enabledProfilerReference();
    910901    if (*profiler)
     
    915906    if (!codeBlock->ctiCode)
    916907        CTI::compile(this, exec, codeBlock);
    917     JSValue* result = CTI::execute(codeBlock->ctiCode, &newExec, &m_registerFile, r, &newExec.globalData(), exception);
     908    JSValue* result = CTI::execute(codeBlock->ctiCode, &m_registerFile, r, scopeChain->globalData, exception);
    918909#else
    919     JSValue* result = privateExecute(Normal, &newExec, &m_registerFile, r, exception);
     910    JSValue* result = privateExecute(Normal, &m_registerFile, r, exception);
    920911#endif
    921912    m_reentryDepth--;
     
    959950
    960951    CodeBlock* codeBlock = &functionBodyNode->byteCode(scopeChain);
    961     Register* r = slideRegisterWindowForCall(exec, codeBlock, &m_registerFile, argv, argc + RegisterFile::CallFrameHeaderSize, argc, *exception);
    962     if (UNLIKELY(*exception != 0)) {
     952    Register* r = slideRegisterWindowForCall(codeBlock, &m_registerFile, argv, argc + RegisterFile::CallFrameHeaderSize, argc);
     953    if (UNLIKELY(!r)) {
     954        *exception = createStackOverflowError(exec);
    963955        m_registerFile.shrink(oldEnd);
    964956        return jsNull();
    965957    }
    966958    // a 0 codeBlock indicates a built-in caller
    967     initializeCallFrame(r, codeBlock, 0, scopeChain, makeHostCallFramePointer(exec->m_callFrame), 0, argc, function);
    968 
    969     ExecState newExec(r);
     959    initializeCallFrame(r, codeBlock, 0, scopeChain, makeHostCallFramePointer(exec->registers()), 0, argc, function);
    970960
    971961    Profiler** profiler = Profiler::enabledProfilerReference();
     
    977967    if (!codeBlock->ctiCode)
    978968        CTI::compile(this, exec, codeBlock);
    979     JSValue* result = CTI::execute(codeBlock->ctiCode, &newExec, &m_registerFile, r, &newExec.globalData(), exception);
     969    JSValue* result = CTI::execute(codeBlock->ctiCode, &m_registerFile, r, scopeChain->globalData, exception);
    980970#else
    981     JSValue* result = privateExecute(Normal, &newExec, &m_registerFile, r, exception);
     971    JSValue* result = privateExecute(Normal, &m_registerFile, r, exception);
    982972#endif
    983973    m_reentryDepth--;
     
    10481038    // a 0 codeBlock indicates a built-in caller
    10491039    r[codeBlock->thisRegister] = thisObj;
    1050     initializeCallFrame(r, codeBlock, 0, scopeChain, makeHostCallFramePointer(exec->m_callFrame), 0, 0, 0);
     1040    initializeCallFrame(r, codeBlock, 0, scopeChain, makeHostCallFramePointer(exec->registers()), 0, 0, 0);
    10511041
    10521042    if (codeBlock->needsFullScopeChain)
    10531043        scopeChain = scopeChain->copy();
    1054 
    1055     ExecState newExec(r);
    10561044
    10571045    Profiler** profiler = Profiler::enabledProfilerReference();
     
    10631051    if (!codeBlock->ctiCode)
    10641052        CTI::compile(this, exec, codeBlock);
    1065     JSValue* result = CTI::execute(codeBlock->ctiCode, &newExec, &m_registerFile, r, &newExec.globalData(), exception);
     1053    JSValue* result = CTI::execute(codeBlock->ctiCode, &m_registerFile, r, scopeChain->globalData, exception);
    10661054#else
    1067     JSValue* result = privateExecute(Normal, &newExec, &m_registerFile, r, exception);
     1055    JSValue* result = privateExecute(Normal, &m_registerFile, r, exception);
    10681056#endif
    10691057    m_reentryDepth--;
     
    10861074    CodeBlock* codeBlock = this->codeBlock(r);
    10871075    ScopeChainNode* scopeChain = this->scopeChain(r);
    1088     DebuggerCallFrame debuggerCallFrame(exec, exec->dynamicGlobalObject(), codeBlock, scopeChain, r, 0);
     1076    DebuggerCallFrame debuggerCallFrame(exec->dynamicGlobalObject(), codeBlock, scopeChain, r, 0);
    10891077
    10901078    switch (debugHookID) {
     
    14191407}
    14201408
    1421 JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFile* registerFile, Register* r, JSValue** exception)
     1409JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile, Register* r, JSValue** exception)
    14221410{
    14231411    // One-time initialization of our address tables. We have to put this code
     
    14441432#endif
    14451433
     1434#define exec CallFrame::create(r)
     1435
     1436    JSGlobalData* globalData = &exec->globalData();
    14461437    JSValue* exceptionValue = 0;
    14471438    Instruction* handlerVPC = 0;
     
    14531444#define VM_CHECK_EXCEPTION() \
    14541445    do { \
    1455         if (UNLIKELY(exec->hadException())) { \
    1456             exceptionValue = exec->exception(); \
     1446        if (UNLIKELY(globalData->exception != 0)) { \
     1447            exceptionValue = globalData->exception; \
    14571448            goto vm_throw; \
    14581449        } \
     
    15271518        int dst = (++vPC)->u.operand;
    15281519        int regExp = (++vPC)->u.operand;
    1529         r[dst] = new (exec) RegExpObject(scopeChain(r)->globalObject()->regExpStructure(), codeBlock(r)->regexps[regExp]);
     1520        r[dst] = new (globalData) RegExpObject(scopeChain(r)->globalObject()->regExpStructure(), codeBlock(r)->regexps[regExp]);
    15301521
    15311522        ++vPC;
     
    32843275            Register* savedR = r;
    32853276
    3286             r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, r, registerOffset, argCount, exceptionValue);
    3287             exec->m_callFrame = r;
    3288             if (UNLIKELY(exceptionValue != 0))
     3277            r = slideRegisterWindowForCall(newCodeBlock, registerFile, r, registerOffset, argCount);
     3278            if (UNLIKELY(!r)) {
     3279                r = savedR;
     3280                exceptionValue = createStackOverflowError(CallFrame::create(r));
    32893281                goto vm_throw;
     3282            }
    32903283
    32913284            initializeCallFrame(r, newCodeBlock, vPC + 1, callDataScopeChain, savedR, dst, argCount, v);
     
    33093302            ScopeChainNode* scopeChain = this->scopeChain(r);
    33103303            initializeCallFrame(r + registerOffset, 0, vPC + 1, scopeChain, r, dst, argCount, v);
    3311             exec->m_callFrame = r + registerOffset;
     3304            ExecState* callFrame = CallFrame::create(r + registerOffset);
    33123305
    33133306            if (*enabledProfilerReference)
    3314                 (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v));
     3307                (*enabledProfilerReference)->willExecute(callFrame, static_cast<JSObject*>(v));
    33153308
    33163309            MACHINE_SAMPLING_callingHostFunction();
    33173310
    3318             JSValue* returnValue = callData.native.function(exec, static_cast<JSObject*>(v), thisValue, args);
    3319             exec->m_callFrame = r;
     3311            JSValue* returnValue = callData.native.function(callFrame, static_cast<JSObject*>(v), thisValue, args);
    33203312            VM_CHECK_EXCEPTION();
    33213313
     
    33233315
    33243316            if (*enabledProfilerReference)
    3325                 (*enabledProfilerReference)->didExecute(exec, static_cast<JSObject*>(v));
     3317                (*enabledProfilerReference)->didExecute(CallFrame::create(r), static_cast<JSObject*>(v));
    33263318
    33273319            ++vPC;
     
    33673359        int dst = r[RegisterFile::ReturnValueRegister].i();
    33683360        r = r[RegisterFile::CallerRegisters].r();
    3369         exec->m_callFrame = r;
    33703361       
    33713362        if (isHostCallFrame(r))
     
    34223413            r[i] = codeBlock->constantRegisters[j];
    34233414
    3424         JSActivation* activation = new (exec) JSActivation(exec, static_cast<FunctionBodyNode*>(codeBlock->ownerNode), r);
     3415        JSActivation* activation = new (globalData) JSActivation(exec, static_cast<FunctionBodyNode*>(codeBlock->ownerNode), r);
    34253416        r[RegisterFile::OptionalCalleeActivation] = activation;
    34263417        r[RegisterFile::ScopeChain] = scopeChain(r)->copy()->push(activation);
     
    34533444        if (activation) {
    34543445            ASSERT(activation->isObject(&JSActivation::info));
    3455             arguments = new (exec) Arguments(exec, static_cast<JSActivation*>(activation));
     3446            arguments = new (globalData) Arguments(exec, static_cast<JSActivation*>(activation));
    34563447        } else
    3457             arguments = new (exec) Arguments(exec, r);
     3448            arguments = new (globalData) Arguments(exec, r);
    34583449        r[RegisterFile::OptionalCalleeArguments] = arguments;
    34593450        r[RegisterFile::ArgumentsRegister] = arguments;
     
    35033494            else
    35043495                structure = callDataScopeChain->globalObject()->emptyObjectStructure();
    3505             JSObject* newObject = new (exec) JSObject(structure);
     3496            JSObject* newObject = new (globalData) JSObject(structure);
    35063497
    35073498            r[firstArg] = newObject; // "this" value
     
    35093500            Register* savedR = r;
    35103501
    3511             r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, r, registerOffset, argCount, exceptionValue);
    3512             exec->m_callFrame = r;
    3513             if (UNLIKELY(exceptionValue != 0))
     3502            r = slideRegisterWindowForCall(newCodeBlock, registerFile, r, registerOffset, argCount);
     3503            if (UNLIKELY(!r)) {
     3504                r = savedR;
     3505                exceptionValue = createStackOverflowError(CallFrame::create(r));
    35143506                goto vm_throw;
     3507            }
    35153508
    35163509            initializeCallFrame(r, newCodeBlock, vPC + 1, callDataScopeChain, savedR, dst, argCount, v);
     
    35333526            ScopeChainNode* scopeChain = this->scopeChain(r);
    35343527            initializeCallFrame(r + registerOffset, 0, vPC + 1, scopeChain, r, dst, argCount, v);
    3535             exec->m_callFrame = r + registerOffset;
     3528            r += registerOffset;
    35363529
    35373530            if (*enabledProfilerReference)
     
    35413534
    35423535            JSValue* returnValue = constructData.native.function(exec, static_cast<JSObject*>(v), args);
    3543             exec->m_callFrame = r;
     3536            r -= registerOffset;
    35443537
    35453538            VM_CHECK_EXCEPTION();
     
    38613854    }
    38623855    vm_throw: {
    3863         exec->clearException();
     3856        globalData->exception = 0;
    38643857        if (!tickCount) {
    38653858            // The exceptionValue is a lie! (GCC produces bad code for reasons I
    38663859            // cannot fathom if we don't assign to the exceptionValue before branching)
    3867             exceptionValue = createInterruptedExecutionException(exec);
     3860            exceptionValue = createInterruptedExecutionException(globalData);
    38683861        }
    38693862        handlerVPC = throwException(exec, exceptionValue, vPC, r, false);
     
    38803873    #undef VM_CHECK_EXCEPTION
    38813874    #undef CHECK_FOR_TIMEOUT
     3875    #undef exec
    38823876}
    38833877
     
    39343928    sourceURL = UString();
    39353929
    3936     Register* r = exec->m_callFrame;
     3930    Register* r = exec->registers();
    39373931    Register* callerR = r[RegisterFile::CallerRegisters].r();
    39383932    if (isHostCallFrame(callerR))
     
    39653959Register* Machine::callFrame(ExecState* exec, InternalFunction* function) const
    39663960{
    3967     for (Register* r = exec->m_callFrame; r; r = stripHostCallFrameBit(r[RegisterFile::CallerRegisters].r()))
     3961    for (Register* r = exec->registers(); r; r = stripHostCallFrameBit(r[RegisterFile::CallerRegisters].r()))
    39683962        if (r[RegisterFile::Callee].getJSValue() == function)
    39693963            return r;
     
    39933987NEVER_INLINE static void doSetReturnAddressVMThrowTrampoline(void** returnAddress)
    39943988{
    3995     ctiSetReturnAddress(returnAddress, (void*)ctiVMThrowTrampoline);
     3989    ctiSetReturnAddress(returnAddress, reinterpret_cast<void*>(ctiVMThrowTrampoline));
    39963990}
    39973991
     
    42084202}
    42094203
    4210 
    4211 #define JSVALUE_VM_CHECK_EXCEPTION_ARG(exception) \
     4204#define VM_THROW_EXCEPTION() \
    42124205    do { \
    4213         if (UNLIKELY(exception != 0)) { \
    4214             exec->setException(exception); \
    4215             exec->setCTIReturnAddress(CTI_RETURN_ADDRESS); \
    4216             doSetReturnAddressVMThrowTrampoline(&CTI_RETURN_ADDRESS); \
    4217             return 0; \
    4218         } \
     4206        VM_THROW_EXCEPTION_AT_END(); \
     4207        return 0; \
    42194208    } while (0)
    4220 #define VM_CHECK_EXCEPTION_v() \
     4209#define VM_THROW_EXCEPTION_AT_END() \
    42214210    do { \
    4222         if (UNLIKELY(exec->hadException())) { \
    4223             exec->setCTIReturnAddress(CTI_RETURN_ADDRESS); \
    4224             doSetReturnAddressVMThrowTrampoline(&CTI_RETURN_ADDRESS); \
    4225             return; \
    4226         } \
     4211        ASSERT(ARG_globalData->exception); \
     4212        ARG_globalData->throwReturnAddress = CTI_RETURN_ADDRESS; \
     4213        doSetReturnAddressVMThrowTrampoline(&CTI_RETURN_ADDRESS); \
    42274214    } while (0)
    4228 #define VM_CHECK_EXCEPTION(type) \
     4215
     4216#define VM_CHECK_EXCEPTION() \
    42294217    do { \
    4230         if (UNLIKELY(exec->hadException())) { \
    4231             exec->setCTIReturnAddress(CTI_RETURN_ADDRESS); \
    4232             doSetReturnAddressVMThrowTrampoline(&CTI_RETURN_ADDRESS); \
    4233             return (type)0; \
     4218        if (UNLIKELY(ARG_globalData->exception != 0)) \
     4219            VM_THROW_EXCEPTION(); \
     4220    } while (0)
     4221#define VM_CHECK_EXCEPTION_ARG(exceptionValue) \
     4222    do { \
     4223        if (UNLIKELY((exceptionValue) != 0)) { \
     4224            ARG_globalData->exception = (exceptionValue); \
     4225            VM_THROW_EXCEPTION(); \
    42344226        } \
    42354227    } while (0)
    42364228#define VM_CHECK_EXCEPTION_AT_END() \
    42374229    do { \
    4238         if (UNLIKELY(exec->hadException())) { \
    4239             /*printf("VM_CHECK_EXCEPTION_AT_END()\n");*/ \
    4240             exec->setCTIReturnAddress(CTI_RETURN_ADDRESS); \
    4241             doSetReturnAddressVMThrowTrampoline(&CTI_RETURN_ADDRESS); \
     4230        if (UNLIKELY(ARG_globalData->exception != 0)) \
     4231            VM_THROW_EXCEPTION_AT_END(); \
     4232    } while (0)
     4233#define VM_CHECK_EXCEPTION_VOID() \
     4234    do { \
     4235        if (UNLIKELY(ARG_globalData->exception != 0)) { \
     4236            VM_THROW_EXCEPTION_AT_END(); \
     4237            return; \
    42424238        } \
    42434239    } while (0)
    4244 
    42454240
    42464241JSValue* Machine::cti_op_convert_this(CTI_ARGS)
     
    42804275        RefPtr<UString::Rep> value = concatenate(static_cast<JSString*>(v1)->value().rep(), static_cast<JSString*>(v2)->value().rep());
    42814276        if (UNLIKELY(!value)) {
    4282             JSValue* result = throwOutOfMemoryError(exec);
    4283             VM_CHECK_EXCEPTION_AT_END();
    4284             return result;
     4277            throwOutOfMemoryError(exec);
     4278            VM_THROW_EXCEPTION();
    42854279        }
    42864280
     
    42944288
    42954289        if (UNLIKELY(!value)) {
    4296             JSValue* result = throwOutOfMemoryError(exec);
    4297             VM_CHECK_EXCEPTION_AT_END();
    4298             return result;
     4290            throwOutOfMemoryError(exec);
     4291            VM_THROW_EXCEPTION();
    42994292        }
    43004293        return jsString(ARG_globalData, value.release());
     
    43124305
    43134306    ExecState* exec = ARG_exec;
    4314     JSValue* result = jsNumber(exec, v->toNumber(exec) + 1);
     4307    JSValue* result = jsNumber(ARG_globalData, v->toNumber(exec) + 1);
    43154308    VM_CHECK_EXCEPTION_AT_END();
    43164309    return result;
     
    43194312void Machine::cti_timeout_check(CTI_ARGS)
    43204313{
    4321     ExecState* exec = ARG_exec;
    4322 
    4323     if (ARG_globalData->machine->checkTimeout(exec->dynamicGlobalObject()))
    4324         exec->setException(createInterruptedExecutionException(exec));
    4325 
    4326     VM_CHECK_EXCEPTION_AT_END();
     4314    if (ARG_globalData->machine->checkTimeout(ARG_exec->dynamicGlobalObject())) {
     4315        ARG_globalData->exception = createInterruptedExecutionException(ARG_globalData);
     4316        VM_THROW_EXCEPTION_AT_END();
     4317    }
    43274318}
    43284319
     
    44874478        ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(CTI_RETURN_ADDRESS));
    44884479        unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(CTI_RETURN_ADDRESS);
    4489         exec->setException(createInvalidParamError(exec, "instanceof", baseVal, codeBlock->instructions.begin() + vPCIndex, codeBlock));
    4490         VM_CHECK_EXCEPTION(JSValue*);
     4480        ARG_globalData->exception = createInvalidParamError(exec, "instanceof", baseVal, codeBlock->instructions.begin() + vPCIndex, codeBlock);
     4481        VM_THROW_EXCEPTION();
    44914482    }
    44924483
     
    44964487    if (!proto->isObject()) {
    44974488        throwError(exec, TypeError, "instanceof called on an object with an invalid prototype property.");
    4498         VM_CHECK_EXCEPTION(JSValue*);
     4489        VM_THROW_EXCEPTION();
    44994490    }
    45004491       
     
    45384529JSValue* Machine::cti_op_new_func(CTI_ARGS)
    45394530{
    4540     Register* r = ARG_r;
    4541     ScopeChainNode* scopeChain = Machine::scopeChain(r);
    4542     return ARG_func1->makeFunction(ARG_exec, scopeChain);
     4531    return ARG_func1->makeFunction(ARG_exec, Machine::scopeChain(ARG_r));
    45434532}
    45444533
    45454534void* Machine::cti_op_call_JSFunction(CTI_ARGS)
    45464535{
    4547     ExecState* exec = ARG_exec;
    4548     RegisterFile* registerFile = ARG_registerFile;
    4549     Register* r = ARG_r;
    4550 
    4551     JSValue* funcVal = ARG_src1;
    4552     int registerOffset = ARG_int2;
    4553     int argCount = ARG_int3;
    4554 
    45554536#ifndef NDEBUG
    45564537    CallData callData;
    4557     ASSERT(funcVal->getCallData(callData) == CallTypeJS);
     4538    ASSERT(ARG_src1->getCallData(callData) == CallTypeJS);
    45584539#endif
    45594540
    4560     if (*ARG_profilerReference)
    4561         (*ARG_profilerReference)->willExecute(exec, static_cast<JSObject*>(funcVal));
    4562 
    4563     ScopeChainNode* callDataScopeChain = static_cast<JSFunction*>(funcVal)->m_scopeChain.node();
    4564     FunctionBodyNode* functionBodyNode = static_cast<JSFunction*>(funcVal)->m_body.get();
    4565 
    4566     CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeChain);
    4567    
    4568     Register* savedR = r;
    4569 
    4570     JSValue* exceptionValue = 0;
    4571     r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, r, registerOffset, argCount, exceptionValue);
    4572     JSVALUE_VM_CHECK_EXCEPTION_ARG(exceptionValue);
     4541    if (UNLIKELY(*ARG_profilerReference != 0))
     4542        (*ARG_profilerReference)->willExecute(CallFrame::create(ARG_r), static_cast<JSObject*>(ARG_src1));
     4543
     4544    ScopeChainNode* callDataScopeChain = static_cast<JSFunction*>(ARG_src1)->m_scopeChain.node();
     4545    CodeBlock* newCodeBlock = &static_cast<JSFunction*>(ARG_src1)->m_body->byteCode(callDataScopeChain);
     4546
     4547    Register* r = slideRegisterWindowForCall(newCodeBlock, ARG_registerFile, ARG_r, ARG_int2, ARG_int3);
     4548    if (UNLIKELY(!r)) {
     4549        ARG_globalData->exception = createStackOverflowError(CallFrame::create(ARG_r));
     4550        VM_THROW_EXCEPTION();
     4551    }
    45734552
    45744553    r[RegisterFile::CodeBlock] = newCodeBlock;
    45754554    r[RegisterFile::ScopeChain] = callDataScopeChain;
    4576     r[RegisterFile::CallerRegisters] = savedR;
     4555    r[RegisterFile::CallerRegisters] = ARG_r;
    45774556    // RegisterFile::ReturnPC is set by callee
    45784557    // RegisterFile::ReturnValueRegister is set by caller
    4579     r[RegisterFile::ArgumentCount] = argCount; // original argument count (for the sake of the "arguments" object)
    4580     r[RegisterFile::Callee] = funcVal;
     4558    r[RegisterFile::ArgumentCount] = ARG_int3; // original argument count (for the sake of the "arguments" object)
     4559    r[RegisterFile::Callee] = ARG_src1;
    45814560    r[RegisterFile::OptionalCalleeActivation] = nullJSValue;
    45824561    r[RegisterFile::OptionalCalleeArguments] = nullJSValue;
    45834562
    4584     exec->m_callFrame = r;
    45854563    ARG_setR(r);
    45864564
     
    45904568void* Machine::cti_vm_compile(CTI_ARGS)
    45914569{
    4592     ExecState* exec = ARG_exec;
    45934570    Register* r = ARG_r;
    45944571    CodeBlock* codeBlock = Machine::codeBlock(r);
    45954572
    45964573    if (!codeBlock->ctiCode)
    4597         CTI::compile(ARG_globalData->machine, exec, codeBlock);
     4574        CTI::compile(ARG_globalData->machine, CallFrame::create(r), codeBlock);
    45984575
    45994576    return codeBlock->ctiCode;
     
    46074584    ScopeChainNode* scopeChain = Machine::scopeChain(r);
    46084585
    4609     JSActivation* activation = new (exec) JSActivation(exec, static_cast<FunctionBodyNode*>(codeBlock->ownerNode), r);
     4586    JSActivation* activation = new (ARG_globalData) JSActivation(exec, static_cast<FunctionBodyNode*>(codeBlock->ownerNode), r);
    46104587    r[RegisterFile::OptionalCalleeActivation] = activation;
    46114588    r[RegisterFile::ScopeChain] = scopeChain->copy()->push(activation);
     
    46144591JSValue* Machine::cti_op_call_NotJSFunction(CTI_ARGS)
    46154592{
    4616     ExecState* exec = ARG_exec;
    46174593    JSValue* funcVal = ARG_src1;
    46184594
     
    46294605
    46304606        initializeCallFrame(r, 0, ARG_instr4 + 1, scopeChain(savedR), savedR, 0, argCount, funcVal);
    4631         exec->m_callFrame = r;
    46324607        ARG_setR(r);
    46334608
    46344609        if (*ARG_profilerReference)
    4635             (*ARG_profilerReference)->willExecute(exec, static_cast<JSObject*>(funcVal));
     4610            (*ARG_profilerReference)->willExecute(CallFrame::create(r), static_cast<JSObject*>(funcVal));
    46364611
    46374612        Register* argv = r - RegisterFile::CallFrameHeaderSize - argCount;
     
    46404615        CTI_MACHINE_SAMPLING_callingHostFunction();
    46414616
    4642         JSValue* returnValue = callData.native.function(exec, static_cast<JSObject*>(funcVal), argv[0].jsValue(exec), argList);
    4643         exec->m_callFrame = savedR;
     4617        JSValue* returnValue = callData.native.function(CallFrame::create(r), static_cast<JSObject*>(funcVal), argv[0].jsValue(CallFrame::create(r)), argList);
    46444618        ARG_setR(savedR);
    4645         VM_CHECK_EXCEPTION(JSValue*);
     4619        VM_CHECK_EXCEPTION();
    46464620
    46474621        if (*ARG_profilerReference)
    4648             (*ARG_profilerReference)->didExecute(exec, static_cast<JSObject*>(funcVal));
     4622            (*ARG_profilerReference)->didExecute(CallFrame::create(savedR), static_cast<JSObject*>(funcVal));
    46494623
    46504624        return returnValue;
     
    46534627    ASSERT(callType == CallTypeNone);
    46544628
    4655     Register* r = ARG_r;
    4656     exec->setException(createNotAFunctionError(exec, funcVal, ARG_instr4, codeBlock(r)));
    4657     VM_CHECK_EXCEPTION_AT_END();
    4658     return 0;
     4629    ARG_globalData->exception = createNotAFunctionError(CallFrame::create(ARG_r), funcVal, ARG_instr4, codeBlock(ARG_r));
     4630    VM_THROW_EXCEPTION();
    46594631}
    46604632
     
    46684640    if (activation) {
    46694641        ASSERT(activation->isObject(&JSActivation::info));
    4670         arguments = new (exec) Arguments(exec, static_cast<JSActivation*>(activation));
     4642        arguments = new (ARG_globalData) Arguments(exec, static_cast<JSActivation*>(activation));
    46714643    } else
    4672         arguments = new (exec) Arguments(exec, r);
     4644        arguments = new (ARG_globalData) Arguments(exec, r);
    46734645    r[RegisterFile::OptionalCalleeArguments] = arguments;
    46744646    r[RegisterFile::ArgumentsRegister] = arguments;
     
    47374709    unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(CTI_RETURN_ADDRESS);
    47384710    exec->setException(createUndefinedVariableError(exec, ident, codeBlock->instructions.begin() + vPCIndex, codeBlock));
    4739 
    4740     VM_CHECK_EXCEPTION_AT_END();
    4741     return 0;
     4711    VM_THROW_EXCEPTION();
    47424712}
    47434713
    47444714void* Machine::cti_op_construct_JSConstruct(CTI_ARGS)
    47454715{
    4746     ExecState* exec = ARG_exec;
    47474716    RegisterFile* registerFile = ARG_registerFile;
    47484717    Register* r = ARG_r;
     
    47624731
    47634732    if (*ARG_profilerReference)
    4764         (*ARG_profilerReference)->willExecute(exec, constructor);
     4733        (*ARG_profilerReference)->willExecute(CallFrame::create(r), constructor);
    47654734
    47664735    ScopeChainNode* callDataScopeChain = constructor->m_scopeChain.node();
     
    47734742    else
    47744743        structure = callDataScopeChain->globalObject()->emptyObjectStructure();
    4775     JSObject* newObject = new (exec) JSObject(structure);
     4744    JSObject* newObject = new (ARG_globalData) JSObject(structure);
    47764745
    47774746    r[firstArg] = newObject; // "this" value
    47784747
    4779     Register* savedR = r;
    4780 
    4781     JSValue* exceptionValue = 0;
    4782     r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, r, registerOffset, argCount, exceptionValue);
    4783     JSVALUE_VM_CHECK_EXCEPTION_ARG(exceptionValue);
     4748    r = slideRegisterWindowForCall(newCodeBlock, registerFile, r, registerOffset, argCount);
     4749    if (UNLIKELY(!r)) {
     4750        ARG_globalData->exception = createStackOverflowError(CallFrame::create(ARG_r));
     4751        VM_THROW_EXCEPTION();
     4752    }
    47844753
    47854754    r[RegisterFile::CodeBlock] = newCodeBlock;
    47864755    r[RegisterFile::ScopeChain] = callDataScopeChain;
    4787     r[RegisterFile::CallerRegisters] = savedR;
     4756    r[RegisterFile::CallerRegisters] = ARG_r;
    47884757    // RegisterFile::ReturnPC is set by callee
    47894758    // RegisterFile::ReturnValueRegister is set by caller
     
    47934762    r[RegisterFile::OptionalCalleeArguments] = nullJSValue;
    47944763
    4795     exec->m_callFrame = r;
    4796 
    47974764    ARG_setR(r);
    47984765    return newCodeBlock->ctiCode;
     
    48224789
    48234790        JSValue* returnValue = constructData.native.function(exec, constructor, argList);
    4824         VM_CHECK_EXCEPTION(JSValue*);
     4791        VM_CHECK_EXCEPTION();
    48254792
    48264793        if (*ARG_profilerReference)
     
    48334800
    48344801    exec->setException(createNotAConstructorError(exec, constrVal, ARG_instr6, codeBlock(r)));
    4835     VM_CHECK_EXCEPTION_AT_END();
    4836     return 0;
     4802    VM_THROW_EXCEPTION();
    48374803}
    48384804
     
    49094875    unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(CTI_RETURN_ADDRESS);
    49104876    exec->setException(createUndefinedVariableError(exec, ident, codeBlock->instructions.begin() + vPCIndex, codeBlock));
    4911 
    4912     VM_CHECK_EXCEPTION_AT_END();
    4913     return 0;
     4877    VM_THROW_EXCEPTION();
    49144878}
    49154879
     
    49534917    } else {
    49544918        Identifier property(exec, subscript->toString(exec));
    4955         if (!exec->hadException()) { // Don't put to an object if toString threw an exception.
     4919        if (!ARG_globalData->exception) { // Don't put to an object if toString threw an exception.
    49564920            PutPropertySlot slot;
    49574921            baseValue->put(exec, property, value, slot);
     
    49774941        Identifier property(exec, JSImmediate::from(i)->toString(exec));
    49784942        // FIXME: can toString throw an exception here?
    4979         if (!exec->hadException()) { // Don't put to an object if toString threw an exception.
     4943        if (!ARG_globalData->exception) { // Don't put to an object if toString threw an exception.
    49804944            PutPropertySlot slot;
    49814945            baseValue->put(exec, property, value, slot);
     
    50545018    unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(CTI_RETURN_ADDRESS);
    50555019    exec->setException(createUndefinedVariableError(exec, ident, codeBlock->instructions.begin() + vPCIndex, codeBlock));
    5056 
    5057     VM_CHECK_EXCEPTION_AT_END();
    5058     return 0;
     5020    VM_THROW_EXCEPTION();
    50595021}
    50605022
     
    50845046   
    50855047    Register* r = ARG_r;
    5086     exec->setException(createUndefinedVariableError(exec, ident, vPC, codeBlock(r)));
    5087    
    5088     VM_CHECK_EXCEPTION_AT_END();
    5089     return 0;
     5048    exec->setException(createUndefinedVariableError(exec, ident, vPC, codeBlock(r)));   
     5049    VM_THROW_EXCEPTION();
    50905050}
    50915051
     
    51565116
    51575117    JSValue* number = v->toJSNumber(exec);
    5158     VM_CHECK_EXCEPTION(JSValue*);
     5118    VM_CHECK_EXCEPTION();
    51595119    ARG_set2ndResult(jsNumber(ARG_globalData, number->uncheckedGetNumber() + 1));
    51605120    return number;
     
    52715231    unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(CTI_RETURN_ADDRESS);
    52725232    exec->setException(createUndefinedVariableError(exec, ident, codeBlock->instructions.begin() + vPCIndex, codeBlock));
    5273 
    5274     VM_CHECK_EXCEPTION_AT_END();
    5275     return 0;
     5233    VM_THROW_EXCEPTION();
    52765234}
    52775235
     
    53215279
    53225280    JSValue* number = v->toJSNumber(exec);
    5323     VM_CHECK_EXCEPTION(JSValue*);
     5281    VM_CHECK_EXCEPTION();
    53245282
    53255283    ARG_set2ndResult(jsNumber(ARG_globalData, number->uncheckedGetNumber() - 1));
     
    53575315JSValue* Machine::cti_op_new_regexp(CTI_ARGS)
    53585316{
    5359     return new (ARG_exec) RegExpObject(scopeChain(ARG_r)->globalObject()->regExpStructure(), ARG_regexp1);
     5317    return new (ARG_globalData) RegExpObject(scopeChain(ARG_r)->globalObject()->regExpStructure(), ARG_regexp1);
    53605318}
    53615319
     
    53915349        JSValue* exceptionValue = 0;
    53925350        JSValue* result = machine->callEval(exec, thisObject, scopeChain, registerFile,  r, registerOffset - RegisterFile::CallFrameHeaderSize - argCount, argCount, exceptionValue);
    5393         JSVALUE_VM_CHECK_EXCEPTION_ARG(exceptionValue);
     5351        VM_CHECK_EXCEPTION_ARG(exceptionValue);
    53945352        return result;
    53955353    }
     
    54085366
    54095367    JSValue* exceptionValue = ARG_src1;
     5368    ASSERT(exceptionValue);
     5369
    54105370    Instruction* handlerVPC = ARG_globalData->machine->throwException(exec, exceptionValue, codeBlock->instructions.begin() + vPCIndex, r, true);
    54115371
    5412     if (handlerVPC) {
    5413         exec->setException(exceptionValue);
    5414         ARG_setR(r);
    5415 
    5416         void* catchRoutine = Machine::codeBlock(r)->nativeExceptionCodeForHandlerVPC(handlerVPC);
    5417         ASSERT(catchRoutine);
    5418         ctiSetReturnAddress(&CTI_RETURN_ADDRESS, catchRoutine);
    5419         return catchRoutine;
    5420     } else {
    5421         exec->clearException();
     5372    if (!handlerVPC) {
    54225373        *ARG_exception = exceptionValue;
    54235374        return JSImmediate::nullImmediate();
    54245375    }
     5376
     5377    ARG_setR(r);
     5378    void* catchRoutine = Machine::codeBlock(r)->nativeExceptionCodeForHandlerVPC(handlerVPC);
     5379    ASSERT(catchRoutine);
     5380    ctiSetReturnAddress(&CTI_RETURN_ADDRESS, catchRoutine);
     5381    return exceptionValue;
    54255382}
    54265383
     
    54455402
    54465403    JSObject* o = v->toObject(exec);
    5447     VM_CHECK_EXCEPTION_v();
     5404    VM_CHECK_EXCEPTION_VOID();
    54485405
    54495406    Register* r = ARG_r;
     
    55385495        unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(CTI_RETURN_ADDRESS);
    55395496        exec->setException(createInvalidParamError(exec, "in", baseVal, codeBlock->instructions.begin() + vPCIndex, codeBlock));
    5540         VM_CHECK_EXCEPTION(JSValue*);
     5497        VM_THROW_EXCEPTION();
    55415498    }
    55425499
     
    55495506
    55505507    Identifier property(exec, propName->toString(exec));
    5551     VM_CHECK_EXCEPTION(JSValue*);
     5508    VM_CHECK_EXCEPTION();
    55525509    return jsBoolean(baseObj->hasProperty(exec, property));
    55535510}
     
    55555512JSValue* Machine::cti_op_push_new_scope(CTI_ARGS)
    55565513{
    5557     ExecState* exec = ARG_exec;
    5558     JSObject* scope = new (exec) JSStaticScopeObject(exec, *ARG_id1, ARG_src2, DontDelete);
     5514    JSObject* scope = new (ARG_globalData) JSStaticScopeObject(ARG_exec, *ARG_id1, ARG_src2, DontDelete);
    55595515
    55605516    Register* r = ARG_r;
     
    56455601        result = jsBoolean(baseObj->deleteProperty(exec, i));
    56465602    else {
    5647         VM_CHECK_EXCEPTION(JSValue*);
     5603        VM_CHECK_EXCEPTION();
    56485604        Identifier property(exec, subscript->toString(exec));
    5649         VM_CHECK_EXCEPTION(JSValue*);
     5605        VM_CHECK_EXCEPTION();
    56505606        result = jsBoolean(baseObj->deleteProperty(exec, property));
    56515607    }
     
    57075663    CodeBlock* codeBlock = Machine::codeBlock(r);
    57085664
    5709     ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(exec->ctiReturnAddress()));
    5710     unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(exec->ctiReturnAddress());
    5711 
    5712     ASSERT(exec->hadException());
    5713 
    5714     JSValue* exceptionValue = exec->exception();
     5665    ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(ARG_globalData->throwReturnAddress));
     5666    unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(ARG_globalData->throwReturnAddress);
     5667
     5668    JSValue* exceptionValue = ARG_globalData->exception;
     5669    ASSERT(exceptionValue);
     5670    ARG_globalData->exception = 0;
    57155671
    57165672    Instruction* handlerVPC = ARG_globalData->machine->throwException(exec, exceptionValue, codeBlock->instructions.begin() + vPCIndex, r, false);
    57175673
    5718     if (handlerVPC) {
    5719         exec->setException(exceptionValue);
    5720         ARG_setR(r);
    5721 
    5722         void* catchRoutine = Machine::codeBlock(r)->nativeExceptionCodeForHandlerVPC(handlerVPC);
    5723         ASSERT(catchRoutine);
    5724         ctiSetReturnAddress(&CTI_RETURN_ADDRESS, catchRoutine);
    5725         return catchRoutine;
    5726     } else {
    5727         exec->clearException();
     5674    if (!handlerVPC) {
    57285675        *ARG_exception = exceptionValue;
    57295676        return JSImmediate::nullImmediate();
    57305677    }
     5678
     5679    ARG_setR(r);
     5680    void* catchRoutine = Machine::codeBlock(r)->nativeExceptionCodeForHandlerVPC(handlerVPC);
     5681    ASSERT(catchRoutine);
     5682    ctiSetReturnAddress(&CTI_RETURN_ADDRESS, catchRoutine);
     5683    return exceptionValue;
    57315684}
    57325685
    57335686#undef VM_CHECK_EXCEPTION
    5734 #undef VM_CHECK_EXCEPTION_v
     5687#undef VM_CHECK_EXCEPTION_ARG
    57355688#undef VM_CHECK_EXCEPTION_AT_END
     5689#undef VM_CHECK_EXCEPTION_VOID
    57365690
    57375691#endif // ENABLE(CTI)
  • trunk/JavaScriptCore/VM/Machine.h

    r37294 r37297  
    269269        Register* callFrame(ExecState*, InternalFunction*) const;
    270270
    271         JSValue* privateExecute(ExecutionFlag, ExecState* = 0, RegisterFile* = 0, Register* = 0, JSValue** exception = 0);
     271        JSValue* privateExecute(ExecutionFlag, RegisterFile*, Register*, JSValue** exception);
    272272
    273273        void dumpCallFrame(const RegisterFile*, const Register*);
  • trunk/JavaScriptCore/kjs/DebuggerCallFrame.cpp

    r37257 r37297  
    4545    if (!function)
    4646        return 0;
    47     return &function->name(m_exec);
     47    return &function->name(m_scopeChain->globalData);
    4848}
    4949
     
    6969        return 0;
    7070
    71     ExecState newExec(m_registers);
    72 
    7371    int errLine;
    7472    UString errMsg;
    7573    SourceCode source = makeSource(script);
    76     RefPtr<EvalNode> evalNode = newExec.parser()->parse<EvalNode>(&newExec, source, &errLine, &errMsg);
     74    RefPtr<EvalNode> evalNode = m_scopeChain->globalData->parser->parse<EvalNode>(CallFrame::create(m_registers), source, &errLine, &errMsg);
    7775    if (!evalNode)
    78         return Error::create(&newExec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());
     76        return Error::create(CallFrame::create(m_registers), SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());
    7977
    80     return newExec.machine()->execute(evalNode.get(), &newExec, thisObject(), m_scopeChain, &exception);
     78    return m_scopeChain->globalData->machine->execute(evalNode.get(), CallFrame::create(m_registers), thisObject(), m_scopeChain, &exception);
    8179}
    8280
  • trunk/JavaScriptCore/kjs/DebuggerCallFrame.h

    r36821 r37297  
    4949        };
    5050
    51         DebuggerCallFrame(ExecState* exec, JSGlobalObject* dynamicGlobalObject, const CodeBlock* codeBlock, ScopeChainNode* scopeChain, Register* r, JSValue* exception)
    52             : m_exec(exec)
    53             , m_dynamicGlobalObject(dynamicGlobalObject)
     51        DebuggerCallFrame(JSGlobalObject* dynamicGlobalObject, const CodeBlock* codeBlock, ScopeChainNode* scopeChain, Register* r, JSValue* exception)
     52            : m_dynamicGlobalObject(dynamicGlobalObject)
    5453            , m_codeBlock(codeBlock)
    5554            , m_scopeChain(scopeChain)
     
    6261        const ScopeChainNode* scopeChain() const { return m_scopeChain; }
    6362        const UString* functionName() const;
    64         DebuggerCallFrame::Type type() const;
     63        Type type() const;
    6564        JSObject* thisObject() const;
    6665        JSValue* evaluate(const UString&, JSValue*& exception) const;
     
    6867
    6968    private:
    70         ExecState* m_exec;
    7169        JSGlobalObject* m_dynamicGlobalObject;
    7270        const CodeBlock* m_codeBlock;
  • trunk/JavaScriptCore/kjs/ExecState.h

    r37257 r37297  
    3030namespace JSC  {
    3131
     32    class ExecState;
    3233    class JSValue;
    3334    class Register;
    3435
     36    typedef ExecState CallFrame;
     37
    3538    // Represents the current state of script execution.
    3639    // Passed as the first argument to most functions.
    37     class ExecState : Noncopyable {
    38 #if ENABLE(CTI)
    39         friend class CTI;
    40 #endif
    41         friend class Machine;
    42         friend class DebuggerCallFrame;
     40    class ExecState : private Register, Noncopyable {
    4341    public:
    44         explicit ExecState(Register* callFrame)
    45             : m_exception(0)
    46             , m_callFrame(callFrame)
     42        static CallFrame* create(Register* callFrameBase) { return static_cast<CallFrame*>(callFrameBase); }
     43        Register* registers() { return this; }
     44
     45        // Global object in which execution began.
     46        JSGlobalObject* dynamicGlobalObject()
    4747        {
     48            return Machine::scopeChain(Machine::firstCallFrame(this))->globalObject();
    4849        }
    4950
    50         // Global object in which execution began.
    51         JSGlobalObject* dynamicGlobalObject() const
     51        // Global object in which the currently executing code was defined.
     52        // Differs from dynamicGlobalObject() during function calls across web browser frames.
     53        JSGlobalObject* lexicalGlobalObject()
    5254        {
    53             return Machine::scopeChain(Machine::firstCallFrame(m_callFrame))->globalObject();
     55            return Machine::scopeChain(this)->globalObject();
    5456        }
    5557
    56         // Global object in which the current script was defined. (Can differ
    57         // from dynamicGlobalObject() during function calls across frames.)
    58         JSGlobalObject* lexicalGlobalObject() const
     58        // Differs from lexicalGlobalObject because this will have DOM window shell rather than
     59        // the actual DOM window.
     60        JSObject* globalThisValue()
    5961        {
    60             return Machine::scopeChain(m_callFrame)->globalObject();
     62            return Machine::scopeChain(this)->globalThisObject();
    6163        }
    6264
    63         JSObject* globalThisValue() const
     65        JSGlobalData& globalData()
    6466        {
    65             return Machine::scopeChain(m_callFrame)->globalThisObject();
     67            return *Machine::scopeChain(this)->globalData;
    6668        }
    6769
    68         // Exception propogation.
    69         void setException(JSValue* exception) { m_exception = exception; }
    70         void clearException() { m_exception = 0; }
    71         JSValue* exception() const { return m_exception; }
    72         JSValue** exceptionSlot() { return &m_exception; }
    73         bool hadException() const { return !!m_exception; }
    74 #if ENABLE(CTI)
    75         void setCTIReturnAddress(void* ctiRA) { m_ctiReturnAddress = ctiRA; }
    76         void* ctiReturnAddress() const { return m_ctiReturnAddress; }
    77 #endif
     70        // Convenience functions for access to global data.
    7871
    79         JSGlobalData& globalData() const
    80         {
    81             return *Machine::scopeChain(m_callFrame)->globalData;
    82         }
     72        void setException(JSValue* exception) { globalData().exception = exception; }
     73        void clearException() { globalData().exception = 0; }
     74        JSValue* exception() { return globalData().exception; }
     75        JSValue** exceptionSlot() { return &globalData().exception; }
     76        bool hadException() { return !!globalData().exception; }
    8377
    8478        IdentifierTable* identifierTable() { return globalData().identifierTable; }
    85         const CommonIdentifiers& propertyNames() const { return *globalData().propertyNames; }
    86         const ArgList& emptyList() const { return *globalData().emptyList; }
     79        const CommonIdentifiers& propertyNames() { return *globalData().propertyNames; }
     80        const ArgList& emptyList() { return *globalData().emptyList; }
    8781        Lexer* lexer() { return globalData().lexer; }
    8882        Parser* parser() { return globalData().parser; }
    89         Machine* machine() const { return globalData().machine; }
    90         static const HashTable* arrayTable(ExecState* exec) { return exec->globalData().arrayTable; }
    91         static const HashTable* dateTable(ExecState* exec) { return exec->globalData().dateTable; }
    92         static const HashTable* mathTable(ExecState* exec) { return exec->globalData().mathTable; }
    93         static const HashTable* numberTable(ExecState* exec) { return exec->globalData().numberTable; }
    94         static const HashTable* regExpTable(ExecState* exec) { return exec->globalData().regExpTable; }
    95         static const HashTable* regExpConstructorTable(ExecState* exec) { return exec->globalData().regExpConstructorTable; }
    96         static const HashTable* stringTable(ExecState* exec) { return exec->globalData().stringTable; }
     83        Machine* machine() { return globalData().machine; }
     84        Heap* heap() { return &globalData().heap; }
    9785
    98         Heap* heap() const { return &globalData().heap; }
     86        static const HashTable* arrayTable(CallFrame* callFrame) { return callFrame->globalData().arrayTable; }
     87        static const HashTable* dateTable(CallFrame* callFrame) { return callFrame->globalData().dateTable; }
     88        static const HashTable* mathTable(CallFrame* callFrame) { return callFrame->globalData().mathTable; }
     89        static const HashTable* numberTable(CallFrame* callFrame) { return callFrame->globalData().numberTable; }
     90        static const HashTable* regExpTable(CallFrame* callFrame) { return callFrame->globalData().regExpTable; }
     91        static const HashTable* regExpConstructorTable(CallFrame* callFrame) { return callFrame->globalData().regExpConstructorTable; }
     92        static const HashTable* stringTable(CallFrame* callFrame) { return callFrame->globalData().stringTable; }
    9993
    10094    private:
    101         // Default constructor required for gcc 3.
    102         ExecState() { }
    103 
    104         bool isGlobalObject(JSObject*) const;
    105 
    106         JSValue* m_exception;
    107 #if ENABLE(CTI)
    108         void* m_ctiReturnAddress;
    109 #endif
    110         Register* m_callFrame; // The most recent call frame.
     95        ExecState();
     96        ~ExecState();
    11197    };
    11298
  • trunk/JavaScriptCore/kjs/FunctionPrototype.cpp

    r37257 r37297  
    6868    if (thisValue->isObject(&JSFunction::info)) {
    6969        JSFunction* function = static_cast<JSFunction*>(thisValue);
    70         return jsString(exec, "function " + function->name(exec) + "(" + function->m_body->paramString() + ") " + function->m_body->toSourceString());
     70        return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + function->m_body->paramString() + ") " + function->m_body->toSourceString());
    7171    }
    7272
    7373    if (thisValue->isObject(&InternalFunction::info)) {
    7474        InternalFunction* function = static_cast<InternalFunction*>(thisValue);
    75         return jsString(exec, "function " + function->name(exec) + "() {\n    [native code]\n}");
     75        return jsString(exec, "function " + function->name(&exec->globalData()) + "() {\n    [native code]\n}");
    7676    }
    7777
  • trunk/JavaScriptCore/kjs/InternalFunction.cpp

    r37257 r37297  
    5050}
    5151
    52 const UString& InternalFunction::name(ExecState* exec)
     52const UString& InternalFunction::name(JSGlobalData* globalData)
    5353{
    54     JSValue* v = getDirect(exec->propertyNames().name);
     54    JSValue* v = getDirect(globalData->propertyNames->name);
    5555    ASSERT(v->isString());
    5656    return static_cast<JSString*>(v)->value();
  • trunk/JavaScriptCore/kjs/InternalFunction.h

    r37257 r37297  
    3737        static const ClassInfo info;
    3838
    39         const UString& name(ExecState*);
     39        const UString& name(JSGlobalData*);
    4040
    4141        static PassRefPtr<StructureID> createStructureID(JSValue* proto)
  • trunk/JavaScriptCore/kjs/JSGlobalData.cpp

    r37285 r37297  
    6161JSGlobalData::JSGlobalData(bool isShared)
    6262    : machine(new Machine)
     63    , exception(0)
    6364#if ENABLE(JSC_MULTIPLE_THREADS)
    6465    , arrayTable(new HashTable(JSC::arrayTable))
  • trunk/JavaScriptCore/kjs/JSGlobalData.h

    r37285 r37297  
    6565        Machine* machine;
    6666
     67        JSValue* exception;
     68#if ENABLE(CTI)
     69        void* throwReturnAddress;
     70#endif
     71
    6772        const HashTable* arrayTable;
    6873        const HashTable* dateTable;
  • trunk/JavaScriptCore/kjs/JSGlobalObject.cpp

    r37257 r37297  
    143143    d()->debugger = 0;
    144144
    145     d()->globalExec.set(new ExecState(d()->globalCallFrame + RegisterFile::CallFrameHeaderSize));
    146 
    147145    d()->profileGroup = 0;
    148146
     
    199197void JSGlobalObject::reset(JSValue* prototype)
    200198{
    201     ExecState* exec = d()->globalExec.get();
     199    ExecState* exec = JSGlobalObject::globalExec();
    202200
    203201    // Prototypes
     
    365363        registerFile.markGlobals(&globalData()->heap);
    366364
    367     markIfNeeded(d()->globalExec->exception());
    368 
    369365    markIfNeeded(d()->regExpConstructor);
    370366    markIfNeeded(d()->errorConstructor);
     
    411407ExecState* JSGlobalObject::globalExec()
    412408{
    413     return d()->globalExec.get();
     409    return CallFrame::create(d()->globalCallFrame + RegisterFile::CallFrameHeaderSize);
    414410}
    415411
  • trunk/JavaScriptCore/kjs/JSGlobalObject.h

    r37257 r37297  
    9292            ScopeChain globalScopeChain;
    9393            Register globalCallFrame[RegisterFile::CallFrameHeaderSize];
    94             OwnPtr<ExecState> globalExec;
    9594
    9695            int recursion;
  • trunk/JavaScriptCore/kjs/JSObject.cpp

    r36977 r37297  
    482482void JSObject::putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr)
    483483{
    484     putDirect(Identifier(exec, function->name(exec)), function, attr);
     484    putDirect(Identifier(exec, function->name(&exec->globalData())), function, attr);
    485485}
    486486
  • trunk/JavaScriptCore/kjs/collector.cpp

    r37215 r37297  
    982982    if (m_markListSet && m_markListSet->size())
    983983        ArgList::markLists(*m_markListSet);
     984    if (m_globalData->exception && !m_globalData->exception->marked())
     985        m_globalData->exception->mark();
    984986    m_globalData->machine->registerFile().markCallFrames(this);
    985987    m_globalData->smallStrings.mark();
  • trunk/JavaScriptCore/profiler/ProfileGenerator.cpp

    r37184 r37297  
    6363
    6464    exec->machine()->retrieveLastCaller(exec, lineNumber, sourceID, sourceURL, function);
    65     m_currentNode = ProfileNode::create(Profiler::createCallIdentifier(exec, function ? function->toThisObject(exec) : 0, sourceURL, lineNumber), m_head.get(), m_head.get());
     65    m_currentNode = ProfileNode::create(Profiler::createCallIdentifier(&exec->globalData(), function ? function->toThisObject(exec) : 0, sourceURL, lineNumber), m_head.get(), m_head.get());
    6666    m_head->insertNode(m_currentNode.get());
    6767}
  • trunk/JavaScriptCore/profiler/Profiler.cpp

    r36263 r37297  
    4545static unsigned ProfilesUID = 0;
    4646
    47 static CallIdentifier createCallIdentifierFromFunctionImp(ExecState*, JSFunction*);
     47static CallIdentifier createCallIdentifierFromFunctionImp(JSGlobalData*, JSFunction*);
    4848
    4949Profiler* Profiler::s_sharedProfiler = 0;
     
    106106    ASSERT(!m_currentProfiles.isEmpty());
    107107
    108     dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::willExecute, createCallIdentifier(exec, calledFunction, "", 0), exec->lexicalGlobalObject()->profileGroup());
     108    dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::willExecute, createCallIdentifier(&exec->globalData(), calledFunction, "", 0), exec->lexicalGlobalObject()->profileGroup());
    109109}
    110110
     
    113113    ASSERT(!m_currentProfiles.isEmpty());
    114114
    115     CallIdentifier callIdentifier = createCallIdentifier(exec, 0, sourceURL, startingLineNumber);
     115    CallIdentifier callIdentifier = createCallIdentifier(&exec->globalData(), 0, sourceURL, startingLineNumber);
    116116
    117117    dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::willExecute, callIdentifier, exec->lexicalGlobalObject()->profileGroup());
     
    122122    ASSERT(!m_currentProfiles.isEmpty());
    123123
    124     dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(exec, calledFunction, "", 0), exec->lexicalGlobalObject()->profileGroup());
     124    dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(&exec->globalData(), calledFunction, "", 0), exec->lexicalGlobalObject()->profileGroup());
    125125}
    126126
     
    129129    ASSERT(!m_currentProfiles.isEmpty());
    130130
    131     dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(exec, 0, sourceURL, startingLineNumber), exec->lexicalGlobalObject()->profileGroup());
     131    dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(&exec->globalData(), 0, sourceURL, startingLineNumber), exec->lexicalGlobalObject()->profileGroup());
    132132}
    133133
    134 CallIdentifier Profiler::createCallIdentifier(ExecState* exec, JSObject* calledFunction, const UString& defaultSourceURL, int defaultLineNumber)
     134CallIdentifier Profiler::createCallIdentifier(JSGlobalData* globalData, JSObject* calledFunction, const UString& defaultSourceURL, int defaultLineNumber)
    135135{
    136136    if (!calledFunction)
     
    138138
    139139    if (calledFunction->inherits(&JSFunction::info))
    140         return createCallIdentifierFromFunctionImp(exec, static_cast<JSFunction*>(calledFunction));
     140        return createCallIdentifierFromFunctionImp(globalData, static_cast<JSFunction*>(calledFunction));
    141141    if (calledFunction->inherits(&InternalFunction::info))
    142         return CallIdentifier(static_cast<InternalFunction*>(calledFunction)->name(exec), defaultSourceURL, defaultLineNumber);
     142        return CallIdentifier(static_cast<InternalFunction*>(calledFunction)->name(globalData), defaultSourceURL, defaultLineNumber);
    143143
    144144    UString name = "(" + calledFunction->className() + " object)";
     
    146146}
    147147
    148 CallIdentifier createCallIdentifierFromFunctionImp(ExecState* exec, JSFunction* function)
     148CallIdentifier createCallIdentifierFromFunctionImp(JSGlobalData* globalData, JSFunction* function)
    149149{
    150     const UString& name = function->name(exec);
     150    const UString& name = function->name(globalData);
    151151    return CallIdentifier(name.isEmpty() ? AnonymousFunction : name, function->m_body->sourceURL(), function->m_body->lineNo());
    152152}
  • trunk/JavaScriptCore/profiler/Profiler.h

    r36263 r37297  
    3939    class CallIdentifier;
    4040    class ExecState;
     41    class JSGlobalData;
    4142    class JSObject;
    4243    class ProfileGenerator;
     
    5152
    5253        static Profiler* profiler();
    53         static CallIdentifier createCallIdentifier(ExecState*, JSObject*, const UString& sourceURL, int lineNumber);
     54        static CallIdentifier createCallIdentifier(JSGlobalData*, JSObject*, const UString& sourceURL, int lineNumber);
    5455
    5556        void startProfiling(ExecState*, const UString& title);
Note: See TracChangeset for help on using the changeset viewer.