summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/jit/JITStubs.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
commit2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch)
tree988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/JavaScriptCore/jit/JITStubs.cpp
parentdd91e772430dc294e3bf478c119ef8d43c0a3358 (diff)
downloadqtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/JavaScriptCore/jit/JITStubs.cpp')
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.cpp182
1 files changed, 33 insertions, 149 deletions
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp
index eebe90427..d81e68aae 100644
--- a/Source/JavaScriptCore/jit/JITStubs.cpp
+++ b/Source/JavaScriptCore/jit/JITStubs.cpp
@@ -48,7 +48,6 @@
#include "JITExceptions.h"
#include "JSActivation.h"
#include "JSArray.h"
-#include "JSByteArray.h"
#include "JSFunction.h"
#include "JSGlobalObjectFunctions.h"
#include "JSNotAnObject.h"
@@ -1281,7 +1280,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_create_this)
STUB_INIT_STACK_FRAME(stackFrame);
CallFrame* callFrame = stackFrame.callFrame;
- JSFunction* constructor = asFunction(callFrame->callee());
+ JSFunction* constructor = jsCast<JSFunction*>(callFrame->callee());
#if !ASSERT_DISABLED
ConstructData constructData;
ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
@@ -1498,7 +1497,9 @@ DEFINE_STUB_FUNCTION(JSObject*, op_put_by_id_transition_realloc)
ASSERT(baseValue.isObject());
JSObject* base = asObject(baseValue);
- base->allocatePropertyStorage(*stackFrame.globalData, oldSize, newSize);
+ JSGlobalData& globalData = *stackFrame.globalData;
+ PropertyStorage newStorage = base->growPropertyStorage(globalData, oldSize, newSize);
+ base->setPropertyStorage(globalData, newStorage, newStructure);
return base;
}
@@ -1517,6 +1518,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
MethodCallLinkInfo& methodCallLinkInfo = codeBlock->getMethodCallLinkInfo(STUB_RETURN_ADDRESS);
+ StructureStubInfo& stubInfo = codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
if (!methodCallLinkInfo.seenOnce()) {
methodCallLinkInfo.setSeen();
@@ -1555,7 +1557,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
// Check to see if the function is on the object's prototype. Patch up the code to optimize.
if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
- JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS);
+ JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, stubInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS);
return JSValue::encode(result);
}
@@ -1566,7 +1568,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
// for now. For now it performs a check on a special object on the global object only used for this
// purpose. The object is in no way exposed, and as such the check will always pass.
if (slot.slotBase() == baseValue) {
- JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject->methodCallDummy(), STUB_RETURN_ADDRESS);
+ JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, stubInfo, callee, structure, callFrame->scopeChain()->globalObject->methodCallDummy(), STUB_RETURN_ADDRESS);
return JSValue::encode(result);
}
}
@@ -1590,6 +1592,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check_update)
CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
MethodCallLinkInfo& methodCallLinkInfo = codeBlock->getMethodCallLinkInfo(STUB_RETURN_ADDRESS);
+ StructureStubInfo& stubInfo = codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
ASSERT(methodCallLinkInfo.seenOnce());
@@ -1650,7 +1653,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check_update)
// Check to see if the function is on the object's prototype. Patch up the code to optimize.
if (slot.slotBase() == proto) {
- JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS);
+ JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, stubInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS);
return JSValue::encode(result);
}
@@ -1661,7 +1664,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check_update)
// useful. We could try to nop it out altogether, but that's a little messy, so lets do something simpler
// for now. For now it performs a check on a special object on the global object only used for this
// purpose. The object is in no way exposed, and as such the check will always pass.
- JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject->methodCallDummy(), STUB_RETURN_ADDRESS);
+ JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, stubInfo, callee, structure, callFrame->scopeChain()->globalObject->methodCallDummy(), STUB_RETURN_ADDRESS);
return JSValue::encode(result);
}
@@ -2149,7 +2152,7 @@ DEFINE_STUB_FUNCTION(JSObject*, op_new_func)
inline void* jitCompileFor(CallFrame* callFrame, CodeSpecializationKind kind)
{
- JSFunction* function = asFunction(callFrame->callee());
+ JSFunction* function = jsCast<JSFunction*>(callFrame->callee());
ASSERT(!function->isHostFunction());
FunctionExecutable* executable = function->jsExecutable();
ScopeChainNode* callDataScopeChain = function->scope();
@@ -2183,7 +2186,7 @@ DEFINE_STUB_FUNCTION(void*, op_construct_jitCompile)
#if !ASSERT_DISABLED
ConstructData constructData;
- ASSERT(asFunction(stackFrame.callFrame->callee())->methodTable()->getConstructData(stackFrame.callFrame->callee(), constructData) == ConstructTypeJS);
+ ASSERT(jsCast<JSFunction*>(stackFrame.callFrame->callee())->methodTable()->getConstructData(stackFrame.callFrame->callee(), constructData) == ConstructTypeJS);
#endif
CallFrame* callFrame = stackFrame.callFrame;
@@ -2222,7 +2225,7 @@ DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck)
inline void* lazyLinkFor(CallFrame* callFrame, CodeSpecializationKind kind)
{
- JSFunction* callee = asFunction(callFrame->callee());
+ JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
ExecutableBase* executable = callee->executable();
MacroAssemblerCodePtr codePtr;
@@ -2233,9 +2236,10 @@ inline void* lazyLinkFor(CallFrame* callFrame, CodeSpecializationKind kind)
codePtr = executable->generatedJITCodeFor(kind).addressForCall();
else {
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
- JSObject* error = functionExecutable->compileFor(callFrame, callee->scope(), kind);
- if (error)
+ if (JSObject* error = functionExecutable->compileFor(callFrame, callee->scope(), kind)) {
+ callFrame->globalData().exception = error;
return 0;
+ }
codeBlock = &functionExecutable->generatedBytecodeFor(kind);
if (callFrame->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters())
|| callLinkInfo->callType == CallLinkInfo::CallVarargs)
@@ -2444,11 +2448,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val)
CHECK_FOR_EXCEPTION();
return JSValue::encode(result);
}
- if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
- // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
- ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_byte_array));
- return JSValue::encode(asByteArray(baseValue)->getIndex(callFrame, i));
- }
JSValue result = baseValue.get(callFrame, i);
CHECK_FOR_EXCEPTION();
return JSValue::encode(result);
@@ -2489,36 +2488,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_string)
return JSValue::encode(result);
}
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_byte_array)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- JSValue baseValue = stackFrame.args[0].jsValue();
- JSValue subscript = stackFrame.args[1].jsValue();
-
- JSValue result;
-
- if (LIKELY(subscript.isUInt32())) {
- uint32_t i = subscript.asUInt32();
- if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
- // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
- return JSValue::encode(asByteArray(baseValue)->getIndex(callFrame, i));
- }
-
- result = baseValue.get(callFrame, i);
- if (!isJSByteArray(baseValue))
- ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val));
- } else {
- Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
- result = baseValue.get(callFrame, property);
- }
-
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
DEFINE_STUB_FUNCTION(EncodedJSValue, op_sub)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -2554,21 +2523,6 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val)
jsArray->setIndex(*globalData, i, value);
else
JSArray::putByIndex(jsArray, callFrame, i, value, callFrame->codeBlock()->isStrictMode());
- } else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
- JSByteArray* jsByteArray = asByteArray(baseValue);
- ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val_byte_array));
- // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
- if (value.isInt32()) {
- jsByteArray->setIndex(i, value.asInt32());
- return;
- } else {
- if (value.isNumber()) {
- jsByteArray->setIndex(i, value.asNumber());
- return;
- }
- }
-
- baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
} else
baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
} else {
@@ -2582,47 +2536,6 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val)
CHECK_FOR_EXCEPTION_AT_END();
}
-DEFINE_STUB_FUNCTION(void, op_put_by_val_byte_array)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- JSValue baseValue = stackFrame.args[0].jsValue();
- JSValue subscript = stackFrame.args[1].jsValue();
- JSValue value = stackFrame.args[2].jsValue();
-
- if (LIKELY(subscript.isUInt32())) {
- uint32_t i = subscript.asUInt32();
- if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
- JSByteArray* jsByteArray = asByteArray(baseValue);
-
- // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
- if (value.isInt32()) {
- jsByteArray->setIndex(i, value.asInt32());
- return;
- } else {
- if (value.isNumber()) {
- jsByteArray->setIndex(i, value.asNumber());
- return;
- }
- }
- }
-
- if (!isJSByteArray(baseValue))
- ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val));
- baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
- } else {
- Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
- if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception.
- PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
- baseValue.put(callFrame, property, value, slot);
- }
- }
-
- CHECK_FOR_EXCEPTION_AT_END();
-}
-
DEFINE_STUB_FUNCTION(EncodedJSValue, op_less)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -2949,20 +2862,20 @@ DEFINE_STUB_FUNCTION(int, op_eq)
if (cell1->isString()) {
if (src2.isInt32())
- return jsToNumber(static_cast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asInt32();
+ return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asInt32();
if (src2.isDouble())
- return jsToNumber(static_cast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asDouble();
+ return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asDouble();
if (src2.isTrue())
- return jsToNumber(static_cast<JSString*>(cell1)->value(stackFrame.callFrame)) == 1.0;
+ return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == 1.0;
if (src2.isFalse())
- return jsToNumber(static_cast<JSString*>(cell1)->value(stackFrame.callFrame)) == 0.0;
+ return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == 0.0;
JSCell* cell2 = src2.asCell();
if (cell2->isString())
- return static_cast<JSString*>(cell1)->value(stackFrame.callFrame) == static_cast<JSString*>(cell2)->value(stackFrame.callFrame);
+ return jsCast<JSString*>(cell1)->value(stackFrame.callFrame) == jsCast<JSString*>(cell2)->value(stackFrame.callFrame);
src2 = asObject(cell2)->toPrimitive(stackFrame.callFrame);
CHECK_FOR_EXCEPTION();
@@ -3252,35 +3165,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_typeof)
return JSValue::encode(jsTypeStringForValue(stackFrame.callFrame, stackFrame.args[0].jsValue()));
}
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_undefined)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue v = stackFrame.args[0].jsValue();
- return JSValue::encode(jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()));
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_boolean)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- return JSValue::encode(jsBoolean(stackFrame.args[0].jsValue().isBoolean()));
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_number)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- return JSValue::encode(jsBoolean(stackFrame.args[0].jsValue().isNumber()));
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_string)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- return JSValue::encode(jsBoolean(isJSString(stackFrame.args[0].jsValue())));
-}
-
DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_object)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -3558,24 +3442,24 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, to_object)
MacroAssemblerCodeRef JITThunks::ctiStub(JSGlobalData* globalData, ThunkGenerator generator)
{
- std::pair<CTIStubMap::iterator, bool> entry = m_ctiStubMap.add(generator, MacroAssemblerCodeRef());
- if (entry.second)
- entry.first->second = generator(globalData);
- return entry.first->second;
+ CTIStubMap::AddResult entry = m_ctiStubMap.add(generator, MacroAssemblerCodeRef());
+ if (entry.isNewEntry)
+ entry.iterator->second = generator(globalData);
+ return entry.iterator->second;
}
NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function, NativeFunction constructor)
{
- std::pair<HostFunctionStubMap::iterator, bool> result = m_hostFunctionStubMap->add(function, PassWeak<NativeExecutable>());
- if (!result.first->second)
- result.first->second = PassWeak<NativeExecutable>(*globalData, NativeExecutable::create(*globalData, JIT::compileCTINativeCall(globalData, function), function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct()), constructor, NoIntrinsic));
- return result.first->second.get();
+ HostFunctionStubMap::AddResult result = m_hostFunctionStubMap->add(function, PassWeak<NativeExecutable>());
+ if (!result.iterator->second)
+ result.iterator->second = PassWeak<NativeExecutable>(NativeExecutable::create(*globalData, JIT::compileCTINativeCall(globalData, function), function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct()), constructor, NoIntrinsic));
+ return result.iterator->second.get();
}
NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function, ThunkGenerator generator, Intrinsic intrinsic)
{
- std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap->add(function, PassWeak<NativeExecutable>());
- if (!*entry.first->second) {
+ HostFunctionStubMap::AddResult entry = m_hostFunctionStubMap->add(function, PassWeak<NativeExecutable>());
+ if (!entry.iterator->second) {
MacroAssemblerCodeRef code;
if (generator) {
if (globalData->canUseJIT())
@@ -3584,9 +3468,9 @@ NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFu
code = MacroAssemblerCodeRef();
} else
code = JIT::compileCTINativeCall(globalData, function);
- entry.first->second = PassWeak<NativeExecutable>(*globalData, NativeExecutable::create(*globalData, code, function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct()), callHostFunctionAsConstructor, intrinsic));
+ entry.iterator->second = PassWeak<NativeExecutable>(NativeExecutable::create(*globalData, code, function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct()), callHostFunctionAsConstructor, intrinsic));
}
- return entry.first->second.get();
+ return entry.iterator->second.get();
}
void JITThunks::clearHostFunctionStubs()