Commit 77da1086 authored by barraclough@apple.com's avatar barraclough@apple.com

Bug 54524 - Allow JSObject to fully utilize cell's capacity for inline storage.

Reviewed by Geoff Garen.

Currently JSObject is both directly instantiated for regular JS objects, and
derived to implement subtypes. A consequence of this is that we need to ensure
that sufficient space from the cell is left unused and available for any data
members that will be introduced by subclasses of JSObject. By restructuring
the internal storage array out of JSObject we can increase the size in the
internal storage for regular objects.

Add classes JSFinalObject and JSNonFinalObject. JSNonFinalObject retains as
much additional capacity as is currently available to allow for data members
in subclasses. JSFinalObject utilizes all available space for internal storage,
and only allows construction through JSFinalObject::create().

Source/JavaScriptCore: 

The additional storage made available in the JSObject means that we need no
longer rely on a union of the internal storage with a pointer to storage that
is only valid for external storage. This means we can go back to always having
a valid pointer to property storage, regardless of whether this is internal or
external. This simplifies some cases of access to the array from C code, and
significantly simplifies JIT access, since repatching no longer needs to be
able to change between a load of the storage pointer / a LEA of the internal
storage.

* API/JSObjectRef.cpp:
(JSObjectMake):
* assembler/ARMAssembler.h:
* assembler/ARMv7Assembler.h:
* assembler/AbstractMacroAssembler.h:
(JSC::AbstractMacroAssembler::repatchPointer):
* assembler/MIPSAssembler.h:
* assembler/MacroAssemblerARM.h:
* assembler/MacroAssemblerARMv7.h:
* assembler/MacroAssemblerMIPS.h:
* assembler/MacroAssemblerX86.h:
* assembler/MacroAssemblerX86_64.h:
* assembler/RepatchBuffer.h:
* assembler/X86Assembler.h:
* debugger/DebuggerActivation.cpp:
(JSC::DebuggerActivation::DebuggerActivation):
* debugger/DebuggerActivation.h:
* interpreter/Interpreter.cpp:
(JSC::Interpreter::privateExecute):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_resolve_global):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_resolve_global):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::compileGetDirectOffset):
(JSC::JIT::emit_op_get_by_pname):
(JSC::JIT::compileGetByIdHotPath):
(JSC::JIT::emit_op_put_by_id):
(JSC::JIT::compilePutDirectOffset):
(JSC::JIT::patchGetByIdSelf):
(JSC::JIT::patchPutByIdReplace):
(JSC::JIT::privateCompileGetByIdProto):
(JSC::JIT::privateCompileGetByIdSelfList):
(JSC::JIT::privateCompileGetByIdProtoList):
(JSC::JIT::privateCompileGetByIdChainList):
(JSC::JIT::privateCompileGetByIdChain):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::compileGetByIdHotPath):
(JSC::JIT::emit_op_put_by_id):
(JSC::JIT::compilePutDirectOffset):
(JSC::JIT::compileGetDirectOffset):
(JSC::JIT::patchGetByIdSelf):
(JSC::JIT::patchPutByIdReplace):
(JSC::JIT::privateCompileGetByIdProto):
(JSC::JIT::privateCompileGetByIdSelfList):
(JSC::JIT::privateCompileGetByIdProtoList):
(JSC::JIT::privateCompileGetByIdChainList):
(JSC::JIT::privateCompileGetByIdChain):
(JSC::JIT::emit_op_get_by_pname):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* runtime/Arguments.h:
(JSC::Arguments::Arguments):
* runtime/ErrorInstance.cpp:
(JSC::ErrorInstance::ErrorInstance):
* runtime/ErrorInstance.h:
* runtime/ExceptionHelpers.cpp:
(JSC::InterruptedExecutionError::InterruptedExecutionError):
(JSC::TerminatedExecutionError::TerminatedExecutionError):
* runtime/JSArray.cpp:
(JSC::JSArray::JSArray):
* runtime/JSArray.h:
* runtime/JSByteArray.cpp:
(JSC::JSByteArray::JSByteArray):
* runtime/JSByteArray.h:
(JSC::JSByteArray::JSByteArray):
* runtime/JSFunction.cpp:
(JSC::JSFunction::getOwnPropertySlot):
* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::JSGlobalData):
* runtime/JSGlobalObject.h:
(JSC::constructEmptyObject):
* runtime/JSNotAnObject.h:
(JSC::JSNotAnObject::JSNotAnObject):
* runtime/JSObject.cpp:
(JSC::JSObject::createInheritorID):
(JSC::JSObject::allocatePropertyStorage):
* runtime/JSObject.h:
(JSC::JSObject::propertyStorage):
(JSC::JSNonFinalObject::JSNonFinalObject):
(JSC::JSNonFinalObject::createStructure):
(JSC::JSFinalObject::create):
(JSC::JSFinalObject::createStructure):
(JSC::JSFinalObject::JSFinalObject):
(JSC::JSObject::offsetOfInlineStorage):
(JSC::constructEmptyObject):
(JSC::createEmptyObjectStructure):
(JSC::JSObject::JSObject):
(JSC::JSObject::~JSObject):
(JSC::Structure::isUsingInlineStorage):
* runtime/JSObjectWithGlobalObject.cpp:
(JSC::JSObjectWithGlobalObject::JSObjectWithGlobalObject):
* runtime/JSObjectWithGlobalObject.h:
(JSC::JSObjectWithGlobalObject::JSObjectWithGlobalObject):
* runtime/JSTypeInfo.h:
(JSC::TypeInfo::TypeInfo):
(JSC::TypeInfo::isVanilla):
* runtime/JSVariableObject.h:
(JSC::JSVariableObject::JSVariableObject):
* runtime/JSWrapperObject.h:
(JSC::JSWrapperObject::JSWrapperObject):
* runtime/ObjectConstructor.cpp:
(JSC::constructObject):
* runtime/ObjectPrototype.cpp:
(JSC::ObjectPrototype::ObjectPrototype):
* runtime/ObjectPrototype.h:
* runtime/StrictEvalActivation.cpp:
(JSC::StrictEvalActivation::StrictEvalActivation):
* runtime/StrictEvalActivation.h:
* runtime/Structure.cpp:
(JSC::Structure::Structure):
(JSC::Structure::growPropertyStorageCapacity):

