From 5466563f4b5b6b86523e3f89bb7f77e5b5270c78 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 15 Oct 2012 16:08:57 +0200 Subject: Imported WebKit commit 0dc6cd75e1d4836eaffbb520be96fac4847cc9d2 (http://svn.webkit.org/repository/webkit/trunk@131300) WebKit update which introduces the QtWebKitWidgets module that contains the WK1 widgets based API. (In fact it renames QtWebKit to QtWebKitWidgets while we're working on completing the entire split as part of https://bugs.webkit.org/show_bug.cgi?id=99314 --- Source/JavaScriptCore/llint/LLIntData.cpp | 20 ++--- .../JavaScriptCore/llint/LLIntOfflineAsmConfig.h | 7 ++ .../JavaScriptCore/llint/LLIntOffsetsExtractor.cpp | 2 +- Source/JavaScriptCore/llint/LLIntSlowPaths.cpp | 20 ++--- Source/JavaScriptCore/llint/LLIntSlowPaths.h | 2 +- .../JavaScriptCore/llint/LowLevelInterpreter.asm | 31 ++++--- .../llint/LowLevelInterpreter32_64.asm | 96 ++++++++++++++++------ .../JavaScriptCore/llint/LowLevelInterpreter64.asm | 92 +++++++++++++++------ 8 files changed, 183 insertions(+), 87 deletions(-) (limited to 'Source/JavaScriptCore/llint') diff --git a/Source/JavaScriptCore/llint/LLIntData.cpp b/Source/JavaScriptCore/llint/LLIntData.cpp index c7fd741d6..8e2dacf4d 100644 --- a/Source/JavaScriptCore/llint/LLIntData.cpp +++ b/Source/JavaScriptCore/llint/LLIntData.cpp @@ -68,14 +68,14 @@ void Data::performAssertions(JSGlobalData& globalData) // Assertions to match LowLevelInterpreter.asm. If you change any of this code, be // prepared to change LowLevelInterpreter.asm as well!! - ASSERT(RegisterFile::CallFrameHeaderSize * 8 == 48); - ASSERT(RegisterFile::ArgumentCount * 8 == -48); - ASSERT(RegisterFile::CallerFrame * 8 == -40); - ASSERT(RegisterFile::Callee * 8 == -32); - ASSERT(RegisterFile::ScopeChain * 8 == -24); - ASSERT(RegisterFile::ReturnPC * 8 == -16); - ASSERT(RegisterFile::CodeBlock * 8 == -8); - ASSERT(CallFrame::argumentOffsetIncludingThis(0) == -RegisterFile::CallFrameHeaderSize - 1); + ASSERT(JSStack::CallFrameHeaderSize * 8 == 48); + ASSERT(JSStack::ArgumentCount * 8 == -48); + ASSERT(JSStack::CallerFrame * 8 == -40); + ASSERT(JSStack::Callee * 8 == -32); + ASSERT(JSStack::ScopeChain * 8 == -24); + ASSERT(JSStack::ReturnPC * 8 == -16); + ASSERT(JSStack::CodeBlock * 8 == -8); + ASSERT(CallFrame::argumentOffsetIncludingThis(0) == -JSStack::CallFrameHeaderSize - 1); #if CPU(BIG_ENDIAN) ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag) == 0); ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload) == 4); @@ -108,9 +108,9 @@ void Data::performAssertions(JSGlobalData& globalData) ASSERT(ImplementsHasInstance == 2); ASSERT(ImplementsDefaultHasInstance == 8); #if USE(JSVALUE64) - ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(sizeof(JSFinalObject)) - &globalData.heap.firstAllocatorWithoutDestructors() == 1); + ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(JSObject::allocationSize(INLINE_STORAGE_CAPACITY)) - &globalData.heap.firstAllocatorWithoutDestructors() == 1); #else - ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(sizeof(JSFinalObject)) - &globalData.heap.firstAllocatorWithoutDestructors() == 3); + ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(JSObject::allocationSize(INLINE_STORAGE_CAPACITY)) - &globalData.heap.firstAllocatorWithoutDestructors() == 3); #endif ASSERT(FirstConstantRegisterIndex == 0x40000000); ASSERT(GlobalCode == 0); diff --git a/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h b/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h index 63488aa0b..da2d510b5 100644 --- a/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h +++ b/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h @@ -37,6 +37,7 @@ #define OFFLINE_ASM_X86 0 #define OFFLINE_ASM_ARMv7 0 #define OFFLINE_ASM_X86_64 0 +#define OFFLINE_ASM_ARMv7s 0 #else // !ENABLE(LLINT_C_LOOP) @@ -48,6 +49,12 @@ #define OFFLINE_ASM_X86 0 #endif +#ifdef __ARM_ARCH_7S__ +#define OFFLINE_ASM_ARMv7s 1 +#else +#define OFFLINE_ASM_ARMv7s 0 +#endif + #if CPU(ARM_THUMB2) #define OFFLINE_ASM_ARMv7 1 #else diff --git a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp index 3ed6d6d2f..cbfff29d6 100644 --- a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp +++ b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp @@ -38,13 +38,13 @@ #include "JSGlobalObject.h" #include "JSObject.h" #include "JSPropertyNameIterator.h" +#include "JSStack.h" #include "JSString.h" #include "JSTypeInfo.h" #include "JSVariableObject.h" #include "JumpTable.h" #include "LLIntOfflineAsmConfig.h" #include "MarkedSpace.h" -#include "RegisterFile.h" #include "Structure.h" #include "StructureChain.h" diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp index f9833e4ce..5a9b41da7 100644 --- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp +++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp @@ -396,7 +396,7 @@ LLINT_SLOW_PATH_DECL(replace) } #endif // ENABLE(JIT) -LLINT_SLOW_PATH_DECL(register_file_check) +LLINT_SLOW_PATH_DECL(stack_check) { LLINT_BEGIN(); #if LLINT_SLOW_PATH_TRACING @@ -404,10 +404,10 @@ LLINT_SLOW_PATH_DECL(register_file_check) dataLog("CodeBlock = %p.\n", exec->codeBlock()); dataLog("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeRegisters); dataLog("Num vars = %u.\n", exec->codeBlock()->m_numVars); - dataLog("Current end is at %p.\n", exec->globalData().interpreter->registerFile().end()); + dataLog("Current end is at %p.\n", exec->globalData().interpreter->stack().end()); #endif - ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->globalData().interpreter->registerFile().end()); - if (UNLIKELY(!globalData.interpreter->registerFile().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) { + ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->globalData().interpreter->stack().end()); + if (UNLIKELY(!globalData.interpreter->stack().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) { ReturnAddressPtr returnPC = exec->returnPC(); exec = exec->callerFrame(); globalData.exception = createStackOverflowError(exec); @@ -420,7 +420,7 @@ LLINT_SLOW_PATH_DECL(register_file_check) LLINT_SLOW_PATH_DECL(slow_path_call_arityCheck) { LLINT_BEGIN(); - ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->registerFile(), CodeForCall); + ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->stack(), CodeForCall); if (!newExec) { ReturnAddressPtr returnPC = exec->returnPC(); exec = exec->callerFrame(); @@ -434,7 +434,7 @@ LLINT_SLOW_PATH_DECL(slow_path_call_arityCheck) LLINT_SLOW_PATH_DECL(slow_path_construct_arityCheck) { LLINT_BEGIN(); - ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->registerFile(), CodeForConstruct); + ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->stack(), CodeForConstruct); if (!newExec) { ReturnAddressPtr returnPC = exec->returnPC(); exec = exec->callerFrame(); @@ -1408,7 +1408,7 @@ inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpec ExecState* execCallee = exec + pc[3].u.operand; execCallee->setArgumentCountIncludingThis(pc[2].u.operand); - execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue; + execCallee->uncheckedR(JSStack::Callee) = calleeAsValue; execCallee->setCallerFrame(exec); ASSERT(pc[4].u.callLinkInfo); @@ -1438,11 +1438,11 @@ LLINT_SLOW_PATH_DECL(slow_path_call_varargs) JSValue calleeAsValue = LLINT_OP_C(1).jsValue(); ExecState* execCallee = loadVarargs( - exec, &globalData.interpreter->registerFile(), + exec, &globalData.interpreter->stack(), LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), pc[4].u.operand); LLINT_CALL_CHECK_EXCEPTION(exec, pc); - execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue; + execCallee->uncheckedR(JSStack::Callee) = calleeAsValue; execCallee->setCallerFrame(exec); exec->setCurrentVPC(pc + OPCODE_LENGTH(op_call_varargs)); @@ -1458,7 +1458,7 @@ LLINT_SLOW_PATH_DECL(slow_path_call_eval) execCallee->setArgumentCountIncludingThis(pc[2].u.operand); execCallee->setCallerFrame(exec); - execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue; + execCallee->uncheckedR(JSStack::Callee) = calleeAsValue; execCallee->setScope(exec->scope()); execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point)); execCallee->setCodeBlock(0); diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.h b/Source/JavaScriptCore/llint/LLIntSlowPaths.h index fe897d4a4..5bfb0ccdf 100644 --- a/Source/JavaScriptCore/llint/LLIntSlowPaths.h +++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.h @@ -112,7 +112,7 @@ LLINT_SLOW_PATH_HIDDEN_DECL(entry_osr_function_for_call_arityCheck); LLINT_SLOW_PATH_HIDDEN_DECL(entry_osr_function_for_construct_arityCheck); LLINT_SLOW_PATH_HIDDEN_DECL(loop_osr); LLINT_SLOW_PATH_HIDDEN_DECL(replace); -LLINT_SLOW_PATH_HIDDEN_DECL(register_file_check); +LLINT_SLOW_PATH_HIDDEN_DECL(stack_check); LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_call_arityCheck); LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_construct_arityCheck); LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_create_activation); diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm index e347ccc70..a971abf4f 100644 --- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm +++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm @@ -24,7 +24,13 @@ # First come the common protocols that both interpreters use. Note that each # of these must have an ASSERT() in LLIntData.cpp -# These declarations must match interpreter/RegisterFile.h. +# Work-around for the fact that the toolchain's awareness of armv7s results in +# a separate slab in the fat binary, yet the offlineasm doesn't know to expect +# it. +if ARMv7s +end + +# These declarations must match interpreter/JSStack.h. const CallFrameHeaderSize = 48 const ArgumentCount = -48 const CallerFrame = -40 @@ -38,7 +44,7 @@ const ThisArgumentOffset = -CallFrameHeaderSize - 8 # Some register conventions. if JSVALUE64 # - Use a pair of registers to represent the PC: one register for the - # base of the register file, and one register for the index. + # base of the stack, and one register for the index. # - The PC base (or PB for short) should be stored in the csr. It will # get clobbered on calls to other JS code, but will get saved on calls # to C functions. @@ -63,8 +69,10 @@ end # Constant for reasoning about butterflies. const IsArray = 1 -const HasArrayStorage = 8 -const AllArrayTypes = 15 +const IndexingShapeMask = 30 +const ContiguousShape = 26 +const ArrayStorageShape = 28 +const SlowPutArrayStorageShape = 30 # Type constants. const StringType = 5 @@ -89,12 +97,8 @@ const LLIntReturnPC = ArgumentCount + TagOffset # String flags. const HashFlags8BitBuffer = 64 -# Property storage constants -if JSVALUE64 - const InlineStorageCapacity = 6 -else - const InlineStorageCapacity = 7 -end +# Copied from PropertyOffset.h +const firstOutOfLineOffset = 100 # Allocation constants if JSVALUE64 @@ -319,13 +323,13 @@ macro functionInitialization(profileArgSkip) # Check stack height. loadi CodeBlock::m_numCalleeRegisters[t1], t0 loadp CodeBlock::m_globalData[t1], t2 - loadp JSGlobalData::interpreter[t2], t2 # FIXME: Can get to the RegisterFile from the JITStackFrame + loadp JSGlobalData::interpreter[t2], t2 # FIXME: Can get to the JSStack from the JITStackFrame lshifti 3, t0 addp t0, cfr, t0 - bpaeq Interpreter::m_registerFile + RegisterFile::m_end[t2], t0, .stackHeightOK + bpaeq Interpreter::m_stack + JSStack::m_end[t2], t0, .stackHeightOK # Stack height check failed - need to call a slow_path. - callSlowPath(_llint_register_file_check) + callSlowPath(_llint_stack_check) .stackHeightOK: end @@ -910,3 +914,4 @@ _llint_op_put_by_id_transition: # Indicate the end of LLInt. _llint_end: crash() + diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm index 83abf380c..f0d45eb0e 100644 --- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm +++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm @@ -937,24 +937,24 @@ _llint_op_is_string: dispatch(3) -macro loadPropertyAtVariableOffsetKnownNotFinal(propertyOffset, objectAndStorage, tag, payload) - assert(macro (ok) bigteq propertyOffset, InlineStorageCapacity, ok end) +macro loadPropertyAtVariableOffsetKnownNotInline(propertyOffset, objectAndStorage, tag, payload) + assert(macro (ok) bigteq propertyOffset, firstOutOfLineOffset, ok end) negi propertyOffset 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 + loadi TagOffset + (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffset, 8], tag + loadi PayloadOffset + (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffset, 8], payload end macro loadPropertyAtVariableOffset(propertyOffset, objectAndStorage, tag, payload) - bilt propertyOffset, InlineStorageCapacity, .isInline + bilt propertyOffset, firstOutOfLineOffset, .isInline loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage negi propertyOffset jmp .ready .isInline: - addp JSFinalObject::m_inlineStorage - (InlineStorageCapacity - 1) * 8 + sizeof IndexingHeader, objectAndStorage + addp sizeof JSObject - (firstOutOfLineOffset - 2) * 8, objectAndStorage .ready: - loadi TagOffset + (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffset, 8], tag - loadi PayloadOffset + (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffset, 8], payload + loadi TagOffset + (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffset, 8], tag + loadi PayloadOffset + (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffset, 8], payload end macro resolveGlobal(size, slow) @@ -968,7 +968,7 @@ macro resolveGlobal(size, slow) loadp JSCell::m_structure[t0], t1 bpneq t1, 12[PC], slow loadi 16[PC], t1 - loadPropertyAtVariableOffsetKnownNotFinal(t1, t0, t2, t3) + loadPropertyAtVariableOffsetKnownNotInline(t1, t0, t2, t3) loadi 4[PC], t0 storei t2, TagOffset[cfr, t0, 8] storei t3, PayloadOffset[cfr, t0, 8] @@ -1171,7 +1171,7 @@ _llint_op_get_array_length: loadp JSCell::m_structure[t3], t2 arrayProfile(t2, t1, t0) btiz t2, IsArray, .opGetArrayLengthSlow - btiz t2, HasArrayStorage, .opGetArrayLengthSlow + btiz t2, IndexingShapeMask, .opGetArrayLengthSlow loadi 4[PC], t1 loadp 32[PC], t2 loadp JSObject::m_butterfly[t3], t0 @@ -1302,14 +1302,26 @@ _llint_op_get_by_val: loadp JSCell::m_structure[t0], t2 loadp 16[PC], t3 arrayProfile(t2, t3, t1) - btiz t2, HasArrayStorage, .opGetByValSlow loadi 12[PC], t3 loadConstantOrVariablePayload(t3, Int32Tag, t1, .opGetByValSlow) loadp JSObject::m_butterfly[t0], t3 + andi IndexingShapeMask, t2 + bineq t2, ContiguousShape, .opGetByValNotContiguous + + biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow + loadi TagOffset[t3, t1, 8], t2 + loadi PayloadOffset[t3, t1, 8], t1 + jmp .opGetByValDone + +.opGetByValNotContiguous: + subi ArrayStorageShape, t2 + bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValSlow biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValSlow - loadi 4[PC], t0 loadi ArrayStorage::m_vector + TagOffset[t3, t1, 8], t2 loadi ArrayStorage::m_vector + PayloadOffset[t3, t1, 8], t1 + +.opGetByValDone: + loadi 4[PC], t0 bieq t2, EmptyValueTag, .opGetByValSlow storei t2, TagOffset[cfr, t0, 8] storei t1, PayloadOffset[cfr, t0, 8] @@ -1364,7 +1376,10 @@ _llint_op_get_by_pname: loadi [cfr, t0, 8], t0 subi 1, t0 biaeq t0, JSPropertyNameIterator::m_numCacheableSlots[t3], .opGetByPnameSlow - addi JSPropertyNameIterator::m_offsetBase[t3], t0 + bilt t0, JSPropertyNameIterator::m_cachedStructureInlineCapacity[t3], .opGetByPnameInlineProperty + addi firstOutOfLineOffset, t0 + subi JSPropertyNameIterator::m_cachedStructureInlineCapacity[t3], t0 +.opGetByPnameInlineProperty: loadPropertyAtVariableOffset(t0, t2, t1, t3) loadi 4[PC], t0 storei t1, TagOffset[cfr, t0, 8] @@ -1383,29 +1398,53 @@ _llint_op_put_by_val: loadp JSCell::m_structure[t1], t2 loadp 16[PC], t3 arrayProfile(t2, t3, t0) - btiz t2, HasArrayStorage, .opPutByValSlow loadi 8[PC], t0 - loadConstantOrVariablePayload(t0, Int32Tag, t2, .opPutByValSlow) + loadConstantOrVariablePayload(t0, Int32Tag, t3, .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 - loadConstantOrVariable2Reg(t3, t1, t3) - writeBarrier(t1, t3) - storei t1, ArrayStorage::m_vector + TagOffset[t0, t2, 8] - storei t3, ArrayStorage::m_vector + PayloadOffset[t0, t2, 8] + andi IndexingShapeMask, t2 + bineq t2, ContiguousShape, .opPutByValNotContiguous + + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValContiguousOutOfBounds +.opPutByValContiguousStoreResult: + loadi 12[PC], t2 + loadConstantOrVariable2Reg(t2, t1, t2) + writeBarrier(t1, t2) + storei t1, TagOffset[t0, t3, 8] + storei t2, PayloadOffset[t0, t3, 8] dispatch(5) -.opPutByValEmpty: +.opPutByValContiguousOutOfBounds: + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow if VALUE_PROFILER - storeb 1, ArrayProfile::m_mayStoreToHole[t3] + loadp 16[PC], t1 + storeb 1, ArrayProfile::m_mayStoreToHole[t1] + end + addi 1, t3, t2 + storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0] + jmp .opPutByValContiguousStoreResult + +.opPutByValNotContiguous: + bineq t2, ArrayStorageShape, .opPutByValSlow + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow + bieq ArrayStorage::m_vector + TagOffset[t0, t3, 8], EmptyValueTag, .opPutByValArrayStorageEmpty +.opPutByValArrayStorageStoreResult: + loadi 12[PC], t2 + loadConstantOrVariable2Reg(t2, t1, t2) + writeBarrier(t1, t2) + storei t1, ArrayStorage::m_vector + TagOffset[t0, t3, 8] + storei t2, ArrayStorage::m_vector + PayloadOffset[t0, t3, 8] + dispatch(5) + +.opPutByValArrayStorageEmpty: + if VALUE_PROFILER + loadp 16[PC], t1 + storeb 1, ArrayProfile::m_mayStoreToHole[t1] end addi 1, ArrayStorage::m_numValuesInVector[t0] - bib t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValStoreResult + bib t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValArrayStorageStoreResult addi 1, t2, t1 storei t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0] - jmp .opPutByValStoreResult + jmp .opPutByValArrayStorageStoreResult .opPutByValSlow: callSlowPath(_llint_slow_path_put_by_val) @@ -1485,7 +1524,10 @@ _llint_op_jneq_ptr: traceExecution() loadi 4[PC], t0 loadi 8[PC], t1 + loadp CodeBlock[cfr], t2 + loadp CodeBlock::m_globalObject[t2], t2 bineq TagOffset[cfr, t0, 8], CellTag, .opJneqPtrBranch + loadp JSGlobalObject::m_specialPointers[t2, t1, 8], t1 bpeq PayloadOffset[cfr, t0, 8], t1, .opJneqPtrFallThrough .opJneqPtrBranch: dispatchBranch(12[PC]) diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm index 4d614f51f..8b72674ab 100644 --- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm +++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm @@ -796,23 +796,23 @@ _llint_op_is_string: dispatch(3) -macro loadPropertyAtVariableOffsetKnownNotFinal(propertyOffsetAsPointer, objectAndStorage, value) - assert(macro (ok) bigteq propertyOffsetAsPointer, InlineStorageCapacity, ok end) +macro loadPropertyAtVariableOffsetKnownNotInline(propertyOffsetAsPointer, objectAndStorage, value) + assert(macro (ok) bigteq propertyOffsetAsPointer, firstOutOfLineOffset, ok end) negp propertyOffsetAsPointer loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage - loadp (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffsetAsPointer, 8], value + loadp (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffsetAsPointer, 8], value end macro loadPropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value) - bilt propertyOffsetAsInt, InlineStorageCapacity, .isInline + bilt propertyOffsetAsInt, firstOutOfLineOffset, .isInline loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage negi propertyOffsetAsInt sxi2p propertyOffsetAsInt, propertyOffsetAsInt jmp .ready .isInline: - addp JSFinalObject::m_inlineStorage - (InlineStorageCapacity - 1) * 8 + sizeof IndexingHeader, objectAndStorage + addp sizeof JSObject - (firstOutOfLineOffset - 2) * 8, objectAndStorage .ready: - loadp (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffsetAsInt, 8], value + loadp (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffsetAsInt, 8], value end macro resolveGlobal(size, slow) @@ -826,7 +826,7 @@ macro resolveGlobal(size, slow) loadp JSCell::m_structure[t0], t1 bpneq t1, 24[PB, PC, 8], slow loadis 32[PB, PC, 8], t1 - loadPropertyAtVariableOffset(t1, t0, t2) + loadPropertyAtVariableOffsetKnownNotInline(t1, t0, t2) loadis 8[PB, PC, 8], t0 storep t2, [cfr, t0, 8] loadp (size - 1) * 8[PB, PC, 8], t0 @@ -1018,7 +1018,7 @@ _llint_op_get_array_length: loadp JSCell::m_structure[t3], t2 arrayProfile(t2, t1, t0) btiz t2, IsArray, .opGetArrayLengthSlow - btiz t2, HasArrayStorage, .opGetArrayLengthSlow + btiz t2, IndexingShapeMask, .opGetArrayLengthSlow loadis 8[PB, PC, 8], t1 loadp 64[PB, PC, 8], t2 loadp JSObject::m_butterfly[t3], t0 @@ -1147,14 +1147,27 @@ _llint_op_get_by_val: loadp 32[PB, PC, 8], t3 arrayProfile(t2, t3, t1) loadis 24[PB, PC, 8], t3 - btiz t2, HasArrayStorage, .opGetByValSlow loadConstantOrVariableInt32(t3, t1, .opGetByValSlow) sxi2p t1, t1 loadp JSObject::m_butterfly[t0], t3 + andi IndexingShapeMask, t2 + bineq t2, ContiguousShape, .opGetByValNotContiguous + + biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow + loadis 8[PB, PC, 8], t0 + loadp [t3, t1, 8], t2 + btpz t2, .opGetByValSlow + jmp .opGetByValDone + +.opGetByValNotContiguous: + subi ArrayStorageShape, t2 + bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValSlow 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 + +.opGetByValDone: storep t2, [cfr, t0, 8] loadp 40[PB, PC, 8], t0 valueProfile(t2, t0) @@ -1208,7 +1221,10 @@ _llint_op_get_by_pname: loadi PayloadOffset[cfr, t3, 8], t3 subi 1, t3 biaeq t3, JSPropertyNameIterator::m_numCacheableSlots[t1], .opGetByPnameSlow - addi JSPropertyNameIterator::m_offsetBase[t1], t3 + bilt t3, JSPropertyNameIterator::m_cachedStructureInlineCapacity[t1], .opGetByPnameInlineProperty + addi firstOutOfLineOffset, t3 + subi JSPropertyNameIterator::m_cachedStructureInlineCapacity[t1], t3 +.opGetByPnameInlineProperty: loadPropertyAtVariableOffset(t3, t0, t0) loadis 8[PB, PC, 8], t1 storep t0, [cfr, t1, 8] @@ -1226,29 +1242,52 @@ _llint_op_put_by_val: loadp JSCell::m_structure[t1], t2 loadp 32[PB, PC, 8], t3 arrayProfile(t2, t3, t0) - btiz t2, HasArrayStorage, .opPutByValSlow loadis 16[PB, PC, 8], t0 - loadConstantOrVariableInt32(t0, t2, .opPutByValSlow) - sxi2p t2, t2 + loadConstantOrVariableInt32(t0, t3, .opPutByValSlow) + sxi2p t3, t3 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 - loadConstantOrVariable(t3, t1) + andi IndexingShapeMask, t2 + bineq t2, ContiguousShape, .opPutByValNotContiguous + + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValContiguousOutOfBounds +.opPutByValContiguousStoreResult: + loadis 24[PB, PC, 8], t2 + loadConstantOrVariable(t2, t1) + writeBarrier(t1) + storep t1, [t0, t3, 8] + dispatch(5) + +.opPutByValContiguousOutOfBounds: + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow + if VALUE_PROFILER + loadp 32[PB, PC, 8], t2 + storeb 1, ArrayProfile::m_mayStoreToHole[t2] + end + addi 1, t3, t2 + storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0] + jmp .opPutByValContiguousStoreResult + +.opPutByValNotContiguous: + bineq t2, ArrayStorageShape, .opPutByValSlow + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow + btpz ArrayStorage::m_vector[t0, t3, 8], .opPutByValArrayStorageEmpty +.opPutByValArrayStorageStoreResult: + loadis 24[PB, PC, 8], t2 + loadConstantOrVariable(t2, t1) writeBarrier(t1) - storep t1, ArrayStorage::m_vector[t0, t2, 8] + storep t1, ArrayStorage::m_vector[t0, t3, 8] dispatch(5) -.opPutByValEmpty: +.opPutByValArrayStorageEmpty: if VALUE_PROFILER - storeb 1, ArrayProfile::m_mayStoreToHole[t3] + loadp 32[PB, PC, 8], t1 + storeb 1, ArrayProfile::m_mayStoreToHole[t1] end addi 1, ArrayStorage::m_numValuesInVector[t0] - bib t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValStoreResult - addi 1, t2, t1 + bib t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValArrayStorageStoreResult + addi 1, t3, t1 storei t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0] - jmp .opPutByValStoreResult + jmp .opPutByValArrayStorageStoreResult .opPutByValSlow: callSlowPath(_llint_slow_path_put_by_val) @@ -1328,7 +1367,10 @@ _llint_op_jneq_null: _llint_op_jneq_ptr: traceExecution() loadis 8[PB, PC, 8], t0 - loadp 16[PB, PC, 8], t1 + loadi 16[PB, PC, 8], t1 + loadp CodeBlock[cfr], t2 + loadp CodeBlock::m_globalObject[t2], t2 + loadp JSGlobalObject::m_specialPointers[t2, t1, 8], t1 bpneq t1, [cfr, t0, 8], .opJneqPtrTarget dispatch(4) -- cgit v1.2.1