diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGOperations.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGOperations.cpp | 233 |
1 files changed, 213 insertions, 20 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp index 2e6fd9276..569b4fe86 100644 --- a/Source/JavaScriptCore/dfg/DFGOperations.cpp +++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp @@ -31,6 +31,7 @@ #include "CodeBlock.h" #include "DFGOSRExit.h" #include "DFGRepatch.h" +#include "GetterSetter.h" #include "InlineASM.h" #include "Interpreter.h" #include "JSByteArray.h" @@ -42,6 +43,7 @@ #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, register) \ asm( \ ".globl " SYMBOL_STRING(function) "\n" \ + HIDE_SYMBOL(function) "\n" \ SYMBOL_STRING(function) ":" "\n" \ "mov (%rsp), %" STRINGIZE(register) "\n" \ "jmp " SYMBOL_STRING_RELOCATION(function##WithReturnAddress) "\n" \ @@ -56,6 +58,7 @@ #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, offset) \ asm( \ ".globl " SYMBOL_STRING(function) "\n" \ + HIDE_SYMBOL(function) "\n" \ SYMBOL_STRING(function) ":" "\n" \ "mov (%esp), %eax\n" \ "mov %eax, " STRINGIZE(offset) "(%esp)\n" \ @@ -175,6 +178,9 @@ 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); + JSValue baseValue = JSValue::decode(encodedBase); JSValue property = JSValue::decode(encodedProperty); JSValue value = JSValue::decode(encodedValue); @@ -193,10 +199,9 @@ ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exe } } - JSGlobalData* globalData = &exec->globalData(); // Don't put to an object if toString throws an exception. - Identifier ident(exec, property.toString(exec)); + Identifier ident(exec, property.toString(exec)->value(exec)); if (!globalData->exception) { PutPropertySlot slot(strict); baseValue.put(exec, ident, value, slot); @@ -207,6 +212,9 @@ extern "C" { EncodedJSValue DFG_OPERATION operationConvertThis(ExecState* exec, EncodedJSValue encodedOp) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + return JSValue::encode(JSValue::decode(encodedOp).toThisObject(exec)); } @@ -230,21 +238,33 @@ inline JSCell* createThis(ExecState* exec, JSCell* prototype, JSFunction* constr JSCell* DFG_OPERATION operationCreateThis(ExecState* exec, JSCell* prototype) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + return createThis(exec, prototype, asFunction(exec->callee())); } JSCell* DFG_OPERATION operationCreateThisInlined(ExecState* exec, JSCell* prototype, JSCell* constructor) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + return createThis(exec, prototype, static_cast<JSFunction*>(constructor)); } JSCell* DFG_OPERATION operationNewObject(ExecState* exec) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + return constructEmptyObject(exec); } EncodedJSValue DFG_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + JSValue op1 = JSValue::decode(encodedOp1); JSValue op2 = JSValue::decode(encodedOp2); @@ -253,16 +273,16 @@ 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); + JSValue op1 = JSValue::decode(encodedOp1); JSValue op2 = JSValue::decode(encodedOp2); ASSERT(!op1.isNumber() || !op2.isNumber()); - if (op1.isString()) { - if (op2.isString()) - return JSValue::encode(jsString(exec, asString(op1), asString(op2))); - return JSValue::encode(jsString(exec, asString(op1), op2.toPrimitiveString(exec))); - } + if (op1.isString() && !op2.isObject()) + return JSValue::encode(jsString(exec, asString(op1), op2.toString(exec))); return JSValue::encode(jsAddSlowCase(exec, op1, op2)); } @@ -286,6 +306,9 @@ 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); + JSValue baseValue = JSValue::decode(encodedBase); JSValue property = JSValue::decode(encodedProperty); @@ -305,12 +328,15 @@ EncodedJSValue DFG_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue e } } - Identifier ident(exec, property.toString(exec)); + Identifier ident(exec, property.toString(exec)->value(exec)); return JSValue::encode(baseValue.get(exec, ident)); } EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + JSValue property = JSValue::decode(encodedProperty); if (property.isUInt32()) @@ -325,12 +351,15 @@ EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState* exec, JSCell* base return JSValue::encode(result); } - Identifier ident(exec, property.toString(exec)); + Identifier ident(exec, property.toString(exec)->value(exec)); return JSValue::encode(JSValue(base).get(exec, ident)); } EncodedJSValue DFG_OPERATION operationGetById(ExecState* exec, EncodedJSValue base, Identifier* propertyName) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + JSValue baseValue = JSValue::decode(base); PropertySlot slot(baseValue); return JSValue::encode(baseValue.get(exec, *propertyName, slot)); @@ -339,6 +368,9 @@ 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); + JSValue baseValue = JSValue::decode(base); PropertySlot slot(baseValue); JSValue result = baseValue.get(exec, *propertyName, slot); @@ -352,6 +384,9 @@ 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); + JSValue baseValue = JSValue::decode(base); PropertySlot slot(baseValue); JSValue result = baseValue.get(exec, *propertyName, slot); @@ -365,6 +400,9 @@ 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); + JSValue baseValue = JSValue::decode(base); PropertySlot slot(baseValue); JSValue result = baseValue.get(exec, *propertyName, slot); @@ -378,28 +416,65 @@ EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ExecState return JSValue::encode(result); } +EncodedJSValue DFG_OPERATION operationCallCustomGetter(ExecState* exec, JSCell* base, PropertySlot::GetValueFunc function, Identifier* ident) +{ + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, 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); + + GetterSetter* getterSetter = asGetterSetter(value); + JSObject* getter = getterSetter->getter(); + if (!getter) + return JSValue::encode(jsUndefined()); + CallData callData; + CallType callType = getter->methodTable()->getCallData(getter, callData); + return JSValue::encode(call(exec, getter, callType, callData, asObject(base), ArgList())); +} + void DFG_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, 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); + 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); + 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); + operationPutByValInternal<false>(exec, JSValue::encode(cell), encodedProperty, encodedValue); } void DFG_OPERATION operationPutByValBeyondArrayBounds(ExecState* exec, JSArray* array, int32_t index, EncodedJSValue encodedValue) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + // We should only get here if index is outside the existing vector. ASSERT(!array->canSetIndex(index)); JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue)); @@ -407,42 +482,65 @@ void DFG_OPERATION operationPutByValBeyondArrayBounds(ExecState* exec, JSArray* EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + array->push(exec, JSValue::decode(encodedValue)); return JSValue::encode(jsNumber(array->length())); } EncodedJSValue DFG_OPERATION operationArrayPop(ExecState* exec, JSArray* array) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + return JSValue::encode(array->pop(exec)); } void DFG_OPERATION operationPutByIdStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + PutPropertySlot slot(true); base->methodTable()->put(base, exec, *propertyName, JSValue::decode(encodedValue), slot); } void DFG_OPERATION operationPutByIdNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + PutPropertySlot slot(false); base->methodTable()->put(base, exec, *propertyName, JSValue::decode(encodedValue), slot); } void DFG_OPERATION operationPutByIdDirectStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + PutPropertySlot slot(true); - JSValue(base).putDirect(exec, *propertyName, JSValue::decode(encodedValue), slot); + ASSERT(base->isObject()); + asObject(base)->putDirect(exec->globalData(), *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); + PutPropertySlot slot(false); - JSValue(base).putDirect(exec, *propertyName, JSValue::decode(encodedValue), slot); + ASSERT(base->isObject()); + asObject(base)->putDirect(exec->globalData(), *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); + JSValue value = JSValue::decode(encodedValue); JSValue baseValue(base); PutPropertySlot slot(true); @@ -459,6 +557,9 @@ 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); + JSValue value = JSValue::decode(encodedValue); JSValue baseValue(base); PutPropertySlot slot(false); @@ -475,15 +576,18 @@ 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); + JSValue value = JSValue::decode(encodedValue); - JSValue baseValue(base); PutPropertySlot slot(true); - baseValue.putDirect(exec, *propertyName, value, slot); + ASSERT(base->isObject()); + asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); if (stubInfo.seen) - dfgRepatchPutByID(exec, baseValue, *propertyName, slot, stubInfo, Direct); + dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct); else stubInfo.seen = true; } @@ -491,46 +595,67 @@ 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); + JSValue value = JSValue::decode(encodedValue); - JSValue baseValue(base); PutPropertySlot slot(false); - baseValue.putDirect(exec, *propertyName, value, slot); + ASSERT(base->isObject()); + asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); if (stubInfo.seen) - dfgRepatchPutByID(exec, baseValue, *propertyName, slot, stubInfo, Direct); + dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct); else stubInfo.seen = true; } size_t DFG_OPERATION operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, 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); + 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); + 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); + 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); + return JSValue::equalSlowCaseInline(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); } size_t DFG_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + JSValue op1 = JSValue::decode(encodedOp1); JSValue op2 = JSValue::decode(encodedOp2); @@ -542,6 +667,9 @@ 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); + return JSValue::strictEqual(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); } @@ -551,6 +679,7 @@ EncodedJSValue DFG_OPERATION getHostCallReturnValueWithExecState(ExecState*); #if CPU(X86_64) asm ( ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n" +HIDE_SYMBOL(getHostCallReturnValue) "\n" SYMBOL_STRING(getHostCallReturnValue) ":" "\n" "mov -40(%r13), %r13\n" "mov %r13, %rdi\n" @@ -559,6 +688,7 @@ SYMBOL_STRING(getHostCallReturnValue) ":" "\n" #elif CPU(X86) asm ( ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n" +HIDE_SYMBOL(getHostCallReturnValue) "\n" SYMBOL_STRING(getHostCallReturnValue) ":" "\n" "mov -40(%edi), %edi\n" "mov %edi, 4(%esp)\n" @@ -581,6 +711,9 @@ SYMBOL_STRING(getHostCallReturnValue) ":" "\n" EncodedJSValue DFG_OPERATION getHostCallReturnValueWithExecState(ExecState* exec) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + return JSValue::encode(exec->globalData().hostCallReturnValue); } @@ -635,6 +768,8 @@ inline void* linkFor(ExecState* execCallee, ReturnAddressPtr returnAddress, Code { ExecState* exec = execCallee->callerFrame(); JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + JSValue calleeAsValue = execCallee->calleeAsValue(); JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue); if (!calleeAsFunctionCell) @@ -684,6 +819,9 @@ void* DFG_OPERATION operationLinkConstructWithReturnAddress(ExecState* execCalle inline void* virtualFor(ExecState* execCallee, CodeSpecializationKind kind) { ExecState* exec = execCallee->callerFrame(); + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + JSValue calleeAsValue = execCallee->calleeAsValue(); JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue); if (UNLIKELY(!calleeAsFunctionCell)) @@ -704,7 +842,7 @@ inline void* virtualFor(ExecState* execCallee, CodeSpecializationKind kind) } void* DFG_OPERATION operationVirtualCall(ExecState* execCallee) -{ +{ return virtualFor(execCallee, CodeForCall); } @@ -715,6 +853,9 @@ void* DFG_OPERATION operationVirtualConstruct(ExecState* execCallee) EncodedJSValue DFG_OPERATION operationResolve(ExecState* exec, Identifier* propertyName) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + ScopeChainNode* scopeChain = exec->scopeChain(); ScopeChainIterator iter = scopeChain->begin(); ScopeChainIterator end = scopeChain->end(); @@ -732,11 +873,17 @@ EncodedJSValue DFG_OPERATION operationResolve(ExecState* exec, Identifier* prope EncodedJSValue DFG_OPERATION operationResolveBase(ExecState* exec, Identifier* propertyName) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + return JSValue::encode(resolveBase(exec, *propertyName, exec->scopeChain(), false)); } EncodedJSValue DFG_OPERATION operationResolveBaseStrictPut(ExecState* exec, Identifier* propertyName) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + JSValue base = resolveBase(exec, *propertyName, exec->scopeChain(), true); if (!base) throwError(exec, createErrorForInvalidGlobalAssignment(exec, propertyName->ustring())); @@ -745,6 +892,9 @@ EncodedJSValue DFG_OPERATION operationResolveBaseStrictPut(ExecState* exec, Iden EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState* exec, GlobalResolveInfo* resolveInfo, Identifier* propertyName) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + JSGlobalObject* globalObject = exec->lexicalGlobalObject(); PropertySlot slot(globalObject); @@ -764,16 +914,25 @@ EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState* exec, GlobalResol EncodedJSValue DFG_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + return JSValue::encode(JSValue::decode(value).toPrimitive(exec)); } EncodedJSValue DFG_OPERATION operationStrCat(ExecState* exec, void* start, size_t size) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + return JSValue::encode(jsString(exec, static_cast<Register*>(start), size)); } EncodedJSValue DFG_OPERATION operationNewArray(ExecState* exec, void* start, size_t size) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + return JSValue::encode(constructArray(exec, static_cast<JSValue*>(start), size)); } @@ -795,6 +954,9 @@ EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState* exec, uint32_t callIndex) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + JSValue exceptionValue = exec->exception(); ASSERT(exceptionValue); @@ -806,29 +968,60 @@ DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState* exec, uint32_t return dfgHandlerEncoded(exec, catchRoutine); } +DFGHandlerEncoded DFG_OPERATION lookupExceptionHandlerInStub(ExecState* exec, StructureStubInfo* stubInfo) +{ + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + + JSValue exceptionValue = exec->exception(); + ASSERT(exceptionValue); + + CodeOrigin codeOrigin = stubInfo->codeOrigin; + while (codeOrigin.inlineCallFrame) + codeOrigin = codeOrigin.inlineCallFrame->caller; + + HandlerInfo* handler = exec->globalData().interpreter->throwException(exec, exceptionValue, codeOrigin.bytecodeIndex); + + void* catchRoutine = handler ? handler->nativeCode.executableAddress() : (void*)ctiOpThrowNotCaught; + ASSERT(catchRoutine); + return dfgHandlerEncoded(exec, 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); + // toInt32/toUInt32 return the same value; we want the value zero extended to fill the register. return JSValue::decode(value).toUInt32(exec); } size_t DFG_OPERATION dfgConvertJSValueToBoolean(ExecState* exec, EncodedJSValue encodedOp) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + return JSValue::decode(encodedOp).toBoolean(exec); } #if DFG_ENABLE(VERBOSE_SPECULATION_FAILURE) -void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState*, void* debugInfoRaw) +void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw) { + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw); CodeBlock* codeBlock = debugInfo->codeBlock; CodeBlock* alternative = codeBlock->alternative(); - printf("Speculation failure in %p at @%u with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u, success/fail %u/%u\n", codeBlock, debugInfo->nodeIndex, alternative ? alternative->executeCounter() : 0, alternative ? alternative->reoptimizationRetryCounter() : 0, alternative ? alternative->optimizationDelayCounter() : 0, codeBlock->speculativeSuccessCounter(), codeBlock->speculativeFailCounter()); + printf("Speculation failure in %p at @%u with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u, success/fail %u/%u\n", codeBlock, debugInfo->nodeIndex, alternative ? alternative->jitExecuteCounter() : 0, alternative ? alternative->reoptimizationRetryCounter() : 0, alternative ? alternative->optimizationDelayCounter() : 0, codeBlock->speculativeSuccessCounter(), codeBlock->speculativeFailCounter()); } #endif |