summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/llint
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-07-11 13:45:28 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-07-11 13:45:28 +0200
commitd6a599dbc9d824a462b2b206316e102bf8136446 (patch)
treeecb257a5e55b2239d74b90fdad62fccd661cf286 /Source/JavaScriptCore/llint
parent3ccc3a85f09a83557b391aae380d3bf5f81a2911 (diff)
downloadqtwebkit-d6a599dbc9d824a462b2b206316e102bf8136446.tar.gz
Imported WebKit commit 8ff1f22783a32de82fee915abd55bd1b298f2644 (http://svn.webkit.org/repository/webkit/trunk@122325)
New snapshot that should work with the latest Qt build system changes
Diffstat (limited to 'Source/JavaScriptCore/llint')
-rw-r--r--Source/JavaScriptCore/llint/LLIntSlowPaths.cpp39
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter.asm25
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm182
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter64.asm157
4 files changed, 278 insertions, 125 deletions
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
index a7698be37..fbc0146b8 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
@@ -895,7 +895,13 @@ LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
&& !structure->typeInfo().prohibitsPropertyCaching()) {
pc[4].u.structure.set(
globalData, codeBlock->ownerExecutable(), structure);
- pc[5].u.operand = slot.cachedOffset() * sizeof(JSValue);
+ if (isInlineOffset(slot.cachedOffset())) {
+ pc[0].u.opcode = bitwise_cast<void*>(&llint_op_get_by_id);
+ pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
+ } else {
+ pc[0].u.opcode = bitwise_cast<void*>(&llint_op_get_by_id_out_of_line);
+ pc[5].u.operand = offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue);
+ }
}
}
@@ -940,7 +946,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
&& baseCell == slot.base()) {
if (slot.type() == PutPropertySlot::NewProperty) {
- if (!structure->isDictionary() && structure->previousID()->propertyStorageCapacity() == structure->propertyStorageCapacity()) {
+ if (!structure->isDictionary() && structure->previousID()->outOfLineCapacity() == structure->outOfLineCapacity()) {
ASSERT(structure->previousID()->transitionWatchpointSetHasBeenInvalidated());
// This is needed because some of the methods we call
@@ -952,7 +958,10 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
ASSERT(structure->previousID()->isObject());
pc[4].u.structure.set(
globalData, codeBlock->ownerExecutable(), structure->previousID());
- pc[5].u.operand = slot.cachedOffset() * sizeof(JSValue);
+ 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[6].u.structure.set(
globalData, codeBlock->ownerExecutable(), structure);
StructureChain* chain = structure->prototypeChain(exec);
@@ -960,16 +969,28 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
pc[7].u.structureChain.set(
globalData, codeBlock->ownerExecutable(), chain);
- if (pc[8].u.operand)
- pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id_transition_direct);
- else
- pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id_transition_normal);
+ if (pc[8].u.operand) {
+ if (isInlineOffset(slot.cachedOffset()))
+ pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id_transition_direct);
+ else
+ pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id_transition_direct_out_of_line);
+ } else {
+ if (isInlineOffset(slot.cachedOffset()))
+ pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id_transition_normal);
+ else
+ pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id_transition_normal_out_of_line);
+ }
}
} else {
- pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id);
pc[4].u.structure.set(
globalData, codeBlock->ownerExecutable(), structure);
- pc[5].u.operand = slot.cachedOffset() * sizeof(JSValue);
+ if (isInlineOffset(slot.cachedOffset())) {
+ pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id);
+ pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
+ } else {
+ pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id_out_of_line);
+ pc[5].u.operand = offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue);
+ }
}
}
}
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
index e59ddeba4..492535bb2 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
@@ -84,6 +84,13 @@ const LLIntReturnPC = ArgumentCount + TagOffset
# String flags.
const HashFlags8BitBuffer = 64
+# Property storage constants
+if JSVALUE64
+ const InlineStorageCapacity = 4
+else
+ const InlineStorageCapacity = 6
+end
+
# Allocation constants
if JSVALUE64
const JSFinalObjectSizeClassIndex = 1
@@ -312,8 +319,7 @@ macro allocateBasicJSObject(sizeClassIndex, classInfoOffset, structure, result,
storep scratch2, [result]
storep structure, JSCell::m_structure[result]
storep 0, JSObject::m_inheritorID[result]
- addp sizeof JSObject, result, scratch1
- storep scratch1, JSObject::m_propertyStorage[result]
+ storep 0, JSObject::m_outOfLineStorage[result]
end
end
@@ -481,6 +487,21 @@ _llint_op_resolve_with_this:
dispatch(5)
+macro withInlineStorage(object, propertyStorage, continuation)
+ # Indicate that the object is the property storage, and that the
+ # property storage register is unused.
+ continuation(object, propertyStorage)
+end
+
+macro withOutOfLineStorage(object, propertyStorage, continuation)
+ loadp JSObject::m_outOfLineStorage[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.
+ continuation(propertyStorage, object)
+end
+
+
_llint_op_del_by_id:
traceExecution()
callSlowPath(_llint_slow_path_del_by_id)
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
index d27fd8229..9d6304de7 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
@@ -919,6 +919,24 @@ _llint_op_is_string:
dispatch(3)
+macro loadPropertyAtVariableOffsetKnownNotFinal(propertyOffset, objectAndStorage, tag, payload)
+ assert(macro (ok) bigteq propertyOffset, InlineStorageCapacity, ok end)
+ loadp JSObject::m_outOfLineStorage[objectAndStorage], objectAndStorage
+ loadi TagOffset - 8 * InlineStorageCapacity[objectAndStorage, propertyOffset, 8], tag
+ loadi PayloadOffset - 8 * InlineStorageCapacity[objectAndStorage, propertyOffset, 8], payload
+end
+
+macro loadPropertyAtVariableOffset(propertyOffset, objectAndStorage, tag, payload)
+ bilt propertyOffset, InlineStorageCapacity, .isInline
+ loadp JSObject::m_outOfLineStorage[objectAndStorage], objectAndStorage
+ jmp .ready
+.isInline:
+ addp JSFinalObject::m_inlineStorage + InlineStorageCapacity * 8, objectAndStorage
+.ready:
+ loadi TagOffset - 8 * InlineStorageCapacity[objectAndStorage, propertyOffset, 8], tag
+ loadi PayloadOffset - 8 * InlineStorageCapacity[objectAndStorage, propertyOffset, 8], payload
+end
+
macro resolveGlobal(size, slow)
# Operands are as follows:
# 4[PC] Destination for the load.
@@ -930,9 +948,7 @@ macro resolveGlobal(size, slow)
loadp JSCell::m_structure[t0], t1
bpneq t1, 12[PC], slow
loadi 16[PC], t1
- loadp JSObject::m_propertyStorage[t0], t0
- loadi TagOffset[t0, t1, 8], t2
- loadi PayloadOffset[t0, t1, 8], t3
+ loadPropertyAtVariableOffsetKnownNotFinal(t1, t0, t2, t3)
loadi 4[PC], t0
storei t2, TagOffset[cfr, t0, 8]
storei t3, PayloadOffset[cfr, t0, 8]
@@ -1087,31 +1103,44 @@ _llint_op_put_global_var_check:
dispatch(5)
-_llint_op_get_by_id:
+# We only do monomorphic get_by_id caching for now, and we do not modify the
+# opcode. We do, however, allow for the cache to change anytime if fails, since
+# ping-ponging is free. At best we get lucky and the get_by_id will continue
+# to take fast path on the new cache. At worst we take slow path, which is what
+# we would have been doing anyway.
+
+macro getById(getPropertyStorage)
traceExecution()
- # We only do monomorphic get_by_id caching for now, and we do not modify the
- # opcode. We do, however, allow for the cache to change anytime if fails, since
- # ping-ponging is free. At best we get lucky and the get_by_id will continue
- # to take fast path on the new cache. At worst we take slow path, which is what
- # we would have been doing anyway.
loadi 8[PC], t0
loadi 16[PC], t1
loadConstantOrVariablePayload(t0, CellTag, t3, .opGetByIdSlow)
loadi 20[PC], t2
- loadp JSObject::m_propertyStorage[t3], t0
- bpneq JSCell::m_structure[t3], t1, .opGetByIdSlow
- loadi 4[PC], t1
- loadi TagOffset[t0, t2], t3
- loadi PayloadOffset[t0, t2], t2
- storei t3, TagOffset[cfr, t1, 8]
- storei t2, PayloadOffset[cfr, t1, 8]
- loadi 32[PC], t1
- valueProfile(t3, t2, t1)
- dispatch(9)
+ getPropertyStorage(
+ t3,
+ t0,
+ macro (propertyStorage, scratch)
+ bpneq JSCell::m_structure[t3], t1, .opGetByIdSlow
+ loadi 4[PC], t1
+ loadi TagOffset[propertyStorage, t2], scratch
+ loadi PayloadOffset[propertyStorage, t2], t2
+ storei scratch, TagOffset[cfr, t1, 8]
+ storei t2, PayloadOffset[cfr, t1, 8]
+ loadi 32[PC], t1
+ valueProfile(scratch, t2, t1)
+ dispatch(9)
+ end)
+
+ .opGetByIdSlow:
+ callSlowPath(_llint_slow_path_get_by_id)
+ dispatch(9)
+end
+
+_llint_op_get_by_id:
+ getById(withInlineStorage)
-.opGetByIdSlow:
- callSlowPath(_llint_slow_path_get_by_id)
- dispatch(9)
+
+_llint_op_get_by_id_out_of_line:
+ getById(withOutOfLineStorage)
_llint_op_get_arguments_length:
@@ -1130,68 +1159,96 @@ _llint_op_get_arguments_length:
dispatch(4)
-_llint_op_put_by_id:
+macro putById(getPropertyStorage)
traceExecution()
loadi 4[PC], t3
loadi 16[PC], t1
loadConstantOrVariablePayload(t3, CellTag, t0, .opPutByIdSlow)
loadi 12[PC], t2
- loadp JSObject::m_propertyStorage[t0], t3
- bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
- loadi 20[PC], t1
- loadConstantOrVariable2Reg(t2, t0, t2)
- writeBarrier(t0, t2)
- storei t0, TagOffset[t3, t1]
- storei t2, PayloadOffset[t3, t1]
- dispatch(9)
+ getPropertyStorage(
+ t0,
+ t3,
+ macro (propertyStorage, scratch)
+ bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
+ loadi 20[PC], t1
+ loadConstantOrVariable2Reg(t2, scratch, t2)
+ writeBarrier(scratch, t2)
+ storei scratch, TagOffset[propertyStorage, t1]
+ storei t2, PayloadOffset[propertyStorage, t1]
+ dispatch(9)
+ end)
+end
+
+_llint_op_put_by_id:
+ putById(withInlineStorage)
.opPutByIdSlow:
callSlowPath(_llint_slow_path_put_by_id)
dispatch(9)
-macro putByIdTransition(additionalChecks)
+_llint_op_put_by_id_out_of_line:
+ putById(withOutOfLineStorage)
+
+
+macro putByIdTransition(additionalChecks, getPropertyStorage)
traceExecution()
loadi 4[PC], t3
loadi 16[PC], t1
loadConstantOrVariablePayload(t3, CellTag, t0, .opPutByIdSlow)
loadi 12[PC], t2
bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
- additionalChecks(t1, t3, .opPutByIdSlow)
+ additionalChecks(t1, t3)
loadi 20[PC], t1
- loadp JSObject::m_propertyStorage[t0], t3
- addp t1, t3
- loadConstantOrVariable2Reg(t2, t1, t2)
- writeBarrier(t1, t2)
- storei t1, TagOffset[t3]
- loadi 24[PC], t1
- storei t2, PayloadOffset[t3]
- storep t1, JSCell::m_structure[t0]
- dispatch(9)
+ getPropertyStorage(
+ t0,
+ t3,
+ macro (propertyStorage, scratch)
+ addp t1, propertyStorage, t3
+ loadConstantOrVariable2Reg(t2, t1, t2)
+ writeBarrier(t1, t2)
+ storei t1, TagOffset[t3]
+ loadi 24[PC], t1
+ storei t2, PayloadOffset[t3]
+ storep t1, JSCell::m_structure[t0]
+ dispatch(9)
+ end)
+end
+
+macro noAdditionalChecks(oldStructure, scratch)
+end
+
+macro structureChainChecks(oldStructure, scratch)
+ const protoCell = oldStructure # Reusing the oldStructure register for the proto
+
+ loadp 28[PC], scratch
+ assert(macro (ok) btpnz scratch, ok end)
+ loadp StructureChain::m_vector[scratch], scratch
+ assert(macro (ok) btpnz scratch, ok end)
+ bieq Structure::m_prototype + TagOffset[oldStructure], NullTag, .done
+.loop:
+ loadi Structure::m_prototype + PayloadOffset[oldStructure], protoCell
+ loadp JSCell::m_structure[protoCell], oldStructure
+ bpneq oldStructure, [scratch], .opPutByIdSlow
+ addp 4, scratch
+ bineq Structure::m_prototype + TagOffset[oldStructure], NullTag, .loop
+.done:
end
_llint_op_put_by_id_transition_direct:
- putByIdTransition(macro (oldStructure, scratch, slow) end)
+ putByIdTransition(noAdditionalChecks, withInlineStorage)
+
+
+_llint_op_put_by_id_transition_direct_out_of_line:
+ putByIdTransition(noAdditionalChecks, withOutOfLineStorage)
_llint_op_put_by_id_transition_normal:
- putByIdTransition(
- macro (oldStructure, scratch, slow)
- const protoCell = oldStructure # Reusing the oldStructure register for the proto
-
- loadp 28[PC], scratch
- assert(macro (ok) btpnz scratch, ok end)
- loadp StructureChain::m_vector[scratch], scratch
- assert(macro (ok) btpnz scratch, ok end)
- bieq Structure::m_prototype + TagOffset[oldStructure], NullTag, .done
- .loop:
- loadi Structure::m_prototype + PayloadOffset[oldStructure], protoCell
- loadp JSCell::m_structure[protoCell], oldStructure
- bpneq oldStructure, [scratch], slow
- addp 4, scratch
- bineq Structure::m_prototype + TagOffset[oldStructure], NullTag, .loop
- .done:
- end)
+ putByIdTransition(structureChainChecks, withInlineStorage)
+
+
+_llint_op_put_by_id_transition_normal_out_of_line:
+ putByIdTransition(structureChainChecks, withOutOfLineStorage)
_llint_op_get_by_val:
@@ -1261,9 +1318,8 @@ _llint_op_get_by_pname:
loadi [cfr, t0, 8], t0
subi 1, t0
biaeq t0, JSPropertyNameIterator::m_numCacheableSlots[t3], .opGetByPnameSlow
- loadp JSObject::m_propertyStorage[t2], t2
- loadi TagOffset[t2, t0, 8], t1
- loadi PayloadOffset[t2, t0, 8], t3
+ addi JSPropertyNameIterator::m_offsetBase[t3], t0
+ loadPropertyAtVariableOffset(t0, t2, t1, t3)
loadi 4[PC], t0
storei t1, TagOffset[cfr, t0, 8]
storei t3, PayloadOffset[cfr, t0, 8]
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
index a153586f4..a7a2ce88f 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
@@ -778,6 +778,22 @@ _llint_op_is_string:
dispatch(3)
+macro loadPropertyAtVariableOffsetKnownNotFinal(propertyOffset, objectAndStorage, value)
+ assert(macro (ok) bigteq propertyOffset, InlineStorageCapacity, ok end)
+ loadp JSObject::m_outOfLineStorage[objectAndStorage], objectAndStorage
+ loadp -8 * InlineStorageCapacity[objectAndStorage, propertyOffset, 8], value
+end
+
+macro loadPropertyAtVariableOffset(propertyOffset, objectAndStorage, value)
+ bilt propertyOffset, InlineStorageCapacity, .isInline
+ loadp JSObject::m_outOfLineStorage[objectAndStorage], objectAndStorage
+ jmp .ready
+.isInline:
+ addp JSFinalObject::m_inlineStorage + InlineStorageCapacity * 8, objectAndStorage
+.ready:
+ loadp -8 * InlineStorageCapacity[objectAndStorage, propertyOffset, 8], value
+end
+
macro resolveGlobal(size, slow)
# Operands are as follows:
# 8[PB, PC, 8] Destination for the load.
@@ -789,8 +805,7 @@ macro resolveGlobal(size, slow)
loadp JSCell::m_structure[t0], t1
bpneq t1, 24[PB, PC, 8], slow
loadis 32[PB, PC, 8], t1
- loadp JSObject::m_propertyStorage[t0], t0
- loadp [t0, t1, 8], t2
+ loadPropertyAtVariableOffset(t1, t0, t2)
loadis 8[PB, PC, 8], t0
storep t2, [cfr, t0, 8]
loadp (size - 1) * 8[PB, PC, 8], t0
@@ -937,7 +952,7 @@ _llint_op_put_global_var_check:
dispatch(5)
-_llint_op_get_by_id:
+macro getById(getPropertyStorage)
traceExecution()
# We only do monomorphic get_by_id caching for now, and we do not modify the
# opcode. We do, however, allow for the cache to change anytime if fails, since
@@ -948,18 +963,30 @@ _llint_op_get_by_id:
loadp 32[PB, PC, 8], t1
loadConstantOrVariableCell(t0, t3, .opGetByIdSlow)
loadis 40[PB, PC, 8], t2
- loadp JSObject::m_propertyStorage[t3], t0
- bpneq JSCell::m_structure[t3], t1, .opGetByIdSlow
- loadis 8[PB, PC, 8], t1
- loadp [t0, t2], t3
- storep t3, [cfr, t1, 8]
- loadp 64[PB, PC, 8], t1
- valueProfile(t3, t1)
- dispatch(9)
+ getPropertyStorage(
+ t3,
+ t0,
+ macro (propertyStorage, scratch)
+ bpneq JSCell::m_structure[t3], t1, .opGetByIdSlow
+ loadis 8[PB, PC, 8], t1
+ loadp [propertyStorage, t2], scratch
+ storep scratch, [cfr, t1, 8]
+ loadp 64[PB, PC, 8], t1
+ valueProfile(scratch, t1)
+ dispatch(9)
+ end)
+
+ .opGetByIdSlow:
+ callSlowPath(_llint_slow_path_get_by_id)
+ dispatch(9)
+end
+
+_llint_op_get_by_id:
+ getById(withInlineStorage)
-.opGetByIdSlow:
- callSlowPath(_llint_slow_path_get_by_id)
- dispatch(9)
+
+_llint_op_get_by_id_out_of_line:
+ getById(withOutOfLineStorage)
_llint_op_get_arguments_length:
@@ -978,65 +1005,93 @@ _llint_op_get_arguments_length:
dispatch(4)
-_llint_op_put_by_id:
+macro putById(getPropertyStorage)
traceExecution()
loadis 8[PB, PC, 8], t3
loadp 32[PB, PC, 8], t1
loadConstantOrVariableCell(t3, t0, .opPutByIdSlow)
loadis 24[PB, PC, 8], t2
- loadp JSObject::m_propertyStorage[t0], t3
- bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
- loadis 40[PB, PC, 8], t1
- loadConstantOrVariable(t2, t0)
- writeBarrier(t0)
- storep t0, [t3, t1]
- dispatch(9)
+ getPropertyStorage(
+ t0,
+ t3,
+ macro (propertyStorage, scratch)
+ bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
+ loadis 40[PB, PC, 8], t1
+ loadConstantOrVariable(t2, scratch)
+ writeBarrier(t0)
+ storep scratch, [propertyStorage, t1]
+ dispatch(9)
+ end)
+end
+
+_llint_op_put_by_id:
+ putById(withInlineStorage)
.opPutByIdSlow:
callSlowPath(_llint_slow_path_put_by_id)
dispatch(9)
-macro putByIdTransition(additionalChecks)
+_llint_op_put_by_id_out_of_line:
+ putById(withOutOfLineStorage)
+
+
+macro putByIdTransition(additionalChecks, getPropertyStorage)
traceExecution()
loadis 8[PB, PC, 8], t3
loadp 32[PB, PC, 8], t1
loadConstantOrVariableCell(t3, t0, .opPutByIdSlow)
loadis 24[PB, PC, 8], t2
bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
- additionalChecks(t1, t3, .opPutByIdSlow)
+ additionalChecks(t1, t3)
loadis 40[PB, PC, 8], t1
- loadp JSObject::m_propertyStorage[t0], t3
- addp t1, t3
- loadConstantOrVariable(t2, t1)
- writeBarrier(t1)
- storep t1, [t3]
- loadp 48[PB, PC, 8], t1
- storep t1, JSCell::m_structure[t0]
- dispatch(9)
+ getPropertyStorage(
+ t0,
+ t3,
+ macro (propertyStorage, scratch)
+ addp t1, propertyStorage, t3
+ loadConstantOrVariable(t2, t1)
+ writeBarrier(t1)
+ storep t1, [t3]
+ loadp 48[PB, PC, 8], t1
+ storep t1, JSCell::m_structure[t0]
+ dispatch(9)
+ end)
+end
+
+macro noAdditionalChecks(oldStructure, scratch)
+end
+
+macro structureChainChecks(oldStructure, scratch)
+ const protoCell = oldStructure # Reusing the oldStructure register for the proto
+ loadp 56[PB, PC, 8], scratch
+ assert(macro (ok) btpnz scratch, ok end)
+ loadp StructureChain::m_vector[scratch], scratch
+ assert(macro (ok) btpnz scratch, ok end)
+ bpeq Structure::m_prototype[oldStructure], ValueNull, .done
+.loop:
+ loadp Structure::m_prototype[oldStructure], protoCell
+ loadp JSCell::m_structure[protoCell], oldStructure
+ bpneq oldStructure, [scratch], .opPutByIdSlow
+ addp 8, scratch
+ bpneq Structure::m_prototype[oldStructure], ValueNull, .loop
+.done:
end
_llint_op_put_by_id_transition_direct:
- putByIdTransition(macro (oldStructure, scratch, slow) end)
+ putByIdTransition(noAdditionalChecks, withInlineStorage)
+
+
+_llint_op_put_by_id_transition_direct_out_of_line:
+ putByIdTransition(noAdditionalChecks, withOutOfLineStorage)
_llint_op_put_by_id_transition_normal:
- putByIdTransition(
- macro (oldStructure, scratch, slow)
- const protoCell = oldStructure # Reusing the oldStructure register for the proto
- loadp 56[PB, PC, 8], scratch
- assert(macro (ok) btpnz scratch, ok end)
- loadp StructureChain::m_vector[scratch], scratch
- assert(macro (ok) btpnz scratch, ok end)
- bpeq Structure::m_prototype[oldStructure], ValueNull, .done
- .loop:
- loadp Structure::m_prototype[oldStructure], protoCell
- loadp JSCell::m_structure[protoCell], oldStructure
- bpneq oldStructure, [scratch], slow
- addp 8, scratch
- bpneq Structure::m_prototype[oldStructure], ValueNull, .loop
- .done:
- end)
+ putByIdTransition(structureChainChecks, withInlineStorage)
+
+
+_llint_op_put_by_id_transition_normal_out_of_line:
+ putByIdTransition(structureChainChecks, withOutOfLineStorage)
_llint_op_get_by_val:
@@ -1106,8 +1161,8 @@ _llint_op_get_by_pname:
loadi PayloadOffset[cfr, t3, 8], t3
subi 1, t3
biaeq t3, JSPropertyNameIterator::m_numCacheableSlots[t1], .opGetByPnameSlow
- loadp JSObject::m_propertyStorage[t0], t0
- loadp [t0, t3, 8], t0
+ addi JSPropertyNameIterator::m_offsetBase[t1], t3
+ loadPropertyAtVariableOffset(t3, t0, t0)
loadis 8[PB, PC, 8], t1
storep t0, [cfr, t1, 8]
dispatch(7)