Source/JavaScriptGlue: 

* UserObjectImp.cpp:
* UserObjectImp.h:
    Update JSObject -> JSNonFinalObject.

Source/WebCore: 

* bindings/js/JSDOMWindowShell.h:
    Update JSObject -> JSNonFinalObject.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@78732 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e463f309
......@@ -79,7 +79,7 @@ JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data)
APIEntryShim entryShim(exec);
if (!jsClass)
return toRef(new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure())); // slightly more efficient
return toRef(constructEmptyObject(exec));
JSCallbackObject<JSObjectWithGlobalObject>* object = new (exec) JSCallbackObject<JSObjectWithGlobalObject>(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), jsClass, data);
if (JSObject* prototype = jsClass->prototype(exec))
......
2011-02-15 Gavin Barraclough <barraclough@apple.com>
Reviewed by Geoff Garen.
Bug 54524 - Allow JSObject to fully utilize cell's capacity for inline storage.
Currently JSObject is both directly instantiated for regular JS objects, and
derived to implement subtypes. A consequence of this is that we need to ensure
that sufficient space from the cell is left unused and available for any data
members that will be introduced by subclasses of JSObject. By restructuring
the internal storage array out of JSObject we can increase the size in the
internal storage for regular objects.
Add classes JSFinalObject and JSNonFinalObject. JSNonFinalObject retains as
much additional capacity as is currently available to allow for data members
in subclasses. JSFinalObject utilizes all available space for internal storage,
and only allows construction through JSFinalObject::create().
The additional storage made available in the JSObject means that we need no
longer rely on a union of the internal storage with a pointer to storage that
is only valid for external storage. This means we can go back to always having
a valid pointer to property storage, regardless of whether this is internal or
external. This simplifies some cases of access to the array from C code, and
significantly simplifies JIT access, since repatching no longer needs to be
able to change between a load of the storage pointer / a LEA of the internal
storage.
* API/JSObjectRef.cpp:
(JSObjectMake):
* assembler/ARMAssembler.h:
* assembler/ARMv7Assembler.h:
* assembler/AbstractMacroAssembler.h:
(JSC::AbstractMacroAssembler::repatchPointer):
* assembler/MIPSAssembler.h:
* assembler/MacroAssemblerARM.h:
* assembler/MacroAssemblerARMv7.h:
* assembler/MacroAssemblerMIPS.h:
* assembler/MacroAssemblerX86.h:
* assembler/MacroAssemblerX86_64.h:
* assembler/RepatchBuffer.h:
* assembler/X86Assembler.h:
* debugger/DebuggerActivation.cpp:
(JSC::DebuggerActivation::DebuggerActivation):
* debugger/DebuggerActivation.h:
* interpreter/Interpreter.cpp:
(JSC::Interpreter::privateExecute):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_resolve_global):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_resolve_global):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::compileGetDirectOffset):
(JSC::JIT::emit_op_get_by_pname):
(JSC::JIT::compileGetByIdHotPath):
(JSC::JIT::emit_op_put_by_id):
(JSC::JIT::compilePutDirectOffset):
(JSC::JIT::patchGetByIdSelf):
(JSC::JIT::patchPutByIdReplace):
(JSC::JIT::privateCompileGetByIdProto):
(JSC::JIT::privateCompileGetByIdSelfList):
(JSC::JIT::privateCompileGetByIdProtoList):
(JSC::JIT::privateCompileGetByIdChainList):
(JSC::JIT::privateCompileGetByIdChain):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::compileGetByIdHotPath):
(JSC::JIT::emit_op_put_by_id):
(JSC::JIT::compilePutDirectOffset):
(JSC::JIT::compileGetDirectOffset):
(JSC::JIT::patchGetByIdSelf):
(JSC::JIT::patchPutByIdReplace):
(JSC::JIT::privateCompileGetByIdProto):
(JSC::JIT::privateCompileGetByIdSelfList):
(JSC::JIT::privateCompileGetByIdProtoList):
(JSC::JIT::privateCompileGetByIdChainList):
(JSC::JIT::privateCompileGetByIdChain):
(JSC::JIT::emit_op_get_by_pname):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* runtime/Arguments.h:
(JSC::Arguments::Arguments):
* runtime/ErrorInstance.cpp:
(JSC::ErrorInstance::ErrorInstance):
* runtime/ErrorInstance.h:
* runtime/ExceptionHelpers.cpp:
(JSC::InterruptedExecutionError::InterruptedExecutionError):
(JSC::TerminatedExecutionError::TerminatedExecutionError):
* runtime/JSArray.cpp:
(JSC::JSArray::JSArray):
* runtime/JSArray.h:
* runtime/JSByteArray.cpp:
(JSC::JSByteArray::JSByteArray):
* runtime/JSByteArray.h:
(JSC::JSByteArray::JSByteArray):
* runtime/JSFunction.cpp:
(JSC::JSFunction::getOwnPropertySlot):
* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::JSGlobalData):
* runtime/JSGlobalObject.h:
(JSC::constructEmptyObject):
* runtime/JSNotAnObject.h:
(JSC::JSNotAnObject::JSNotAnObject):
* runtime/JSObject.cpp:
(JSC::JSObject::createInheritorID):
(JSC::JSObject::allocatePropertyStorage):
* runtime/JSObject.h:
(JSC::JSObject::propertyStorage):
(JSC::JSNonFinalObject::JSNonFinalObject):
(JSC::JSNonFinalObject::createStructure):
(JSC::JSFinalObject::create):
(JSC::JSFinalObject::createStructure):
(JSC::JSFinalObject::JSFinalObject):
(JSC::JSObject::offsetOfInlineStorage):
(JSC::constructEmptyObject):
(JSC::createEmptyObjectStructure):
(JSC::JSObject::JSObject):
(JSC::JSObject::~JSObject):
(JSC::Structure::isUsingInlineStorage):
* runtime/JSObjectWithGlobalObject.cpp:
(JSC::JSObjectWithGlobalObject::JSObjectWithGlobalObject):
* runtime/JSObjectWithGlobalObject.h:
(JSC::JSObjectWithGlobalObject::JSObjectWithGlobalObject):
* runtime/JSTypeInfo.h:
(JSC::TypeInfo::TypeInfo):
(JSC::TypeInfo::isVanilla):
* runtime/JSVariableObject.h:
(JSC::JSVariableObject::JSVariableObject):
* runtime/JSWrapperObject.h:
(JSC::JSWrapperObject::JSWrapperObject):
* runtime/ObjectConstructor.cpp:
(JSC::constructObject):
* runtime/ObjectPrototype.cpp:
(JSC::ObjectPrototype::ObjectPrototype):
* runtime/ObjectPrototype.h:
* runtime/StrictEvalActivation.cpp:
(JSC::StrictEvalActivation::StrictEvalActivation):
* runtime/StrictEvalActivation.h:
* runtime/Structure.cpp:
(JSC::Structure::Structure):
(JSC::Structure::growPropertyStorageCapacity):
2011-02-16 Oliver Hunt <oliver@apple.com>
Reviewed by Geoff Garen.
......
......@@ -786,17 +786,6 @@ namespace JSC {
patchPointerInternal(reinterpret_cast<intptr_t>(from), to);
}
static void repatchLoadPtrToLEA(void* from)
{
// On arm, this is a patch from LDR to ADD. It is restricted conversion,
// from special case to special case, altough enough for its purpose
ARMWord* insn = reinterpret_cast<ARMWord*>(from);
ASSERT((*insn & 0x0ff00f00) == 0x05900000);
*insn = (*insn & 0xf00ff0ff) | 0x02800000;
ExecutableAllocator::cacheFlush(insn, sizeof(ARMWord));
}
// Linkers
static intptr_t getAbsoluteJumpAddress(void* base, int offset = 0)
{
......
......@@ -1845,22 +1845,6 @@ public:
setPointer(where, value);
}
static void repatchLoadPtrToLEA(void* where)
{
ASSERT(!(reinterpret_cast<intptr_t>(where) & 1));
uint16_t* loadOp = reinterpret_cast<uint16_t*>(where) + 4;
ASSERT((loadOp[0] & 0xfff0) == OP_LDR_reg_T2);
ASSERT((loadOp[1] & 0x0ff0) == 0);
int rn = loadOp[0] & 0xf;
int rt = loadOp[1] >> 12;
int rm = loadOp[1] & 0xf;
loadOp[0] = OP_ADD_reg_T3 | rn;
loadOp[1] = rt << 8 | rm;
ExecutableAllocator::cacheFlush(loadOp, sizeof(uint32_t));
}
private:
// VFP operations commonly take one or more 5-bit operands, typically representing a
// floating point register number. This will commonly be encoded in the instruction
......
......@@ -535,11 +535,6 @@ protected:
{
AssemblerType::repatchPointer(dataLabelPtr.dataLocation(), value);
}
static void repatchLoadPtrToLEA(CodeLocationInstruction instruction)
{
AssemblerType::repatchLoadPtrToLEA(instruction.dataLocation());
}
};
} // namespace JSC
......
......@@ -811,19 +811,7 @@ public:
repatchInt32(from, reinterpret_cast<int32_t>(to));
}
static void repatchLoadPtrToLEA(void* from)
{
MIPSWord* insn = reinterpret_cast<MIPSWord*>(from);
insn = insn + 3;
ASSERT((*insn & 0xfc000000) == 0x8c000000); // lw
/* lw -> addiu */
*insn = 0x24000000 | (*insn & 0x03ffffff);
ExecutableAllocator::cacheFlush(insn, sizeof(MIPSWord));
}
private:
/* Update each jump in the buffer of newBase. */
void relocateJumps(void* oldBase, void* newBase)
{
......
......@@ -271,13 +271,6 @@ public:
return dataLabel;
}
Label loadPtrWithPatchToLEA(Address address, RegisterID dest)
{
Label label(this);
load32(address, dest);
return label;
}
void load16(BaseIndex address, RegisterID dest)
{
m_assembler.add_r(ARMRegisters::S1, address.base, m_assembler.lsl(address.index, address.scale));
......
......@@ -478,14 +478,6 @@ public:
return label;
}
Label loadPtrWithPatchToLEA(Address address, RegisterID dest)
{
Label label(this);
moveFixedWidthEncoding(Imm32(address.offset), dataTempRegister);
load32(ArmAddress(address.base, dataTempRegister), dest);
return label;
}
void load16(BaseIndex address, RegisterID dest)
{
m_assembler.ldrh(dest, makeBaseIndexBase(address), address.index, address.scale);
......
......@@ -608,23 +608,6 @@ public:
return dataLabel;
}
Label loadPtrWithPatchToLEA(Address address, RegisterID dest)
{
m_fixedWidth = true;
/*
lui addrTemp, address.offset >> 16
ori addrTemp, addrTemp, address.offset & 0xffff
addu addrTemp, addrTemp, address.base
lw dest, 0(addrTemp)
*/
Label label(this);
move(Imm32(address.offset), addrTempRegister);
m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
m_assembler.lw(dest, addrTempRegister, 0);
m_fixedWidth = false;
return label;
}
/* Need to use zero-extened load half-word for load16. */
void load16(ImplicitAddress address, RegisterID dest)
{
......
......@@ -162,13 +162,6 @@ public:
return DataLabelPtr(this);
}
Label loadPtrWithPatchToLEA(Address address, RegisterID dest)
{
Label label(this);
load32(address, dest);
return label;
}
bool supportsFloatingPoint() const { return m_isSSE2Present; }
// See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate()
bool supportsFloatingPointTruncate() const { return m_isSSE2Present; }
......
......@@ -417,13 +417,6 @@ public:
return MacroAssemblerX86Common::branchTest8(cond, BaseIndex(scratchRegister, address.base, TimesOne), mask);
}
Label loadPtrWithPatchToLEA(Address address, RegisterID dest)
{
Label label(this);
loadPtr(address, dest);
return label;
}
bool supportsFloatingPoint() const { return true; }
// See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate()
bool supportsFloatingPointTruncate() const { return true; }
......
......@@ -92,11 +92,6 @@ public:
MacroAssembler::repatchPointer(dataLabelPtr, value);
}
void repatchLoadPtrToLEA(CodeLocationInstruction instruction)
{
MacroAssembler::repatchLoadPtrToLEA(instruction);
}
void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label)
{
relink(CodeLocationCall(CodePtr(returnAddress)), label);
......
......@@ -1580,16 +1580,6 @@ public:
setPointer(where, value);
}
static void repatchLoadPtrToLEA(void* where)
{
#if CPU(X86_64)
// On x86-64 pointer memory accesses require a 64-bit operand, and as such a REX prefix.
// Skip over the prefix byte.
where = reinterpret_cast<char*>(where) + 1;
#endif
*reinterpret_cast<unsigned char*>(where) = static_cast<unsigned char>(OP_LEA);
}
static unsigned getCallReturnOffset(JmpSrc call)
{
ASSERT(call.m_offset >= 0);
......
......@@ -31,7 +31,7 @@
namespace JSC {
DebuggerActivation::DebuggerActivation(JSGlobalData& globalData, JSObject* activation)
: JSObject(DebuggerActivation::createStructure(jsNull()))
: JSNonFinalObject(DebuggerActivation::createStructure(jsNull()))
{
ASSERT(activation);
ASSERT(activation->isActivationObject());
......
......@@ -32,7 +32,7 @@ namespace JSC {
class JSActivation;
class DebuggerActivation : public JSObject {
class DebuggerActivation : public JSNonFinalObject {
public:
DebuggerActivation(JSGlobalData&, JSObject*);
......
......@@ -4279,7 +4279,7 @@ skip_id_custom_self:
structure = asObject(proto)->inheritorID();
else
structure = constructor->scope().node()->globalObject->emptyObjectStructure();
callFrame->uncheckedR(thisRegister) = JSValue(new (&callFrame->globalData()) JSObject(structure));
callFrame->uncheckedR(thisRegister) = constructEmptyObject(callFrame, structure);
vPC += OPCODE_LENGTH(op_create_this);
NEXT_INSTRUCTION();
......
......@@ -332,8 +332,8 @@ namespace JSC {
void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false);
#endif
void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, Structure* structure, size_t cachedOffset);
void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset);
void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset);
void compileGetDirectOffset(JSObject* base, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset);
void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID offset);
void compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, Structure* structure, size_t cachedOffset);
// Arithmetic opcode helpers
......@@ -344,15 +344,11 @@ namespace JSC {
#if CPU(X86)
// These architecture specific value are used to enable patching - see comment on op_put_by_id.
static const int patchOffsetPutByIdStructure = 7;
static const int patchOffsetPutByIdExternalLoad = 13;
static const int patchLengthPutByIdExternalLoad = 3;
static const int patchOffsetPutByIdPropertyMapOffset1 = 22;
static const int patchOffsetPutByIdPropertyMapOffset2 = 28;
// These architecture specific value are used to enable patching - see comment on op_get_by_id.
static const int patchOffsetGetByIdStructure = 7;
static const int patchOffsetGetByIdBranchToSlowCase = 13;
static const int patchOffsetGetByIdExternalLoad = 13;
static const int patchLengthGetByIdExternalLoad = 3;
static const int patchOffsetGetByIdPropertyMapOffset1 = 22;
static const int patchOffsetGetByIdPropertyMapOffset2 = 28;
static const int patchOffsetGetByIdPutResult = 28;
......@@ -369,15 +365,11 @@ namespace JSC {
#elif CPU(ARM_TRADITIONAL)
// These architecture specific value are used to enable patching - see comment on op_put_by_id.
static const int patchOffsetPutByIdStructure = 4;
static const int patchOffsetPutByIdExternalLoad = 16;
static const int patchLengthPutByIdExternalLoad = 4;
static const int patchOffsetPutByIdPropertyMapOffset1 = 20;
static const int patchOffsetPutByIdPropertyMapOffset2 = 28;
// These architecture specific value are used to enable patching - see comment on op_get_by_id.
static const int patchOffsetGetByIdStructure = 4;
static const int patchOffsetGetByIdBranchToSlowCase = 16;
static const int patchOffsetGetByIdExternalLoad = 16;
static const int patchLengthGetByIdExternalLoad = 4;
static const int patchOffsetGetByIdPropertyMapOffset1 = 20;
static const int patchOffsetGetByIdPropertyMapOffset2 = 28;
static const int patchOffsetGetByIdPutResult = 36;
......@@ -410,15 +402,11 @@ namespace JSC {
#elif CPU(ARM_THUMB2)
// These architecture specific value are used to enable patching - see comment on op_put_by_id.
static const int patchOffsetPutByIdStructure = 10;
static const int patchOffsetPutByIdExternalLoad = 26;
static const int patchLengthPutByIdExternalLoad = 12;
static const int patchOffsetPutByIdPropertyMapOffset1 = 46;
static const int patchOffsetPutByIdPropertyMapOffset2 = 58;
// These architecture specific value are used to enable patching - see comment on op_get_by_id.
static const int patchOffsetGetByIdStructure = 10;
static const int patchOffsetGetByIdBranchToSlowCase = 26;
static const int patchOffsetGetByIdExternalLoad = 26;
static const int patchLengthGetByIdExternalLoad = 12;
static const int patchOffsetGetByIdPropertyMapOffset1 = 46;
static const int patchOffsetGetByIdPropertyMapOffset2 = 58;
static const int patchOffsetGetByIdPutResult = 62;
......@@ -451,14 +439,10 @@ namespace JSC {
#elif CPU(MIPS)
#if WTF_MIPS_ISA(1)
static const int patchOffsetPutByIdStructure = 16;
static const int patchOffsetPutByIdExternalLoad = 48;
static const int patchLengthPutByIdExternalLoad = 20;
static const int patchOffsetPutByIdPropertyMapOffset1 = 68;
static const int patchOffsetPutByIdPropertyMapOffset2 = 84;
static const int patchOffsetGetByIdStructure = 16;
static const int patchOffsetGetByIdBranchToSlowCase = 48;
static const int patchOffsetGetByIdExternalLoad = 48;
static const int patchLengthGetByIdExternalLoad = 20;
static const int patchOffsetGetByIdPropertyMapOffset1 = 68;
static const int patchOffsetGetByIdPropertyMapOffset2 = 88;
static const int patchOffsetGetByIdPutResult = 108;
......@@ -473,14 +457,10 @@ namespace JSC {
static const int patchOffsetMethodCheckPutFunction = 88;
#else // WTF_MIPS_ISA(1)
static const int patchOffsetPutByIdStructure = 12;
static const int patchOffsetPutByIdExternalLoad = 44;
static const int patchLengthPutByIdExternalLoad = 16;
static const int patchOffsetPutByIdPropertyMapOffset1 = 60;
static const int patchOffsetPutByIdPropertyMapOffset2 = 76;
static const int patchOffsetGetByIdStructure = 12;
static const int patchOffsetGetByIdBranchToSlowCase = 44;
static const int patchOffsetGetByIdExternalLoad = 44;
static const int patchLengthGetByIdExternalLoad = 16;
static const int patchOffsetGetByIdPropertyMapOffset1 = 60;
static const int patchOffsetGetByIdPropertyMapOffset2 = 76;
static const int patchOffsetGetByIdPutResult = 92;
......@@ -551,21 +531,17 @@ namespace JSC {
void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false);
#endif
void compileGetDirectOffset(RegisterID base, RegisterID result, Structure* structure, size_t cachedOffset);
void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID result, size_t cachedOffset);
void compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch);
void compileGetDirectOffset(JSObject* base, RegisterID result, size_t cachedOffset);
void compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID offset, RegisterID scratch);
void compilePutDirectOffset(RegisterID base, RegisterID value, Structure* structure, size_t cachedOffset);
#if CPU(X86_64)
// These architecture specific value are used to enable patching - see comment on op_put_by_id.
static const int patchOffsetPutByIdStructure = 10;
static const int patchOffsetPutByIdExternalLoad = 20;
static const int patchLengthPutByIdExternalLoad = 4;
static const int patchOffsetPutByIdPropertyMapOffset = 31;
// These architecture specific value are used to enable patching - see comment on op_get_by_id.
static const int patchOffsetGetByIdStructure = 10;
static const int patchOffsetGetByIdBranchToSlowCase = 20;
static const int patchOffsetGetByIdExternalLoad = 20;
static const int patchLengthGetByIdExternalLoad = 4;
static const int patchOffsetGetByIdPropertyMapOffset = 31;
static const int patchOffsetGetByIdPutResult = 31;
#if ENABLE(OPCODE_SAMPLING)
......@@ -581,14 +557,10 @@ namespace JSC {
#elif CPU(X86)
// These architecture specific value are used to enable patching - see comment on op_put_by_id.
static const int patchOffsetPutByIdStructure = 7;
static const int patchOffsetPutByIdExternalLoad = 13;
static const int patchLengthPutByIdExternalLoad = 3;
static const int patchOffsetPutByIdPropertyMapOffset = 22;
// These architecture specific value are used to enable patching - see comment on op_get_by_id.
static const int patchOffsetGetByIdStructure = 7;
static const int patchOffsetGetByIdBranchToSlowCase = 13;
static const int patchOffsetGetByIdExternalLoad = 13;
static const int patchLengthGetByIdExternalLoad = 3;
static const int patchOffsetGetByIdPropertyMapOffset = 22;
static const int patchOffsetGetByIdPutResult = 22;
#if ENABLE(OPCODE_SAMPLING)
......@@ -604,14 +576,10 @@ namespace JSC {
#elif CPU(ARM_THUMB2)
// These architecture specific value are used to enable patching - see comment on op_put_by_id.
static const int patchOffsetPutByIdStructure = 10;
static const int patchOffsetPutByIdExternalLoad = 26;
static const int patchLengthPutByIdExternalLoad = 12;
static const int patchOffsetPutByIdPropertyMapOffset = 46;
// These architecture specific value are used to enable patching - see comment on op_get_by_id.
static const int patchOffsetGetByIdStructure = 10;
static const int patchOffsetGetByIdBranchToSlowCase = 26;
static const int patchOffsetGetByIdExternalLoad = 26;
static const int patchLengthGetByIdExternalLoad = 12;
static const int patchOffsetGetByIdPropertyMapOffset = 46;
static const int patchOffsetGetByIdPutResult = 50;
#if ENABLE(OPCODE_SAMPLING)
......@@ -627,14 +595,10 @@ namespace JSC {
#elif CPU(ARM_TRADITIONAL)
// These architecture specific value are used to enable patching - see comment on op_put_by_id.
static const int patchOffsetPutByIdStructure = 4;
static const int patchOffsetPutByIdExternalLoad = 16;
static const int patchLengthPutByIdExternalLoad = 4;
static const int patchOffsetPutByIdPropertyMapOffset = 20;
// These architecture specific value are used to enable patching - see comment on op_get_by_id.
static const int patchOffsetGetByIdStructure = 4;
static const int patchOffsetGetByIdBranchToSlowCase = 16;
static const int patchOffsetGetByIdExternalLoad = 16;
static const int patchLengthGetByIdExternalLoad = 4;
static const int patchOffsetGetByIdPropertyMapOffset = 20;
static const int patchOffsetGetByIdPutResult = 28;
#if ENABLE(OPCODE_SAMPLING)
......@@ -666,13 +630,9 @@ namespace JSC {
#elif CPU(MIPS)
#if WTF_MIPS_ISA(1)
static const int patchOffsetPutByIdStructure = 16;
static const int patchOffsetPutByIdExternalLoad = 48;
static const int patchLengthPutByIdExternalLoad = 20;
static const int patchOffsetPutByIdPropertyMapOffset = 68;
static const int patchOffsetGetByIdStructure = 16;
static const int patchOffsetGetByIdBranchToSlowCase = 48;
static const int patchOffsetGetByIdExternalLoad = 48;
static const int patchLengthGetByIdExternalLoad = 20;
static const int patchOffsetGetByIdPropertyMapOffset = 68;
static const int patchOffsetGetByIdPutResult = 88;
#if ENABLE(OPCODE_SAMPLING)
......@@ -686,13 +646,9 @@ namespace JSC {
static const int patchOffsetMethodCheckPutFunction = 88;
#else // WTF_MIPS_ISA(1)
static const int patchOffsetPutByIdStructure = 12;
static const int patchOffsetPutByIdExternalLoad = 44;
static const int patchLengthPutByIdExternalLoad = 16;
static const int patchOffsetPutByIdPropertyMapOffset = 60;
static const int patchOffsetGetByIdStructure = 12;
static const int patchOffsetGetByIdBranchToSlowCase = 44;
static const int patchOffsetGetByIdExternalLoad = 44;
static const int patchLengthGetByIdExternalLoad = 16;
static const int patchOffsetGetByIdPropertyMapOffset = 60;
static const int patchOffsetGetByIdPutResult = 76;
#if ENABLE(OPCODE_SAMPLING)
......
......@@ -689,7 +689,7 @@ void JIT::emit_op_resolve_global(Instruction* currentInstruction, bool)
// Load cached property
// Assume that the global object always uses external storage.
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_externalStorage)), regT0);
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_propertyStorage)), regT0);
load32(offsetAddr, regT1);
loadPtr(BaseIndex(regT0, regT1, ScalePtr), regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
......
......@@ -804,7 +804,7 @@ void JIT::emit_op_resolve_global(Instruction* currentInstruction, bool dynamic)
addSlowCase(branchPtr(NotEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure))));
// Load property.
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_externalStorage)), regT2);
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_propertyStorage)), regT2);
load32(offsetAddr, regT3);
load32(BaseIndex(regT2, regT3, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload
load32(BaseIndex(regT2, regT3, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag
......
......@@ -138,18 +138,10 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas
stubCall.call(dst);
}
void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch)
void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID offset, RegisterID scratch)
{
ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t));
ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t));
Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity));
loadPtr(BaseIndex(base, offset, ScalePtr, OBJECT_OFFSETOF(JSObject, m_inlineStorage)), result);
Jump finishedLoad = jump();
notUsingInlineStorage.link(this);
loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), scratch);
loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), scratch);
loadPtr(BaseIndex(scratch, offset, ScalePtr, 0), result);
finishedLoad.link(this);
}
void JIT::emit_op_get_by_pname(Instruction* currentInstruction)
......@@ -172,7 +164,7 @@ void JIT::emit_op_get_by_pname(Instruction* currentInstruction)
load32(addressFor(i), regT3);
sub32(Imm32(1), regT3);