summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/llint
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-09-14 16:29:47 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-09-14 16:29:47 +0200
commitd0424a769059c84ae20beb3c217812792ea6726b (patch)
tree6f94a5c3db8c52c6694ee56498542a6c35417350 /Source/JavaScriptCore/llint
parent88a04ac016f57c2d78e714682445dff2e7db4ade (diff)
downloadqtwebkit-d0424a769059c84ae20beb3c217812792ea6726b.tar.gz
Imported WebKit commit 37c5e5041d39a14ea0d429a77ebd352e4bd26516 (http://svn.webkit.org/repository/webkit/trunk@128608)
New snapshot that enables WebKit2 build on Windows (still some bugs) and allows for WebKit to be built with qmake && make
Diffstat (limited to 'Source/JavaScriptCore/llint')
-rw-r--r--Source/JavaScriptCore/llint/LLIntSlowPaths.cpp31
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter.asm12
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter.h33
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm65
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter64.asm61
5 files changed, 119 insertions, 83 deletions
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
index fa50fedb6..b0441e80b 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
@@ -858,7 +858,7 @@ LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
JSValue result = baseValue.get(exec, ident, slot);
LLINT_CHECK_EXCEPTION();
LLINT_OP(1) = result;
-
+
if (!LLINT_ALWAYS_ACCESS_SLOW
&& baseValue.isCell()
&& slot.isCacheable()
@@ -877,11 +877,22 @@ LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
} else {
pc[0].u.opcode = LLInt::getOpcode(llint_op_get_by_id_out_of_line);
- pc[5].u.operand = offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue);
+ pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
}
}
}
+ if (!LLINT_ALWAYS_ACCESS_SLOW
+ && isJSArray(baseValue)
+ && ident == exec->propertyNames().length) {
+ pc[0].u.opcode = LLInt::getOpcode(llint_op_get_array_length);
+#if ENABLE(VALUE_PROFILER)
+ ArrayProfile* arrayProfile = codeBlock->getOrAddArrayProfile(pc - codeBlock->instructions().begin());
+ arrayProfile->observeStructure(baseValue.asCell()->structure());
+ pc[4].u.arrayProfile = arrayProfile;
+#endif
+ }
+
#if ENABLE(VALUE_PROFILER)
pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
#endif
@@ -939,7 +950,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
if (isInlineOffset(slot.cachedOffset()))
pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
else
- pc[5].u.operand = offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue);
+ pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
pc[6].u.structure.set(
globalData, codeBlock->ownerExecutable(), structure);
StructureChain* chain = structure->prototypeChain(exec);
@@ -967,7 +978,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
} else {
pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_out_of_line);
- pc[5].u.operand = offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue);
+ pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
}
}
}
@@ -1046,12 +1057,12 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
if (LIKELY(subscript.isUInt32())) {
uint32_t i = subscript.asUInt32();
- if (isJSArray(baseValue)) {
- JSArray* jsArray = asArray(baseValue);
- if (jsArray->canSetIndex(i))
- jsArray->setIndex(globalData, i, value);
+ if (baseValue.isObject()) {
+ JSObject* object = asObject(baseValue);
+ if (object->canSetIndexQuickly(i))
+ object->setIndexQuickly(globalData, i, value);
else
- JSArray::putByIndex(jsArray, exec, i, value, exec->codeBlock()->isStrictMode());
+ object->methodTable()->putByIndex(object, exec, i, value, exec->codeBlock()->isStrictMode());
LLINT_END();
}
baseValue.putByIndex(exec, i, value, exec->codeBlock()->isStrictMode());
@@ -1128,7 +1139,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter)
if (!setter.isUndefined())
accessor->setSetter(globalData, asObject(setter));
baseObj->putDirectAccessor(
- globalData,
+ exec,
exec->codeBlock()->identifier(pc[2].u.operand),
accessor, Accessor);
LLINT_END();
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
index 4c590a1c3..6f5460aa7 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
@@ -61,6 +61,11 @@ else
const PayloadOffset = 0
end
+# Constant for reasoning about butterflies.
+const IsArray = 1
+const HasArrayStorage = 8
+const AllArrayTypes = 15
+
# Type constants.
const StringType = 5
const ObjectType = 13
@@ -339,7 +344,7 @@ macro allocateBasicJSObject(sizeClassIndex, structure, result, scratch1, scratch
# Initialize the object.
storep structure, JSCell::m_structure[result]
- storep 0, JSObject::m_outOfLineStorage[result]
+ storep 0, JSObject::m_butterfly[result]
end
end
@@ -514,7 +519,7 @@ macro withInlineStorage(object, propertyStorage, continuation)
end
macro withOutOfLineStorage(object, propertyStorage, continuation)
- loadp JSObject::m_outOfLineStorage[object], propertyStorage
+ loadp JSObject::m_butterfly[object], propertyStorage
# Indicate that the propertyStorage register now points to the
# property storage, and that the object register may be reused
# if the object pointer is not needed anymore.
@@ -845,9 +850,6 @@ macro notSupported()
end
end
-_llint_op_get_array_length:
- notSupported()
-
_llint_op_get_by_id_chain:
notSupported()
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.h b/Source/JavaScriptCore/llint/LowLevelInterpreter.h
index 76c950a8c..f45a07303 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.h
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.h
@@ -36,39 +36,16 @@
namespace JSC {
-// The following is a minimal set of alias for the opcode names. This is needed
+// The following is a set of alias for the opcode names. This is needed
// because there is code (e.g. in GetByIdStatus.cpp and PutByIdStatus.cpp)
// which refers to the opcodes expecting them to be prefixed with "llint_".
// In the CLoop implementation, the 2 are equivalent. Hence, we set up this
// alias here.
-//
-// Note: we don't just do this for all opcodes because we only need a few,
-// and currently, FOR_EACH_OPCODE_ID() includes the llint and JIT opcode
-// extensions which we definitely don't want to add an alias for. With some
-// minor refactoring, we can use FOR_EACH_OPCODE_ID() to automatically
-// generate a llint_ alias for all opcodes, but that is not needed at this
-// time.
-const OpcodeID llint_op_call = op_call;
-const OpcodeID llint_op_call_eval = op_call_eval;
-const OpcodeID llint_op_call_varargs = op_call_varargs;
-const OpcodeID llint_op_construct = op_construct;
-const OpcodeID llint_op_catch = op_catch;
-const OpcodeID llint_op_get_by_id = op_get_by_id;
-const OpcodeID llint_op_get_by_id_out_of_line = op_get_by_id_out_of_line;
-const OpcodeID llint_op_put_by_id = op_put_by_id;
-const OpcodeID llint_op_put_by_id_out_of_line = op_put_by_id_out_of_line;
-
-const OpcodeID llint_op_put_by_id_transition_direct =
- op_put_by_id_transition_direct;
-const OpcodeID llint_op_put_by_id_transition_direct_out_of_line =
- op_put_by_id_transition_direct_out_of_line;
-const OpcodeID llint_op_put_by_id_transition_normal =
- op_put_by_id_transition_normal;
-const OpcodeID llint_op_put_by_id_transition_normal_out_of_line =
- op_put_by_id_transition_normal_out_of_line;
-
-const OpcodeID llint_op_method_check = op_method_check;
+#define LLINT_OPCODE_ALIAS(opcode, length) \
+ const OpcodeID llint_##opcode = opcode;
+FOR_EACH_CORE_OPCODE_ID(LLINT_OPCODE_ALIAS)
+#undef LLINT_OPCODE_ALIAS
} // namespace JSC
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
index 103a3f978..0e37a4099 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
@@ -947,21 +947,21 @@ _llint_op_is_string:
macro loadPropertyAtVariableOffsetKnownNotFinal(propertyOffset, objectAndStorage, tag, payload)
assert(macro (ok) bigteq propertyOffset, InlineStorageCapacity, ok end)
negi propertyOffset
- loadp JSObject::m_outOfLineStorage[objectAndStorage], objectAndStorage
- loadi TagOffset + (InlineStorageCapacity - 2) * 8[objectAndStorage, propertyOffset, 8], tag
- loadi PayloadOffset + (InlineStorageCapacity - 2) * 8[objectAndStorage, propertyOffset, 8], payload
+ loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
+ loadi TagOffset + (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffset, 8], tag
+ loadi PayloadOffset + (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffset, 8], payload
end
macro loadPropertyAtVariableOffset(propertyOffset, objectAndStorage, tag, payload)
bilt propertyOffset, InlineStorageCapacity, .isInline
- loadp JSObject::m_outOfLineStorage[objectAndStorage], objectAndStorage
+ loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
negi propertyOffset
jmp .ready
.isInline:
- addp JSFinalObject::m_inlineStorage - (InlineStorageCapacity - 2) * 8, objectAndStorage
+ addp JSFinalObject::m_inlineStorage - (InlineStorageCapacity - 1) * 8 + sizeof IndexingHeader, objectAndStorage
.ready:
- loadi TagOffset + (InlineStorageCapacity - 2) * 8[objectAndStorage, propertyOffset, 8], tag
- loadi PayloadOffset + (InlineStorageCapacity - 2) * 8[objectAndStorage, propertyOffset, 8], payload
+ loadi TagOffset + (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffset, 8], tag
+ loadi PayloadOffset + (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffset, 8], payload
end
macro resolveGlobal(size, slow)
@@ -1101,6 +1101,7 @@ _llint_op_get_global_var_watchable:
getGlobalVar(5)
+_llint_op_init_global_const:
_llint_op_put_global_var:
traceExecution()
loadi 8[PC], t1
@@ -1112,6 +1113,7 @@ _llint_op_put_global_var:
dispatch(3)
+_llint_op_init_global_const_check:
_llint_op_put_global_var_check:
traceExecution()
loadp 12[PC], t2
@@ -1168,6 +1170,33 @@ _llint_op_get_by_id_out_of_line:
getById(withOutOfLineStorage)
+_llint_op_get_array_length:
+ traceExecution()
+ loadi 8[PC], t0
+ loadp 16[PC], t1
+ loadConstantOrVariablePayload(t0, CellTag, t3, .opGetArrayLengthSlow)
+ loadp JSCell::m_structure[t3], t2
+ if VALUE_PROFILER
+ storep t2, ArrayProfile::m_lastSeenStructure[t1]
+ end
+ loadb Structure::m_indexingType[t2], t1
+ btiz t1, IsArray, .opGetArrayLengthSlow
+ btiz t1, HasArrayStorage, .opGetArrayLengthSlow
+ loadi 4[PC], t1
+ loadp 32[PC], t2
+ loadp JSObject::m_butterfly[t3], t0
+ loadi -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], t0
+ bilt t0, 0, .opGetArrayLengthSlow
+ valueProfile(Int32Tag, t0, t2)
+ storep t0, PayloadOffset[cfr, t1, 8]
+ storep Int32Tag, TagOffset[cfr, t1, 8]
+ dispatch(9)
+
+.opGetArrayLengthSlow:
+ callSlowPath(_llint_slow_path_get_by_id)
+ dispatch(9)
+
+
_llint_op_get_arguments_length:
traceExecution()
loadi 8[PC], t0
@@ -1287,12 +1316,9 @@ _llint_op_get_by_val:
if VALUE_PROFILER
storep t3, ArrayProfile::m_lastSeenStructure[t2]
end
- loadp CodeBlock[cfr], t2
- loadp CodeBlock::m_globalData[t2], t2
- loadp JSGlobalData::jsArrayClassInfo[t2], t2
- bpneq Structure::m_classInfo[t3], t2, .opGetByValSlow
- loadp JSArray::m_storage[t0], t3
- biaeq t1, JSArray::m_vectorLength[t0], .opGetByValSlow
+ btpz Structure::m_indexingType[t3], HasArrayStorage, .opGetByValSlow
+ loadp JSObject::m_butterfly[t0], t3
+ biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opGetByValSlow
loadi 4[PC], t0
loadi ArrayStorage::m_vector + TagOffset[t3, t1, 8], t2
loadi ArrayStorage::m_vector + PayloadOffset[t3, t1, 8], t1
@@ -1373,12 +1399,9 @@ _llint_op_put_by_val:
if VALUE_PROFILER
storep t3, ArrayProfile::m_lastSeenStructure[t0]
end
- loadp CodeBlock[cfr], t0
- loadp CodeBlock::m_globalData[t0], t0
- loadp JSGlobalData::jsArrayClassInfo[t0], t0
- bpneq Structure::m_classInfo[t3], t0, .opPutByValSlow
- biaeq t2, JSArray::m_vectorLength[t1], .opPutByValSlow
- loadp JSArray::m_storage[t1], t0
+ btpz Structure::m_indexingType[t3], HasArrayStorage, .opPutByValSlow
+ loadp JSObject::m_butterfly[t1], t0
+ biaeq t2, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow
bieq ArrayStorage::m_vector + TagOffset[t0, t2, 8], EmptyValueTag, .opPutByValEmpty
.opPutByValStoreResult:
loadi 12[PC], t3
@@ -1390,9 +1413,9 @@ _llint_op_put_by_val:
.opPutByValEmpty:
addi 1, ArrayStorage::m_numValuesInVector[t0]
- bib t2, ArrayStorage::m_length[t0], .opPutByValStoreResult
+ bib t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValStoreResult
addi 1, t2, t1
- storei t1, ArrayStorage::m_length[t0]
+ storei t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0]
jmp .opPutByValStoreResult
.opPutByValSlow:
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
index 4bb7b8e1c..7dfcb6728 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
@@ -806,20 +806,20 @@ _llint_op_is_string:
macro loadPropertyAtVariableOffsetKnownNotFinal(propertyOffsetAsPointer, objectAndStorage, value)
assert(macro (ok) bigteq propertyOffsetAsPointer, InlineStorageCapacity, ok end)
negp propertyOffsetAsPointer
- loadp JSObject::m_outOfLineStorage[objectAndStorage], objectAndStorage
- loadp (InlineStorageCapacity - 2) * 8[objectAndStorage, propertyOffsetAsPointer, 8], value
+ loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
+ loadp (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffsetAsPointer, 8], value
end
macro loadPropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value)
bilt propertyOffsetAsInt, InlineStorageCapacity, .isInline
- loadp JSObject::m_outOfLineStorage[objectAndStorage], objectAndStorage
+ loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
negi propertyOffsetAsInt
sxi2p propertyOffsetAsInt, propertyOffsetAsInt
jmp .ready
.isInline:
- addp JSFinalObject::m_inlineStorage - (InlineStorageCapacity - 2) * 8, objectAndStorage
+ addp JSFinalObject::m_inlineStorage - (InlineStorageCapacity - 1) * 8 + sizeof IndexingHeader, objectAndStorage
.ready:
- loadp (InlineStorageCapacity - 2) * 8[objectAndStorage, propertyOffsetAsInt, 8], value
+ loadp (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffsetAsInt, 8], value
end
macro resolveGlobal(size, slow)
@@ -953,6 +953,7 @@ _llint_op_get_global_var_watchable:
getGlobalVar(5)
+_llint_op_init_global_const:
_llint_op_put_global_var:
traceExecution()
loadis 16[PB, PC, 8], t1
@@ -963,6 +964,7 @@ _llint_op_put_global_var:
dispatch(3)
+_llint_op_init_global_const_check:
_llint_op_put_global_var_check:
traceExecution()
loadp 24[PB, PC, 8], t2
@@ -1015,6 +1017,33 @@ _llint_op_get_by_id_out_of_line:
getById(withOutOfLineStorage)
+_llint_op_get_array_length:
+ traceExecution()
+ loadis 16[PB, PC, 8], t0
+ loadp 32[PB, PC, 8], t1
+ loadConstantOrVariableCell(t0, t3, .opGetArrayLengthSlow)
+ loadp JSCell::m_structure[t3], t2
+ if VALUE_PROFILER
+ storep t2, ArrayProfile::m_lastSeenStructure[t1]
+ end
+ loadb Structure::m_indexingType[t2], t1
+ btiz t1, IsArray, .opGetArrayLengthSlow
+ btiz t1, HasArrayStorage, .opGetArrayLengthSlow
+ loadis 8[PB, PC, 8], t1
+ loadp 64[PB, PC, 8], t2
+ loadp JSObject::m_butterfly[t3], t0
+ loadi -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], t0
+ bilt t0, 0, .opGetArrayLengthSlow
+ orp tagTypeNumber, t0
+ valueProfile(t0, t2)
+ storep t0, [cfr, t1, 8]
+ dispatch(9)
+
+.opGetArrayLengthSlow:
+ callSlowPath(_llint_slow_path_get_by_id)
+ dispatch(9)
+
+
_llint_op_get_arguments_length:
traceExecution()
loadis 16[PB, PC, 8], t0
@@ -1132,12 +1161,9 @@ _llint_op_get_by_val:
if VALUE_PROFILER
storep t3, ArrayProfile::m_lastSeenStructure[t2]
end
- loadp CodeBlock[cfr], t2
- loadp CodeBlock::m_globalData[t2], t2
- loadp JSGlobalData::jsArrayClassInfo[t2], t2
- bpneq Structure::m_classInfo[t3], t2, .opGetByValSlow
- loadp JSArray::m_storage[t0], t3
- biaeq t1, JSArray::m_vectorLength[t0], .opGetByValSlow
+ btbz Structure::m_indexingType[t3], HasArrayStorage, .opGetByValSlow
+ loadp JSObject::m_butterfly[t0], t3
+ biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValSlow
loadis 8[PB, PC, 8], t0
loadp ArrayStorage::m_vector[t3, t1, 8], t2
btpz t2, .opGetByValSlow
@@ -1217,12 +1243,9 @@ _llint_op_put_by_val:
if VALUE_PROFILER
storep t3, ArrayProfile::m_lastSeenStructure[t0]
end
- loadp CodeBlock[cfr], t0
- loadp CodeBlock::m_globalData[t0], t0
- loadp JSGlobalData::jsArrayClassInfo[t0], t0
- bpneq Structure::m_classInfo[t3], t0, .opPutByValSlow
- biaeq t2, JSArray::m_vectorLength[t1], .opPutByValSlow
- loadp JSArray::m_storage[t1], t0
+ btbz Structure::m_indexingType[t3], HasArrayStorage, .opPutByValSlow
+ loadp JSObject::m_butterfly[t1], t0
+ biaeq t2, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow
btpz ArrayStorage::m_vector[t0, t2, 8], .opPutByValEmpty
.opPutByValStoreResult:
loadis 24[PB, PC, 8], t3
@@ -1233,9 +1256,9 @@ _llint_op_put_by_val:
.opPutByValEmpty:
addi 1, ArrayStorage::m_numValuesInVector[t0]
- bib t2, ArrayStorage::m_length[t0], .opPutByValStoreResult
+ bib t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValStoreResult
addi 1, t2, t1
- storei t1, ArrayStorage::m_length[t0]
+ storei t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0]
jmp .opPutByValStoreResult
.opPutByValSlow: