diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGOperations.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGOperations.cpp | 670 |
1 files changed, 422 insertions, 248 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp index bb9ccc37d..29a0b2b61 100644 --- a/Source/JavaScriptCore/dfg/DFGOperations.cpp +++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp @@ -39,10 +39,12 @@ #include "JIT.h" #include "JITExceptions.h" #include "JSActivation.h" -#include "JSGlobalData.h" +#include "VM.h" #include "JSNameScope.h" #include "NameInstance.h" +#include "ObjectConstructor.h" #include "Operations.h" +#include "StringConstructor.h" #include <wtf/InlineASM.h> #if ENABLE(JIT) @@ -259,6 +261,53 @@ "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \ ); +#elif COMPILER(GCC) && CPU(SH4) + +#define SH4_SCRATCH_REGISTER "r11" + +#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \ + asm( \ + ".text" "\n" \ + ".globl " SYMBOL_STRING(function) "\n" \ + HIDE_SYMBOL(function) "\n" \ + SYMBOL_STRING(function) ":" "\n" \ + "sts pr, r5" "\n" \ + "bra " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \ + "nop" "\n" \ + ); + +#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \ + asm( \ + ".text" "\n" \ + ".globl " SYMBOL_STRING(function) "\n" \ + HIDE_SYMBOL(function) "\n" \ + SYMBOL_STRING(function) ":" "\n" \ + "sts pr, r7" "\n" \ + "mov.l 2f, " SH4_SCRATCH_REGISTER "\n" \ + "braf " SH4_SCRATCH_REGISTER "\n" \ + "nop" "\n" \ + "1: .balign 4" "\n" \ + "2: .long " LOCAL_REFERENCE(function) "WithReturnAddress-1b" "\n" \ + ); + +#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, offset, scratch) \ + asm( \ + ".text" "\n" \ + ".globl " SYMBOL_STRING(function) "\n" \ + HIDE_SYMBOL(function) "\n" \ + SYMBOL_STRING(function) ":" "\n" \ + "sts pr, " scratch "\n" \ + "mov.l " scratch ", @(" STRINGIZE(offset) ", r15)" "\n" \ + "mov.l 2f, " scratch "\n" \ + "braf " scratch "\n" \ + "nop" "\n" \ + "1: .balign 4" "\n" \ + "2: .long " LOCAL_REFERENCE(function) "WithReturnAddress-1b" "\n" \ + ); + +#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 0, SH4_SCRATCH_REGISTER) +#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 4, SH4_SCRATCH_REGISTER) + #endif #define P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \ @@ -282,13 +331,13 @@ namespace JSC { namespace DFG { template<bool strict> static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); if (baseValue.isObject()) { JSObject* object = asObject(baseValue); if (object->canSetIndexQuickly(index)) { - object->setIndexQuickly(globalData, index, value); + object->setIndexQuickly(vm, index, value); return; } @@ -302,8 +351,8 @@ static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, template<bool strict> ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); JSValue baseValue = JSValue::decode(encodedBase); JSValue property = JSValue::decode(encodedProperty); @@ -331,7 +380,7 @@ ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exe // Don't put to an object if toString throws an exception. Identifier ident(exec, property.toString(exec)->value(exec)); - if (!globalData->exception) { + if (!vm->exception) { PutPropertySlot slot(strict); baseValue.put(exec, ident, value, slot); } @@ -341,37 +390,37 @@ extern "C" { EncodedJSValue DFG_OPERATION operationConvertThis(ExecState* exec, EncodedJSValue encodedOp) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); return JSValue::encode(JSValue::decode(encodedOp).toThisObject(exec)); } -JSCell* DFG_OPERATION operationCreateThis(ExecState* exec, JSCell* constructor) +JSCell* DFG_OPERATION operationCreateThis(ExecState* exec, JSObject* constructor, int32_t inlineCapacity) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); #if !ASSERT_DISABLED ConstructData constructData; ASSERT(jsCast<JSFunction*>(constructor)->methodTable()->getConstructData(jsCast<JSFunction*>(constructor), constructData) == ConstructTypeJS); #endif - return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->cachedInheritorID(exec)); + return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->allocationProfile(exec, inlineCapacity)->structure()); } JSCell* DFG_OPERATION operationNewObject(ExecState* exec, Structure* structure) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); return constructEmptyObject(exec, structure); } EncodedJSValue DFG_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); JSValue op1 = JSValue::decode(encodedOp1); JSValue op2 = JSValue::decode(encodedOp2); @@ -381,8 +430,8 @@ EncodedJSValue DFG_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue e EncodedJSValue DFG_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); JSValue op1 = JSValue::decode(encodedOp1); JSValue op2 = JSValue::decode(encodedOp2); @@ -397,8 +446,8 @@ EncodedJSValue DFG_OPERATION operationValueAddNotNumber(ExecState* exec, Encoded static inline EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); if (base->isObject()) { JSObject* object = asObject(base); @@ -414,8 +463,8 @@ static inline EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t in EncodedJSValue DFG_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); JSValue baseValue = JSValue::decode(encodedBase); JSValue property = JSValue::decode(encodedProperty); @@ -445,8 +494,8 @@ EncodedJSValue DFG_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue e EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); JSValue property = JSValue::decode(encodedProperty); @@ -471,8 +520,8 @@ EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState* exec, JSCell* base EncodedJSValue DFG_OPERATION operationGetByValArrayInt(ExecState* exec, JSArray* base, int32_t index) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); if (index < 0) { // Go the slowest way possible becase negative indices don't use indexed storage. @@ -485,8 +534,8 @@ EncodedJSValue DFG_OPERATION operationGetByValArrayInt(ExecState* exec, JSArray* EncodedJSValue DFG_OPERATION operationGetById(ExecState* exec, EncodedJSValue base, Identifier* propertyName) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); JSValue baseValue = JSValue::decode(base); PropertySlot slot(baseValue); @@ -496,8 +545,8 @@ EncodedJSValue DFG_OPERATION operationGetById(ExecState* exec, EncodedJSValue ba J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdBuildList); EncodedJSValue DFG_OPERATION operationGetByIdBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); AccessType accessType = static_cast<AccessType>(stubInfo.accessType); @@ -515,8 +564,8 @@ EncodedJSValue DFG_OPERATION operationGetByIdBuildListWithReturnAddress(ExecStat J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdProtoBuildList); EncodedJSValue DFG_OPERATION operationGetByIdProtoBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); AccessType accessType = static_cast<AccessType>(stubInfo.accessType); @@ -534,8 +583,8 @@ EncodedJSValue DFG_OPERATION operationGetByIdProtoBuildListWithReturnAddress(Exe J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdOptimize); EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); AccessType accessType = static_cast<AccessType>(stubInfo.accessType); @@ -556,16 +605,16 @@ EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ExecState EncodedJSValue DFG_OPERATION operationCallCustomGetter(ExecState* exec, JSCell* base, PropertySlot::GetValueFunc function, Identifier* ident) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); return JSValue::encode(function(exec, asObject(base), *ident)); } EncodedJSValue DFG_OPERATION operationCallGetter(ExecState* exec, JSCell* base, JSCell* value) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); GetterSetter* getterSetter = asGetterSetter(value); JSObject* getter = getterSetter->getter(); @@ -578,40 +627,40 @@ EncodedJSValue DFG_OPERATION operationCallGetter(ExecState* exec, JSCell* base, void DFG_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); operationPutByValInternal<true>(exec, encodedBase, encodedProperty, encodedValue); } void DFG_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); operationPutByValInternal<false>(exec, encodedBase, encodedProperty, encodedValue); } void DFG_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); operationPutByValInternal<true>(exec, JSValue::encode(cell), encodedProperty, encodedValue); } void DFG_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); operationPutByValInternal<false>(exec, JSValue::encode(cell), encodedProperty, encodedValue); } void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); if (index >= 0) { array->putByIndexInline(exec, index, JSValue::decode(encodedValue), true); @@ -625,8 +674,8 @@ void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSO void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); if (index >= 0) { array->putByIndexInline(exec, index, JSValue::decode(encodedValue), false); @@ -640,8 +689,8 @@ void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, double value) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value); @@ -657,8 +706,8 @@ void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exe void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, double value) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value); @@ -674,8 +723,8 @@ void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState* EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); array->push(exec, JSValue::decode(encodedValue)); return JSValue::encode(jsNumber(array->length())); @@ -683,8 +732,8 @@ EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue EncodedJSValue DFG_OPERATION operationArrayPushDouble(ExecState* exec, double value, JSArray* array) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); array->push(exec, JSValue(JSValue::EncodeAsDouble, value)); return JSValue::encode(jsNumber(array->length())); @@ -692,16 +741,16 @@ EncodedJSValue DFG_OPERATION operationArrayPushDouble(ExecState* exec, double va EncodedJSValue DFG_OPERATION operationArrayPop(ExecState* exec, JSArray* array) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); return JSValue::encode(array->pop(exec)); } EncodedJSValue DFG_OPERATION operationArrayPopAndRecoverLength(ExecState* exec, JSArray* array) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); array->butterfly()->setPublicLength(array->butterfly()->publicLength() + 1); @@ -710,8 +759,8 @@ EncodedJSValue DFG_OPERATION operationArrayPopAndRecoverLength(ExecState* exec, EncodedJSValue DFG_OPERATION operationRegExpExec(ExecState* exec, JSCell* base, JSCell* argument) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); if (!base->inherits(&RegExpObject::s_info)) return throwVMTypeError(exec); @@ -723,8 +772,8 @@ EncodedJSValue DFG_OPERATION operationRegExpExec(ExecState* exec, JSCell* base, size_t DFG_OPERATION operationRegExpTest(ExecState* exec, JSCell* base, JSCell* argument) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); if (!base->inherits(&RegExpObject::s_info)) { throwTypeError(exec); @@ -738,8 +787,8 @@ size_t DFG_OPERATION operationRegExpTest(ExecState* exec, JSCell* base, JSCell* void DFG_OPERATION operationPutByIdStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); PutPropertySlot slot(true); base->methodTable()->put(base, exec, *propertyName, JSValue::decode(encodedValue), slot); @@ -747,8 +796,8 @@ void DFG_OPERATION operationPutByIdStrict(ExecState* exec, EncodedJSValue encode void DFG_OPERATION operationPutByIdNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); PutPropertySlot slot(false); base->methodTable()->put(base, exec, *propertyName, JSValue::decode(encodedValue), slot); @@ -756,29 +805,29 @@ void DFG_OPERATION operationPutByIdNonStrict(ExecState* exec, EncodedJSValue enc void DFG_OPERATION operationPutByIdDirectStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); PutPropertySlot slot(true); ASSERT(base->isObject()); - asObject(base)->putDirect(exec->globalData(), *propertyName, JSValue::decode(encodedValue), slot); + asObject(base)->putDirect(exec->vm(), *propertyName, JSValue::decode(encodedValue), slot); } void DFG_OPERATION operationPutByIdDirectNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); PutPropertySlot slot(false); ASSERT(base->isObject()); - asObject(base)->putDirect(exec->globalData(), *propertyName, JSValue::decode(encodedValue), slot); + asObject(base)->putDirect(exec->vm(), *propertyName, JSValue::decode(encodedValue), slot); } V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictOptimize); void DFG_OPERATION operationPutByIdStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); AccessType accessType = static_cast<AccessType>(stubInfo.accessType); @@ -801,8 +850,8 @@ void DFG_OPERATION operationPutByIdStrictOptimizeWithReturnAddress(ExecState* ex V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictOptimize); void DFG_OPERATION operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); AccessType accessType = static_cast<AccessType>(stubInfo.accessType); @@ -825,8 +874,8 @@ void DFG_OPERATION operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState* V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictOptimize); void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); AccessType accessType = static_cast<AccessType>(stubInfo.accessType); @@ -835,7 +884,7 @@ void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecSta PutPropertySlot slot(true); ASSERT(base->isObject()); - asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot); + asObject(base)->putDirect(exec->vm(), *propertyName, value, slot); if (accessType != static_cast<AccessType>(stubInfo.accessType)) return; @@ -849,8 +898,8 @@ void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecSta V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictOptimize); void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); AccessType accessType = static_cast<AccessType>(stubInfo.accessType); @@ -859,7 +908,7 @@ void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(Exec PutPropertySlot slot(false); ASSERT(base->isObject()); - asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot); + asObject(base)->putDirect(exec->vm(), *propertyName, value, slot); if (accessType != static_cast<AccessType>(stubInfo.accessType)) return; @@ -873,8 +922,8 @@ void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(Exec V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictBuildList); void DFG_OPERATION operationPutByIdStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); AccessType accessType = static_cast<AccessType>(stubInfo.accessType); @@ -894,8 +943,8 @@ void DFG_OPERATION operationPutByIdStrictBuildListWithReturnAddress(ExecState* e V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictBuildList); void DFG_OPERATION operationPutByIdNonStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); AccessType accessType = static_cast<AccessType>(stubInfo.accessType); @@ -915,8 +964,8 @@ void DFG_OPERATION operationPutByIdNonStrictBuildListWithReturnAddress(ExecState V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictBuildList); void DFG_OPERATION operationPutByIdDirectStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); AccessType accessType = static_cast<AccessType>(stubInfo.accessType); @@ -925,7 +974,7 @@ void DFG_OPERATION operationPutByIdDirectStrictBuildListWithReturnAddress(ExecSt PutPropertySlot slot(true); ASSERT(base->isObject()); - asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot); + asObject(base)->putDirect(exec->vm(), *propertyName, value, slot); if (accessType != static_cast<AccessType>(stubInfo.accessType)) return; @@ -936,8 +985,8 @@ void DFG_OPERATION operationPutByIdDirectStrictBuildListWithReturnAddress(ExecSt V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictBuildList); void DFG_OPERATION operationPutByIdDirectNonStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); AccessType accessType = static_cast<AccessType>(stubInfo.accessType); @@ -946,7 +995,7 @@ void DFG_OPERATION operationPutByIdDirectNonStrictBuildListWithReturnAddress(Exe PutPropertySlot slot(false); ASSERT(base->isObject()); - asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot); + asObject(base)->putDirect(exec->vm(), *propertyName, value, slot); if (accessType != static_cast<AccessType>(stubInfo.accessType)) return; @@ -956,48 +1005,65 @@ void DFG_OPERATION operationPutByIdDirectNonStrictBuildListWithReturnAddress(Exe size_t DFG_OPERATION operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); return jsLess<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); } size_t DFG_OPERATION operationCompareLessEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); return jsLessEq<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); } size_t DFG_OPERATION operationCompareGreater(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); return jsLess<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1)); } size_t DFG_OPERATION operationCompareGreaterEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); return jsLessEq<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1)); } size_t DFG_OPERATION operationCompareEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); return JSValue::equalSlowCaseInline(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); } +#if USE(JSVALUE64) +EncodedJSValue DFG_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSCell* right) +#else +size_t DFG_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSCell* right) +#endif +{ + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); + + bool result = asString(left)->value(exec) == asString(right)->value(exec); +#if USE(JSVALUE64) + return JSValue::encode(jsBoolean(result)); +#else + return result; +#endif +} + size_t DFG_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); JSValue op1 = JSValue::decode(encodedOp1); JSValue op2 = JSValue::decode(encodedOp2); @@ -1010,8 +1076,8 @@ size_t DFG_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValu size_t DFG_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); JSValue src1 = JSValue::decode(encodedOp1); JSValue src2 = JSValue::decode(encodedOp2); @@ -1022,7 +1088,7 @@ size_t DFG_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue en static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind) { ExecState* exec = execCallee->callerFrame(); - JSGlobalData* globalData = &exec->globalData(); + VM* vm = &exec->vm(); execCallee->setScope(exec->scope()); execCallee->setCodeBlock(0); @@ -1034,18 +1100,18 @@ static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializ ASSERT(callType != CallTypeJS); if (callType == CallTypeHost) { - NativeCallFrameTracer tracer(globalData, execCallee); + NativeCallFrameTracer tracer(vm, execCallee); execCallee->setCallee(asObject(callee)); - globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee)); - if (globalData->exception) - return globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress(); + vm->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee)); + if (vm->exception) + return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress(); return reinterpret_cast<void*>(getHostCallReturnValue); } ASSERT(callType == CallTypeNone); - exec->globalData().exception = createNotAFunctionError(exec, callee); - return globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress(); + exec->vm().exception = createNotAFunctionError(exec, callee); + return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress(); } ASSERT(kind == CodeForConstruct); @@ -1056,25 +1122,25 @@ static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializ ASSERT(constructType != ConstructTypeJS); if (constructType == ConstructTypeHost) { - NativeCallFrameTracer tracer(globalData, execCallee); + NativeCallFrameTracer tracer(vm, execCallee); execCallee->setCallee(asObject(callee)); - globalData->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee)); - if (globalData->exception) - return globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress(); + vm->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee)); + if (vm->exception) + return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress(); return reinterpret_cast<void*>(getHostCallReturnValue); } ASSERT(constructType == ConstructTypeNone); - exec->globalData().exception = createNotAConstructorError(exec, callee); - return globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress(); + exec->vm().exception = createNotAConstructorError(exec, callee); + return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress(); } inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind) { ExecState* exec = execCallee->callerFrame(); - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); JSValue calleeAsValue = execCallee->calleeAsValue(); JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue); @@ -1093,8 +1159,8 @@ inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind) FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind); if (error) { - globalData->exception = createStackOverflowError(exec); - return reinterpret_cast<char*>(globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress()); + vm->exception = createStackOverflowError(exec); + return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress()); } codeBlock = &functionExecutable->generatedBytecodeFor(kind); if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters())) @@ -1123,8 +1189,8 @@ char* DFG_OPERATION operationLinkConstruct(ExecState* execCallee) inline char* virtualForWithFunction(ExecState* execCallee, CodeSpecializationKind kind, JSCell*& calleeAsFunctionCell) { ExecState* exec = execCallee->callerFrame(); - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); JSValue calleeAsValue = execCallee->calleeAsValue(); calleeAsFunctionCell = getJSFunction(calleeAsValue); @@ -1138,8 +1204,8 @@ inline char* virtualForWithFunction(ExecState* execCallee, CodeSpecializationKin FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind); if (error) { - exec->globalData().exception = error; - return reinterpret_cast<char*>(globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress()); + exec->vm().exception = error; + return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress()); } } return reinterpret_cast<char*>(executable->generatedJITCodeWithArityCheckFor(kind).executableAddress()); @@ -1212,31 +1278,31 @@ void DFG_OPERATION operationNotifyGlobalVarWrite(WatchpointSet* watchpointSet) EncodedJSValue DFG_OPERATION operationResolve(ExecState* exec, Identifier* propertyName, ResolveOperations* operations) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); return JSValue::encode(JSScope::resolve(exec, *propertyName, operations)); } EncodedJSValue DFG_OPERATION operationResolveBase(ExecState* exec, Identifier* propertyName, ResolveOperations* operations, PutToBaseOperation* putToBaseOperations) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); return JSValue::encode(JSScope::resolveBase(exec, *propertyName, false, operations, putToBaseOperations)); } EncodedJSValue DFG_OPERATION operationResolveBaseStrictPut(ExecState* exec, Identifier* propertyName, ResolveOperations* operations, PutToBaseOperation* putToBaseOperations) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); return JSValue::encode(JSScope::resolveBase(exec, *propertyName, true, operations, putToBaseOperations)); } EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState* exec, ResolveOperation* resolveOperation, JSGlobalObject* globalObject, Identifier* propertyName) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); ASSERT(globalObject); UNUSED_PARAM(resolveOperation); UNUSED_PARAM(globalObject); @@ -1246,93 +1312,88 @@ EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState* exec, ResolveOper EncodedJSValue DFG_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); return JSValue::encode(JSValue::decode(value).toPrimitive(exec)); } -EncodedJSValue DFG_OPERATION operationStrCat(ExecState* exec, void* buffer, size_t size) -{ - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); - - return JSValue::encode(jsString(exec, static_cast<Register*>(buffer), size)); -} - char* DFG_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); return bitwise_cast<char*>(constructArray(exec, arrayStructure, static_cast<JSValue*>(buffer), size)); } char* DFG_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); - return bitwise_cast<char*>(JSArray::create(*globalData, arrayStructure)); + return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure)); } char* DFG_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); - - return bitwise_cast<char*>(JSArray::create(*globalData, arrayStructure, size)); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); + + if (UNLIKELY(size < 0)) + return bitwise_cast<char*>(throwError(exec, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer.")))); + + return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure, size)); } char* DFG_OPERATION operationNewArrayBuffer(ExecState* exec, Structure* arrayStructure, size_t start, size_t size) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); return bitwise_cast<char*>(constructArray(exec, arrayStructure, exec->codeBlock()->constantBuffer(start), size)); } EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); RegExp* regexp = static_cast<RegExp*>(regexpPtr); if (!regexp->isValid()) { throwError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor.")); return JSValue::encode(jsUndefined()); } - return JSValue::encode(RegExpObject::create(exec->globalData(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regexp)); + return JSValue::encode(RegExpObject::create(exec->vm(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regexp)); } JSCell* DFG_OPERATION operationCreateActivation(ExecState* exec) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); - JSActivation* activation = JSActivation::create(globalData, exec, exec->codeBlock()); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); + JSActivation* activation = JSActivation::create(vm, exec, exec->codeBlock()); exec->setScope(activation); return activation; } JSCell* DFG_OPERATION operationCreateArguments(ExecState* exec) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); // NB: This needs to be exceedingly careful with top call frame tracking, since it // may be called from OSR exit, while the state of the call stack is bizarre. - Arguments* result = Arguments::create(globalData, exec); - ASSERT(!globalData.exception); + Arguments* result = Arguments::create(vm, exec); + ASSERT(!vm.exception); return result; } JSCell* DFG_OPERATION operationCreateInlinedArguments( ExecState* exec, InlineCallFrame* inlineCallFrame) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); // NB: This needs to be exceedingly careful with top call frame tracking, since it // may be called from OSR exit, while the state of the call stack is bizarre. - Arguments* result = Arguments::create(globalData, exec, inlineCallFrame); - ASSERT(!globalData.exception); + Arguments* result = Arguments::create(vm, exec, inlineCallFrame); + ASSERT(!vm.exception); return result; } @@ -1355,11 +1416,11 @@ void DFG_OPERATION operationTearOffInlinedArguments( EncodedJSValue DFG_OPERATION operationGetArgumentsLength(ExecState* exec, int32_t argumentsRegister) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); // Here we can assume that the argumernts were created. Because otherwise the JIT code would // have not made this call. - Identifier ident(&globalData, "length"); + Identifier ident(&vm, "length"); JSValue baseValue = exec->uncheckedR(argumentsRegister).jsValue(); PropertySlot slot(baseValue); return JSValue::encode(baseValue.get(exec, ident, slot)); @@ -1367,15 +1428,15 @@ EncodedJSValue DFG_OPERATION operationGetArgumentsLength(ExecState* exec, int32_ EncodedJSValue DFG_OPERATION operationGetArgumentByVal(ExecState* exec, int32_t argumentsRegister, int32_t index) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue(); // If there are no arguments, and we're accessing out of bounds, then we have to create the // arguments in case someone has installed a getter on a numeric property. if (!argumentsValue) - exec->uncheckedR(argumentsRegister) = argumentsValue = Arguments::create(exec->globalData(), exec); + exec->uncheckedR(argumentsRegister) = argumentsValue = Arguments::create(exec->vm(), exec); return JSValue::encode(argumentsValue.get(exec, index)); } @@ -1383,8 +1444,8 @@ EncodedJSValue DFG_OPERATION operationGetArgumentByVal(ExecState* exec, int32_t EncodedJSValue DFG_OPERATION operationGetInlinedArgumentByVal( ExecState* exec, int32_t argumentsRegister, InlineCallFrame* inlineCallFrame, int32_t index) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue(); @@ -1392,26 +1453,34 @@ EncodedJSValue DFG_OPERATION operationGetInlinedArgumentByVal( // arguments in case someone has installed a getter on a numeric property. if (!argumentsValue) { exec->uncheckedR(argumentsRegister) = argumentsValue = - Arguments::create(exec->globalData(), exec, inlineCallFrame); + Arguments::create(exec->vm(), exec, inlineCallFrame); } return JSValue::encode(argumentsValue.get(exec, index)); } -JSCell* DFG_OPERATION operationNewFunction(ExecState* exec, JSCell* functionExecutable) +JSCell* DFG_OPERATION operationNewFunctionNoCheck(ExecState* exec, JSCell* functionExecutable) { ASSERT(functionExecutable->inherits(&FunctionExecutable::s_info)); - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); return JSFunction::create(exec, static_cast<FunctionExecutable*>(functionExecutable), exec->scope()); } +EncodedJSValue DFG_OPERATION operationNewFunction(ExecState* exec, JSCell* functionExecutable) +{ + ASSERT(functionExecutable->inherits(&FunctionExecutable::s_info)); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); + return JSValue::encode(JSFunction::create(exec, static_cast<FunctionExecutable*>(functionExecutable), exec->scope())); +} + JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState* exec, JSCell* functionExecutableAsCell) { ASSERT(functionExecutableAsCell->inherits(&FunctionExecutable::s_info)); - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(functionExecutableAsCell); @@ -1428,86 +1497,162 @@ size_t DFG_OPERATION operationIsFunction(EncodedJSValue value) return jsIsFunctionType(JSValue::decode(value)); } +JSCell* DFG_OPERATION operationTypeOf(ExecState* exec, JSCell* value) +{ + return jsTypeStringForValue(exec, JSValue(value)).asCell(); +} + void DFG_OPERATION operationReallocateStorageAndFinishPut(ExecState* exec, JSObject* base, Structure* structure, PropertyOffset offset, EncodedJSValue value) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); ASSERT(structure->outOfLineCapacity() > base->structure()->outOfLineCapacity()); - ASSERT(!globalData.heap.storageAllocator().fastPathShouldSucceed(structure->outOfLineCapacity() * sizeof(JSValue))); - base->setStructureAndReallocateStorageIfNecessary(globalData, structure); - base->putDirectOffset(globalData, offset, JSValue::decode(value)); + ASSERT(!vm.heap.storageAllocator().fastPathShouldSucceed(structure->outOfLineCapacity() * sizeof(JSValue))); + base->setStructureAndReallocateStorageIfNecessary(vm, structure); + base->putDirect(vm, offset, JSValue::decode(value)); } char* DFG_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState* exec) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); return reinterpret_cast<char*>( - Butterfly::createUninitialized(globalData, 0, initialOutOfLineCapacity, false, 0)); + Butterfly::createUninitialized(vm, 0, initialOutOfLineCapacity, false, 0)); } char* DFG_OPERATION operationAllocatePropertyStorage(ExecState* exec, size_t newSize) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); return reinterpret_cast<char*>( - Butterfly::createUninitialized(globalData, 0, newSize, false, 0)); + Butterfly::createUninitialized(vm, 0, newSize, false, 0)); } char* DFG_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); ASSERT(!object->structure()->outOfLineCapacity()); - Butterfly* result = object->growOutOfLineStorage(globalData, 0, initialOutOfLineCapacity); + Butterfly* result = object->growOutOfLineStorage(vm, 0, initialOutOfLineCapacity); object->setButterflyWithoutChangingStructure(result); return reinterpret_cast<char*>(result); } char* DFG_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState* exec, JSObject* object, size_t newSize) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); - Butterfly* result = object->growOutOfLineStorage(globalData, object->structure()->outOfLineCapacity(), newSize); + Butterfly* result = object->growOutOfLineStorage(vm, object->structure()->outOfLineCapacity(), newSize); object->setButterflyWithoutChangingStructure(result); return reinterpret_cast<char*>(result); } -char* DFG_OPERATION operationEnsureInt32(ExecState* exec, JSObject* object) +char* DFG_OPERATION operationEnsureInt32(ExecState* exec, JSCell* cell) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); - return reinterpret_cast<char*>(object->ensureInt32(globalData)); + if (!cell->isObject()) + return 0; + + return reinterpret_cast<char*>(asObject(cell)->ensureInt32(vm).data()); +} + +char* DFG_OPERATION operationEnsureDouble(ExecState* exec, JSCell* cell) +{ + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); + + if (!cell->isObject()) + return 0; + + return reinterpret_cast<char*>(asObject(cell)->ensureDouble(vm).data()); +} + +char* DFG_OPERATION operationEnsureContiguous(ExecState* exec, JSCell* cell) +{ + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); + + if (!cell->isObject()) + return 0; + + return reinterpret_cast<char*>(asObject(cell)->ensureContiguous(vm).data()); +} + +char* DFG_OPERATION operationRageEnsureContiguous(ExecState* exec, JSCell* cell) +{ + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); + + if (!cell->isObject()) + return 0; + + return reinterpret_cast<char*>(asObject(cell)->rageEnsureContiguous(vm).data()); +} + +char* DFG_OPERATION operationEnsureArrayStorage(ExecState* exec, JSCell* cell) +{ + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); + + if (!cell->isObject()) + return 0; + + return reinterpret_cast<char*>(asObject(cell)->ensureArrayStorage(vm)); +} + +StringImpl* DFG_OPERATION operationResolveRope(ExecState* exec, JSString* string) +{ + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); + + return string->value(exec).impl(); } -char* DFG_OPERATION operationEnsureDouble(ExecState* exec, JSObject* object) +JSCell* DFG_OPERATION operationNewStringObject(ExecState* exec, JSString* string, Structure* structure) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); - return reinterpret_cast<char*>(object->ensureDouble(globalData)); + return StringObject::create(exec, structure, string); } -char* DFG_OPERATION operationEnsureContiguous(ExecState* exec, JSObject* object) +JSCell* DFG_OPERATION operationToStringOnCell(ExecState* exec, JSCell* cell) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); - return reinterpret_cast<char*>(object->ensureContiguous(globalData)); + return JSValue(cell).toString(exec); } -char* DFG_OPERATION operationEnsureArrayStorage(ExecState* exec, JSObject* object) +JSCell* DFG_OPERATION operationToString(ExecState* exec, EncodedJSValue value) { - JSGlobalData& globalData = exec->globalData(); - NativeCallFrameTracer tracer(&globalData, exec); + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); - return reinterpret_cast<char*>(object->ensureArrayStorage(globalData)); + return JSValue::decode(value).toString(exec); +} + +JSCell* DFG_OPERATION operationMakeRope2(ExecState* exec, JSString* left, JSString* right) +{ + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); + + return JSRopeString::create(vm, left, right); +} + +JSCell* DFG_OPERATION operationMakeRope3(ExecState* exec, JSString* a, JSString* b, JSString* c) +{ + VM& vm = exec->vm(); + NativeCallFrameTracer tracer(&vm, exec); + + return JSRopeString::create(vm, a, b, c); } double DFG_OPERATION operationFModOnInts(int32_t a, int32_t b) @@ -1515,24 +1660,31 @@ double DFG_OPERATION operationFModOnInts(int32_t a, int32_t b) return fmod(a, b); } +JSCell* DFG_OPERATION operationStringFromCharCode(ExecState* exec, int32_t op1) +{ + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); + return JSC::stringFromCharCode(exec, op1); +} + DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState* exec, uint32_t callIndex) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); JSValue exceptionValue = exec->exception(); ASSERT(exceptionValue); unsigned vPCIndex = exec->codeBlock()->bytecodeOffsetForCallAtIndex(callIndex); - ExceptionHandler handler = genericThrow(globalData, exec, exceptionValue, vPCIndex); + ExceptionHandler handler = genericThrow(vm, exec, exceptionValue, vPCIndex); ASSERT(handler.catchRoutine); return dfgHandlerEncoded(handler.callFrame, handler.catchRoutine); } DFGHandlerEncoded DFG_OPERATION lookupExceptionHandlerInStub(ExecState* exec, StructureStubInfo* stubInfo) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); JSValue exceptionValue = exec->exception(); ASSERT(exceptionValue); @@ -1541,23 +1693,15 @@ DFGHandlerEncoded DFG_OPERATION lookupExceptionHandlerInStub(ExecState* exec, St while (codeOrigin.inlineCallFrame) codeOrigin = codeOrigin.inlineCallFrame->caller; - ExceptionHandler handler = genericThrow(globalData, exec, exceptionValue, codeOrigin.bytecodeIndex); + ExceptionHandler handler = genericThrow(vm, exec, exceptionValue, codeOrigin.bytecodeIndex); ASSERT(handler.catchRoutine); return dfgHandlerEncoded(handler.callFrame, handler.catchRoutine); } -double DFG_OPERATION dfgConvertJSValueToNumber(ExecState* exec, EncodedJSValue value) -{ - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); - - return JSValue::decode(value).toNumber(exec); -} - size_t DFG_OPERATION dfgConvertJSValueToInt32(ExecState* exec, EncodedJSValue value) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); // toInt32/toUInt32 return the same value; we want the value zero extended to fill the register. return JSValue::decode(value).toUInt32(exec); @@ -1565,24 +1709,22 @@ size_t DFG_OPERATION dfgConvertJSValueToInt32(ExecState* exec, EncodedJSValue va size_t DFG_OPERATION dfgConvertJSValueToBoolean(ExecState* exec, EncodedJSValue encodedOp) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); return JSValue::decode(encodedOp).toBoolean(exec); } -#if DFG_ENABLE(VERBOSE_SPECULATION_FAILURE) -void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw) +void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw, void* scratch) { - JSGlobalData* globalData = &exec->globalData(); - NativeCallFrameTracer tracer(globalData, exec); + VM* vm = &exec->vm(); + NativeCallFrameTracer tracer(vm, exec); SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw); CodeBlock* codeBlock = debugInfo->codeBlock; CodeBlock* alternative = codeBlock->alternative(); dataLog( - "Speculation failure in ", *codeBlock, " at @", debugInfo->nodeIndex, - " with "); + "Speculation failure in ", *codeBlock, " with "); if (alternative) { dataLog( "executeCounter = ", alternative->jitExecuteCounter(), @@ -1591,8 +1733,25 @@ void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* } else dataLog("no alternative code block (i.e. we've been jettisoned)"); dataLog(", osrExitCounter = ", codeBlock->osrExitCounter(), "\n"); + dataLog(" GPRs at time of exit:"); + char* scratchPointer = static_cast<char*>(scratch); + for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) { + GPRReg gpr = GPRInfo::toRegister(i); + dataLog(" ", GPRInfo::debugName(gpr), ":", RawPointer(*reinterpret_cast_ptr<void**>(scratchPointer))); + scratchPointer += sizeof(EncodedJSValue); + } + dataLog("\n"); + dataLog(" FPRs at time of exit:"); + for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) { + FPRReg fpr = FPRInfo::toRegister(i); + dataLog(" ", FPRInfo::debugName(fpr), ":"); + uint64_t bits = *reinterpret_cast_ptr<uint64_t*>(scratchPointer); + double value = *reinterpret_cast_ptr<double*>(scratchPointer); + dataLogF("%llx:%lf", static_cast<long long>(bits), value); + scratchPointer += sizeof(EncodedJSValue); + } + dataLog("\n"); } -#endif extern "C" void DFG_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock) { @@ -1676,13 +1835,28 @@ SYMBOL_STRING(getHostCallReturnValue) ":" "\n" "move $a0, $s0" "\n" "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n" ); +#elif COMPILER(GCC) && CPU(SH4) +asm( +".text" "\n" +".globl " SYMBOL_STRING(getHostCallReturnValue) "\n" +HIDE_SYMBOL(getHostCallReturnValue) "\n" +SYMBOL_STRING(getHostCallReturnValue) ":" "\n" + "add #-40, r14" "\n" + "mov.l @r14, r14" "\n" + "mov r14, r4" "\n" + "mov.l 2f, " SH4_SCRATCH_REGISTER "\n" + "braf " SH4_SCRATCH_REGISTER "\n" + "nop" "\n" + "1: .balign 4" "\n" + "2: .long " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "-1b\n" +); #endif extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState* exec) { if (!exec) return JSValue::encode(JSValue()); - return JSValue::encode(exec->globalData().hostCallReturnValue); + return JSValue::encode(exec->vm().hostCallReturnValue); } } // namespace JSC |