Inline property storage should not be wasted when it is exhausted
https://bugs.webkit.org/show_bug.cgi?id=90347

Reviewed by Gavin Barraclough.
        
Previously, if we switched an object from using inline storage to out-of-line
storage, we would abandon the inline storage. This would have two main implications:
(i) all accesses to the object, even for properties that were previously in inline
storage, must now take an extra indirection; and (ii) we waste a non-trivial amount
of space since we must allocate additional out-of-line storage to hold properties
that would have fit in the inline storage. There's also the copying cost when
switching to out-of-line storage - we must copy all inline properties into ouf-of-line
storage.
        
This patch changes the way that object property storage works so that we can use both
inline and out-of-line storage concurrently. This is accomplished by introducing a
new notion of property offset. This PropertyOffset is a 32-bit signed integer and it
behaves as follows:
        
offset == -1: invalid offset, indicating a property that does not exist.
        
0 <= offset <= inlineStorageCapacity: offset into inline storage.
        
inlineStorageCapacity < offset: offset into out-of-line storage.
        
Because non-final objects don't have inline storage, the only valid PropertyOffsets
for those objects' properties are -1 or > inlineStorageCapacity.
        
This now means that the decision to use inline or out-of-line storage for an access is
made based on the offset, rather than the structure. It also means that any access
where the offset is a variable must have an extra branch, unless the type of the
object is also known (if it's known to be a non-final object then we can just assert
that the offset is >= inlineStorageCapacity).
        
This looks like a big Kraken speed-up and a slight V8 speed-up.

* GNUmakefile.list.am:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* assembler/ARMv7Assembler.h:
(ARMv7Assembler):
(JSC::ARMv7Assembler::ldrWide8BitImmediate):
(JSC::ARMv7Assembler::replaceWithLoad):
(JSC::ARMv7Assembler::replaceWithAddressComputation):
* assembler/AbstractMacroAssembler.h:
(AbstractMacroAssembler):
(ConvertibleLoadLabel):
(JSC::AbstractMacroAssembler::ConvertibleLoadLabel::ConvertibleLoadLabel):
(JSC::AbstractMacroAssembler::ConvertibleLoadLabel::isSet):
(JSC::AbstractMacroAssembler::labelIgnoringWatchpoints):
(JSC::AbstractMacroAssembler::replaceWithLoad):
(JSC::AbstractMacroAssembler::replaceWithAddressComputation):
* assembler/CodeLocation.h:
(JSC):
(CodeLocationCommon):
(CodeLocationConvertibleLoad):
(JSC::CodeLocationConvertibleLoad::CodeLocationConvertibleLoad):
(JSC::CodeLocationCommon::convertibleLoadAtOffset):
* assembler/LinkBuffer.cpp:
(JSC::LinkBuffer::finalizeCodeWithDisassembly):
* assembler/LinkBuffer.h:
(LinkBuffer):
(JSC::LinkBuffer::locationOf):
* assembler/MacroAssemblerARMv7.h:
(MacroAssemblerARMv7):
(JSC::MacroAssemblerARMv7::convertibleLoadPtr):
* assembler/MacroAssemblerX86.h:
(JSC::MacroAssemblerX86::convertibleLoadPtr):
(MacroAssemblerX86):
* assembler/MacroAssemblerX86_64.h:
(JSC::MacroAssemblerX86_64::convertibleLoadPtr):
(MacroAssemblerX86_64):
* assembler/RepatchBuffer.h:
(RepatchBuffer):
(JSC::RepatchBuffer::replaceWithLoad):
(JSC::RepatchBuffer::replaceWithAddressComputation):
(JSC::RepatchBuffer::setLoadInstructionIsActive):
* assembler/X86Assembler.h:
(JSC::X86Assembler::replaceWithLoad):
(X86Assembler):
(JSC::X86Assembler::replaceWithAddressComputation):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::printGetByIdOp):
(JSC::CodeBlock::dump):
(JSC::CodeBlock::finalizeUnconditionally):
* bytecode/GetByIdStatus.cpp:
(JSC::GetByIdStatus::computeFromLLInt):
(JSC::GetByIdStatus::computeForChain):
(JSC::GetByIdStatus::computeFor):
* bytecode/GetByIdStatus.h:
(JSC::GetByIdStatus::GetByIdStatus):
(JSC::GetByIdStatus::offset):
(GetByIdStatus):
* bytecode/Opcode.h:
(JSC):
(JSC::padOpcodeName):
* bytecode/PutByIdStatus.cpp:
(JSC::PutByIdStatus::computeFromLLInt):
(JSC::PutByIdStatus::computeFor):
* bytecode/PutByIdStatus.h:
(JSC::PutByIdStatus::PutByIdStatus):
(JSC::PutByIdStatus::offset):
(PutByIdStatus):
* bytecode/ResolveGlobalStatus.cpp:
(JSC):
(JSC::computeForStructure):
* bytecode/ResolveGlobalStatus.h:
(JSC::ResolveGlobalStatus::ResolveGlobalStatus):
(JSC::ResolveGlobalStatus::offset):
(ResolveGlobalStatus):
* bytecode/StructureSet.h:
(StructureSet):
* bytecode/StructureStubInfo.h:
* dfg/DFGByteCodeParser.cpp:
(ByteCodeParser):
(JSC::DFG::ByteCodeParser::handleGetByOffset):
(JSC::DFG::ByteCodeParser::handleGetById):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.h:
(JSC::DFG::canCompileOpcode):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JSC::DFG::PropertyAccessRecord::PropertyAccessRecord):
(PropertyAccessRecord):
* dfg/DFGRepatch.cpp:
(JSC::DFG::dfgRepatchByIdSelfAccess):
(JSC::DFG::generateProtoChainAccessStub):
(JSC::DFG::tryCacheGetByID):
(JSC::DFG::tryBuildGetByIDList):
(JSC::DFG::tryBuildGetByIDProtoList):
(JSC::DFG::emitPutReplaceStub):
(JSC::DFG::emitPutTransitionStub):
(JSC::DFG::tryCachePutByID):
(JSC::DFG::tryBuildPutByIdList):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::cachedGetById):
(JSC::DFG::SpeculativeJIT::cachedPutById):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::cachedGetById):
(JSC::DFG::SpeculativeJIT::cachedPutById):
(JSC::DFG::SpeculativeJIT::compile):
* heap/MarkStack.cpp:
(JSC::visitChildren):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::tryCacheGetByID):
(JSC::Interpreter::privateExecute):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
(JSC::PropertyStubCompilationInfo::copyToStubInfo):
* jit/JIT.h:
(JSC::PropertyStubCompilationInfo::PropertyStubCompilationInfo):
(JSC::JIT::compileGetByIdProto):
(JSC::JIT::compileGetByIdSelfList):
(JSC::JIT::compileGetByIdProtoList):
(JSC::JIT::compileGetByIdChainList):
(JSC::JIT::compileGetByIdChain):
(JSC::JIT::compilePutByIdTransition):
(JIT):
* jit/JITInlineMethods.h:
(JSC::JIT::emitAllocateBasicJSObject):
* 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_method_check):
(JSC::JIT::compileGetByIdHotPath):
(JSC::JIT::emit_op_put_by_id):
(JSC::JIT::compilePutDirectOffset):
(JSC::JIT::privateCompilePutByIdTransition):
(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::emit_op_method_check):
(JSC::JIT::compileGetByIdHotPath):
(JSC::JIT::emit_op_put_by_id):
(JSC::JIT::compilePutDirectOffset):
(JSC::JIT::compileGetDirectOffset):
(JSC::JIT::privateCompilePutByIdTransition):
(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::JITThunks::tryCacheGetByID):
(JSC::DEFINE_STUB_FUNCTION):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* offlineasm/x86.rb:
* runtime/JSGlobalObject.h:
(JSGlobalObject):
(JSC::JSGlobalObject::functionNameOffset):
* runtime/JSObject.cpp:
(JSC::JSObject::visitChildren):
(JSC):
(JSC::JSFinalObject::visitChildren):
(JSC::JSObject::put):
(JSC::JSObject::deleteProperty):
(JSC::JSObject::getPropertySpecificValue):
(JSC::JSObject::removeDirect):
(JSC::JSObject::growOutOfLineStorage):
(JSC::JSObject::getOwnPropertyDescriptor):
* runtime/JSObject.h:
(JSObject):
(JSC::JSObject::getDirect):
(JSC::JSObject::getDirectLocation):
(JSC::JSObject::hasInlineStorage):
(JSC::JSObject::inlineStorageUnsafe):
(JSC::JSObject::inlineStorage):
(JSC::JSObject::outOfLineStorage):
(JSC::JSObject::locationForOffset):
(JSC::JSObject::offsetForLocation):
(JSC::JSObject::getDirectOffset):
(JSC::JSObject::putDirectOffset):
(JSC::JSObject::putUndefinedAtDirectOffset):
(JSC::JSObject::addressOfOutOfLineStorage):
(JSC::JSObject::finishCreation):
(JSC::JSNonFinalObject::JSNonFinalObject):
(JSC::JSNonFinalObject::finishCreation):
(JSFinalObject):
(JSC::JSFinalObject::finishCreation):
(JSC::JSFinalObject::JSFinalObject):
(JSC::JSObject::offsetOfOutOfLineStorage):
(JSC::JSObject::setOutOfLineStorage):
(JSC::JSObject::JSObject):
(JSC):
(JSC::JSCell::fastGetOwnProperty):
(JSC::JSObject::putDirectInternal):
(JSC::JSObject::setStructureAndReallocateStorageIfNecessary):
(JSC::JSObject::putDirectWithoutTransition):
(JSC::offsetRelativeToPatchedStorage):
(JSC::indexRelativeToBase):
(JSC::offsetRelativeToBase):
* runtime/JSPropertyNameIterator.cpp:
(JSC::JSPropertyNameIterator::create):
* runtime/JSPropertyNameIterator.h:
(JSPropertyNameIterator):
(JSC::JSPropertyNameIterator::getOffset):
(JSC::JSPropertyNameIterator::finishCreation):
* runtime/JSValue.cpp:
(JSC::JSValue::putToPrimitive):
* runtime/Operations.h:
(JSC::normalizePrototypeChain):
* runtime/Options.cpp:
(JSC):
(JSC::Options::initialize):
* runtime/PropertyMapHashTable.h:
(PropertyMapEntry):
(JSC::PropertyMapEntry::PropertyMapEntry):
(PropertyTable):
(JSC::PropertyTable::PropertyTable):
(JSC::PropertyTable::getDeletedOffset):
(JSC::PropertyTable::addDeletedOffset):
(JSC::PropertyTable::nextOffset):
(JSC):
(JSC::PropertyTable::sizeInMemory):
* runtime/PropertyOffset.h: Added.
(JSC):
(JSC::checkOffset):
(JSC::validateOffset):
(JSC::isValidOffset):
(JSC::isInlineOffset):
(JSC::isOutOfLineOffset):
(JSC::offsetInInlineStorage):
(JSC::offsetInOutOfLineStorage):
(JSC::offsetInRespectiveStorage):
(JSC::numberOfOutOfLineSlotsForLastOffset):
(JSC::numberOfSlotsForLastOffset):
(JSC::nextPropertyOffsetFor):
(JSC::firstPropertyOffsetFor):
* runtime/PropertySlot.h:
(JSC::PropertySlot::cachedOffset):
(JSC::PropertySlot::setValue):
(JSC::PropertySlot::setCacheableGetterSlot):
(JSC::PropertySlot::clearOffset):
* runtime/PutPropertySlot.h:
(JSC::PutPropertySlot::setExistingProperty):
(JSC::PutPropertySlot::setNewProperty):
(JSC::PutPropertySlot::cachedOffset):
(PutPropertySlot):
* runtime/Structure.cpp:
(JSC::Structure::Structure):
(JSC::Structure::materializePropertyMap):
(JSC::nextOutOfLineStorageCapacity):
(JSC::Structure::growOutOfLineCapacity):
(JSC::Structure::suggestedNewOutOfLineStorageCapacity):
(JSC::Structure::addPropertyTransitionToExistingStructure):
(JSC::Structure::addPropertyTransition):
(JSC::Structure::removePropertyTransition):
(JSC::Structure::flattenDictionaryStructure):
(JSC::Structure::addPropertyWithoutTransition):
(JSC::Structure::removePropertyWithoutTransition):
(JSC::Structure::copyPropertyTableForPinning):
(JSC::Structure::get):
(JSC::Structure::putSpecificValue):
(JSC::Structure::remove):
* runtime/Structure.h:
(Structure):
(JSC::Structure::putWillGrowOutOfLineStorage):
(JSC::Structure::previousID):
(JSC::Structure::outOfLineCapacity):
(JSC::Structure::outOfLineSizeForKnownFinalObject):
(JSC::Structure::outOfLineSizeForKnownNonFinalObject):
(JSC::Structure::outOfLineSize):
(JSC::Structure::hasInlineStorage):
(JSC::Structure::inlineCapacity):
(JSC::Structure::inlineSizeForKnownFinalObject):
(JSC::Structure::inlineSize):
(JSC::Structure::totalStorageSize):
(JSC::Structure::totalStorageCapacity):
(JSC::Structure::firstValidOffset):
(JSC::Structure::lastValidOffset):
(JSC::Structure::isValidOffset):
(JSC::Structure::isEmpty):
(JSC::Structure::transitionCount):
(JSC::Structure::get):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@121925 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index e6e9639..8373d91 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,341 @@
+2012-07-04  Filip Pizlo  <fpizlo@apple.com>
+
+        Inline property storage should not be wasted when it is exhausted
+        https://bugs.webkit.org/show_bug.cgi?id=90347
+
+        Reviewed by Gavin Barraclough.
+        
+        Previously, if we switched an object from using inline storage to out-of-line
+        storage, we would abandon the inline storage. This would have two main implications:
+        (i) all accesses to the object, even for properties that were previously in inline
+        storage, must now take an extra indirection; and (ii) we waste a non-trivial amount
+        of space since we must allocate additional out-of-line storage to hold properties
+        that would have fit in the inline storage. There's also the copying cost when
+        switching to out-of-line storage - we must copy all inline properties into ouf-of-line
+        storage.
+        
+        This patch changes the way that object property storage works so that we can use both
+        inline and out-of-line storage concurrently. This is accomplished by introducing a
+        new notion of property offset. This PropertyOffset is a 32-bit signed integer and it
+        behaves as follows:
+        
+        offset == -1: invalid offset, indicating a property that does not exist.
+        
+        0 <= offset <= inlineStorageCapacity: offset into inline storage.
+        
+        inlineStorageCapacity < offset: offset into out-of-line storage.
+        
+        Because non-final objects don't have inline storage, the only valid PropertyOffsets
+        for those objects' properties are -1 or > inlineStorageCapacity.
+        
+        This now means that the decision to use inline or out-of-line storage for an access is
+        made based on the offset, rather than the structure. It also means that any access
+        where the offset is a variable must have an extra branch, unless the type of the
+        object is also known (if it's known to be a non-final object then we can just assert
+        that the offset is >= inlineStorageCapacity).
+        
+        This looks like a big Kraken speed-up and a slight V8 speed-up.
+
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * assembler/ARMv7Assembler.h:
+        (ARMv7Assembler):
+        (JSC::ARMv7Assembler::ldrWide8BitImmediate):
+        (JSC::ARMv7Assembler::replaceWithLoad):
+        (JSC::ARMv7Assembler::replaceWithAddressComputation):
+        * assembler/AbstractMacroAssembler.h:
+        (AbstractMacroAssembler):
+        (ConvertibleLoadLabel):
+        (JSC::AbstractMacroAssembler::ConvertibleLoadLabel::ConvertibleLoadLabel):
+        (JSC::AbstractMacroAssembler::ConvertibleLoadLabel::isSet):
+        (JSC::AbstractMacroAssembler::labelIgnoringWatchpoints):
+        (JSC::AbstractMacroAssembler::replaceWithLoad):
+        (JSC::AbstractMacroAssembler::replaceWithAddressComputation):
+        * assembler/CodeLocation.h:
+        (JSC):
+        (CodeLocationCommon):
+        (CodeLocationConvertibleLoad):
+        (JSC::CodeLocationConvertibleLoad::CodeLocationConvertibleLoad):
+        (JSC::CodeLocationCommon::convertibleLoadAtOffset):
+        * assembler/LinkBuffer.cpp:
+        (JSC::LinkBuffer::finalizeCodeWithDisassembly):
+        * assembler/LinkBuffer.h:
+        (LinkBuffer):
+        (JSC::LinkBuffer::locationOf):
+        * assembler/MacroAssemblerARMv7.h:
+        (MacroAssemblerARMv7):
+        (JSC::MacroAssemblerARMv7::convertibleLoadPtr):
+        * assembler/MacroAssemblerX86.h:
+        (JSC::MacroAssemblerX86::convertibleLoadPtr):
+        (MacroAssemblerX86):
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::convertibleLoadPtr):
+        (MacroAssemblerX86_64):
+        * assembler/RepatchBuffer.h:
+        (RepatchBuffer):
+        (JSC::RepatchBuffer::replaceWithLoad):
+        (JSC::RepatchBuffer::replaceWithAddressComputation):
+        (JSC::RepatchBuffer::setLoadInstructionIsActive):
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::replaceWithLoad):
+        (X86Assembler):
+        (JSC::X86Assembler::replaceWithAddressComputation):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::printGetByIdOp):
+        (JSC::CodeBlock::dump):
+        (JSC::CodeBlock::finalizeUnconditionally):
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeFromLLInt):
+        (JSC::GetByIdStatus::computeForChain):
+        (JSC::GetByIdStatus::computeFor):
+        * bytecode/GetByIdStatus.h:
+        (JSC::GetByIdStatus::GetByIdStatus):
+        (JSC::GetByIdStatus::offset):
+        (GetByIdStatus):
+        * bytecode/Opcode.h:
+        (JSC):
+        (JSC::padOpcodeName):
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeFromLLInt):
+        (JSC::PutByIdStatus::computeFor):
+        * bytecode/PutByIdStatus.h:
+        (JSC::PutByIdStatus::PutByIdStatus):
+        (JSC::PutByIdStatus::offset):
+        (PutByIdStatus):
+        * bytecode/ResolveGlobalStatus.cpp:
+        (JSC):
+        (JSC::computeForStructure):
+        * bytecode/ResolveGlobalStatus.h:
+        (JSC::ResolveGlobalStatus::ResolveGlobalStatus):
+        (JSC::ResolveGlobalStatus::offset):
+        (ResolveGlobalStatus):
+        * bytecode/StructureSet.h:
+        (StructureSet):
+        * bytecode/StructureStubInfo.h:
+        * dfg/DFGByteCodeParser.cpp:
+        (ByteCodeParser):
+        (JSC::DFG::ByteCodeParser::handleGetByOffset):
+        (JSC::DFG::ByteCodeParser::handleGetById):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.h:
+        (JSC::DFG::canCompileOpcode):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::link):
+        * dfg/DFGJITCompiler.h:
+        (JSC::DFG::PropertyAccessRecord::PropertyAccessRecord):
+        (PropertyAccessRecord):
+        * dfg/DFGRepatch.cpp:
+        (JSC::DFG::dfgRepatchByIdSelfAccess):
+        (JSC::DFG::generateProtoChainAccessStub):
+        (JSC::DFG::tryCacheGetByID):
+        (JSC::DFG::tryBuildGetByIDList):
+        (JSC::DFG::tryBuildGetByIDProtoList):
+        (JSC::DFG::emitPutReplaceStub):
+        (JSC::DFG::emitPutTransitionStub):
+        (JSC::DFG::tryCachePutByID):
+        (JSC::DFG::tryBuildPutByIdList):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::cachedGetById):
+        (JSC::DFG::SpeculativeJIT::cachedPutById):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::cachedGetById):
+        (JSC::DFG::SpeculativeJIT::cachedPutById):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * heap/MarkStack.cpp:
+        (JSC::visitChildren):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::tryCacheGetByID):
+        (JSC::Interpreter::privateExecute):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        (JSC::PropertyStubCompilationInfo::copyToStubInfo):
+        * jit/JIT.h:
+        (JSC::PropertyStubCompilationInfo::PropertyStubCompilationInfo):
+        (JSC::JIT::compileGetByIdProto):
+        (JSC::JIT::compileGetByIdSelfList):
+        (JSC::JIT::compileGetByIdProtoList):
+        (JSC::JIT::compileGetByIdChainList):
+        (JSC::JIT::compileGetByIdChain):
+        (JSC::JIT::compilePutByIdTransition):
+        (JIT):
+        * jit/JITInlineMethods.h:
+        (JSC::JIT::emitAllocateBasicJSObject):
+        * 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_method_check):
+        (JSC::JIT::compileGetByIdHotPath):
+        (JSC::JIT::emit_op_put_by_id):
+        (JSC::JIT::compilePutDirectOffset):
+        (JSC::JIT::privateCompilePutByIdTransition):
+        (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::emit_op_method_check):
+        (JSC::JIT::compileGetByIdHotPath):
+        (JSC::JIT::emit_op_put_by_id):
+        (JSC::JIT::compilePutDirectOffset):
+        (JSC::JIT::compileGetDirectOffset):
+        (JSC::JIT::privateCompilePutByIdTransition):
+        (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::JITThunks::tryCacheGetByID):
+        (JSC::DEFINE_STUB_FUNCTION):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * offlineasm/x86.rb:
+        * runtime/JSGlobalObject.h:
+        (JSGlobalObject):
+        (JSC::JSGlobalObject::functionNameOffset):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::visitChildren):
+        (JSC):
+        (JSC::JSFinalObject::visitChildren):
+        (JSC::JSObject::put):
+        (JSC::JSObject::deleteProperty):
+        (JSC::JSObject::getPropertySpecificValue):
+        (JSC::JSObject::removeDirect):
+        (JSC::JSObject::growOutOfLineStorage):
+        (JSC::JSObject::getOwnPropertyDescriptor):
+        * runtime/JSObject.h:
+        (JSObject):
+        (JSC::JSObject::getDirect):
+        (JSC::JSObject::getDirectLocation):
+        (JSC::JSObject::hasInlineStorage):
+        (JSC::JSObject::inlineStorageUnsafe):
+        (JSC::JSObject::inlineStorage):
+        (JSC::JSObject::outOfLineStorage):
+        (JSC::JSObject::locationForOffset):
+        (JSC::JSObject::offsetForLocation):
+        (JSC::JSObject::getDirectOffset):
+        (JSC::JSObject::putDirectOffset):
+        (JSC::JSObject::putUndefinedAtDirectOffset):
+        (JSC::JSObject::addressOfOutOfLineStorage):
+        (JSC::JSObject::finishCreation):
+        (JSC::JSNonFinalObject::JSNonFinalObject):
+        (JSC::JSNonFinalObject::finishCreation):
+        (JSFinalObject):
+        (JSC::JSFinalObject::finishCreation):
+        (JSC::JSFinalObject::JSFinalObject):
+        (JSC::JSObject::offsetOfOutOfLineStorage):
+        (JSC::JSObject::setOutOfLineStorage):
+        (JSC::JSObject::JSObject):
+        (JSC):
+        (JSC::JSCell::fastGetOwnProperty):
+        (JSC::JSObject::putDirectInternal):
+        (JSC::JSObject::setStructureAndReallocateStorageIfNecessary):
+        (JSC::JSObject::putDirectWithoutTransition):
+        (JSC::offsetRelativeToPatchedStorage):
+        (JSC::indexRelativeToBase):
+        (JSC::offsetRelativeToBase):
+        * runtime/JSPropertyNameIterator.cpp:
+        (JSC::JSPropertyNameIterator::create):
+        * runtime/JSPropertyNameIterator.h:
+        (JSPropertyNameIterator):
+        (JSC::JSPropertyNameIterator::getOffset):
+        (JSC::JSPropertyNameIterator::finishCreation):
+        * runtime/JSValue.cpp:
+        (JSC::JSValue::putToPrimitive):
+        * runtime/Operations.h:
+        (JSC::normalizePrototypeChain):
+        * runtime/Options.cpp:
+        (JSC):
+        (JSC::Options::initialize):
+        * runtime/PropertyMapHashTable.h:
+        (PropertyMapEntry):
+        (JSC::PropertyMapEntry::PropertyMapEntry):
+        (PropertyTable):
+        (JSC::PropertyTable::PropertyTable):
+        (JSC::PropertyTable::getDeletedOffset):
+        (JSC::PropertyTable::addDeletedOffset):
+        (JSC::PropertyTable::nextOffset):
+        (JSC):
+        (JSC::PropertyTable::sizeInMemory):
+        * runtime/PropertyOffset.h: Added.
+        (JSC):
+        (JSC::checkOffset):
+        (JSC::validateOffset):
+        (JSC::isValidOffset):
+        (JSC::isInlineOffset):
+        (JSC::isOutOfLineOffset):
+        (JSC::offsetInInlineStorage):
+        (JSC::offsetInOutOfLineStorage):
+        (JSC::offsetInRespectiveStorage):
+        (JSC::numberOfOutOfLineSlotsForLastOffset):
+        (JSC::numberOfSlotsForLastOffset):
+        (JSC::nextPropertyOffsetFor):
+        (JSC::firstPropertyOffsetFor):
+        * runtime/PropertySlot.h:
+        (JSC::PropertySlot::cachedOffset):
+        (JSC::PropertySlot::setValue):
+        (JSC::PropertySlot::setCacheableGetterSlot):
+        (JSC::PropertySlot::clearOffset):
+        * runtime/PutPropertySlot.h:
+        (JSC::PutPropertySlot::setExistingProperty):
+        (JSC::PutPropertySlot::setNewProperty):
+        (JSC::PutPropertySlot::cachedOffset):
+        (PutPropertySlot):
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+        (JSC::Structure::materializePropertyMap):
+        (JSC::nextOutOfLineStorageCapacity):
+        (JSC::Structure::growOutOfLineCapacity):
+        (JSC::Structure::suggestedNewOutOfLineStorageCapacity):
+        (JSC::Structure::addPropertyTransitionToExistingStructure):
+        (JSC::Structure::addPropertyTransition):
+        (JSC::Structure::removePropertyTransition):
+        (JSC::Structure::flattenDictionaryStructure):
+        (JSC::Structure::addPropertyWithoutTransition):
+        (JSC::Structure::removePropertyWithoutTransition):
+        (JSC::Structure::copyPropertyTableForPinning):
+        (JSC::Structure::get):
+        (JSC::Structure::putSpecificValue):
+        (JSC::Structure::remove):
+        * runtime/Structure.h:
+        (Structure):
+        (JSC::Structure::putWillGrowOutOfLineStorage):
+        (JSC::Structure::previousID):
+        (JSC::Structure::outOfLineCapacity):
+        (JSC::Structure::outOfLineSizeForKnownFinalObject):
+        (JSC::Structure::outOfLineSizeForKnownNonFinalObject):
+        (JSC::Structure::outOfLineSize):
+        (JSC::Structure::hasInlineStorage):
+        (JSC::Structure::inlineCapacity):
+        (JSC::Structure::inlineSizeForKnownFinalObject):
+        (JSC::Structure::inlineSize):
+        (JSC::Structure::totalStorageSize):
+        (JSC::Structure::totalStorageCapacity):
+        (JSC::Structure::firstValidOffset):
+        (JSC::Structure::lastValidOffset):
+        (JSC::Structure::isValidOffset):
+        (JSC::Structure::isEmpty):
+        (JSC::Structure::transitionCount):
+        (JSC::Structure::get):
+
 2012-07-05  Oliver Hunt  <oliver@apple.com>
 
         JSObjectCallAsFunction should thisConvert the provided thisObject
diff --git a/Source/JavaScriptCore/GNUmakefile.list.am b/Source/JavaScriptCore/GNUmakefile.list.am
index 26dc79e..7619f64 100644
--- a/Source/JavaScriptCore/GNUmakefile.list.am
+++ b/Source/JavaScriptCore/GNUmakefile.list.am
@@ -582,6 +582,7 @@
 	Source/JavaScriptCore/runtime/PropertyName.h \
 	Source/JavaScriptCore/runtime/PropertyNameArray.cpp \
 	Source/JavaScriptCore/runtime/PropertyNameArray.h \
+	Source/JavaScriptCore/runtime/PropertyOffset.h \
 	Source/JavaScriptCore/runtime/PropertySlot.cpp \
 	Source/JavaScriptCore/runtime/PropertySlot.h \
 	Source/JavaScriptCore/runtime/Protect.h \
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
index 6fc1d43..c50013a 100755
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
@@ -61,9 +61,9 @@
     ?addBytes@SHA1@WTF@@QAEXPBEI@Z
     ?addCurrentThread@MachineThreads@JSC@@QAEXXZ
     ?addFinalizer@Heap@JSC@@QAEXPAVJSCell@2@P6AX0@Z@Z
-    ?addPropertyTransition@Structure@JSC@@SAPAV12@AAVJSGlobalData@2@PAV12@VPropertyName@2@IPAVJSCell@2@AAI@Z
-    ?addPropertyTransitionToExistingStructure@Structure@JSC@@SAPAV12@PAV12@VPropertyName@2@IPAVJSCell@2@AAI@Z
-    ?addPropertyWithoutTransition@Structure@JSC@@QAEIAAVJSGlobalData@2@VPropertyName@2@IPAVJSCell@2@@Z
+    ?addPropertyTransition@Structure@JSC@@SAPAV12@AAVJSGlobalData@2@PAV12@VPropertyName@2@IPAVJSCell@2@AAH@Z
+    ?addPropertyTransitionToExistingStructure@Structure@JSC@@SAPAV12@PAV12@VPropertyName@2@IPAVJSCell@2@AAH@Z
+    ?addPropertyWithoutTransition@Structure@JSC@@QAEHAAVJSGlobalData@2@VPropertyName@2@IPAVJSCell@2@@Z
     ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVExecState@2@PAVStringImpl@4@@Z
     ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVJSGlobalData@2@PAVStringImpl@4@@Z
     ?addStaticGlobals@JSGlobalObject@JSC@@IAEXPAUGlobalPropertyInfo@12@H@Z
@@ -192,7 +192,6 @@
     ?from@Identifier@JSC@@SA?AV12@PAVExecState@2@I@Z
     ?functionGetter@PropertySlot@JSC@@ABE?AVJSValue@2@PAVExecState@2@@Z
     ?functionName@DebuggerCallFrame@JSC@@QBEPBVUString@2@XZ
-    ?get@Structure@JSC@@QAEIAAVJSGlobalData@2@VPropertyName@2@AAIAAPAVJSCell@2@@Z
     ?getCalculatedDisplayName@JSC@@YA?AVUString@1@PAVExecState@1@PAVJSObject@1@@Z
     ?getCallData@JSCell@JSC@@SA?AW4CallType@2@PAV12@AATCallData@2@@Z
     ?getCallableObjectSlow@JSC@@YAPAVJSCell@1@PAV21@@Z
@@ -211,11 +210,12 @@
     ?getStackTrace@Interpreter@JSC@@SAXPAVJSGlobalData@2@AAV?$Vector@UStackFrame@JSC@@$0A@@WTF@@@Z
     ?getString@JSCell@JSC@@QBE?AVUString@2@PAVExecState@2@@Z
     ?getString@JSCell@JSC@@QBE_NPAVExecState@2@AAVUString@2@@Z
+    ?get@Structure@JSC@@QAEHAAVJSGlobalData@2@VPropertyName@2@AAIAAPAVJSCell@2@@Z
     ?getter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ
     ?globalExec@JSGlobalObject@JSC@@QAEPAVExecState@2@XZ
     ?globalObjectCount@Heap@JSC@@QAEIXZ
+    ?growOutOfLineStorage@JSObject@JSC@@QAEPAV?$WriteBarrierBase@W4Unknown@JSC@@@2@AAVJSGlobalData@2@II@Z
     ?grow@HandleSet@JSC@@AAEXXZ
-    ?growPropertyStorage@JSObject@JSC@@QAEPAV?$WriteBarrierBase@W4Unknown@JSC@@@2@AAVJSGlobalData@2@II@Z
     ?hasInstance@JSObject@JSC@@SA_NPAV12@PAVExecState@2@VJSValue@2@2@Z
     ?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@I@Z
     ?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@VPropertyName@2@@Z
@@ -328,7 +328,7 @@
     ?stopProfiling@Profiler@JSC@@QAE?AV?$PassRefPtr@VProfile@JSC@@@WTF@@PAVExecState@2@ABVUString@2@@Z
     ?stopSampling@JSGlobalData@JSC@@QAEXXZ
     ?substringSharingImpl@UString@JSC@@QBE?AV12@II@Z
-    ?suggestedNewPropertyStorageSize@Structure@JSC@@QAEIXZ
+    ?suggestedNewOutOfLineStorageCapacity@Structure@JSC@@QAEIXZ
     ?sweeper@Heap@JSC@@QAEPAVIncrementalSweeper@2@XZ
     ?synthesizePrototype@JSValue@JSC@@QBEPAVJSObject@2@PAVExecState@2@@Z
     ?thisObject@DebuggerCallFrame@JSC@@QBEPAVJSObject@2@XZ
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
index 534f8bf..a0e32f8 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
@@ -1094,6 +1094,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\runtime\PropertyOffset.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\runtime\PropertySlot.cpp"
 				>
 			</File>
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 7b3454c..12a310d 100644
--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -223,6 +223,7 @@
 		0FF427651591A1CE004CB9FF /* DFGDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF427621591A1C9004CB9FF /* DFGDisassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FF42771159275D5004CB9FF /* ResolveGlobalStatus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF4276E159275D2004CB9FF /* ResolveGlobalStatus.cpp */; };
 		0FF42772159275D8004CB9FF /* ResolveGlobalStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF4276F159275D2004CB9FF /* ResolveGlobalStatus.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FF7168C15A3B235008F5DAA /* PropertyOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF7168A15A3B231008F5DAA /* PropertyOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FF922D414F46B410041A24E /* LLIntOffsetsExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */; };
 		0FFFC95714EF90A000C72532 /* DFGCFAPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FFFC94B14EF909500C72532 /* DFGCFAPhase.cpp */; };
 		0FFFC95814EF90A200C72532 /* DFGCFAPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFFC94C14EF909500C72532 /* DFGCFAPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -957,6 +958,7 @@
 		0FF427621591A1C9004CB9FF /* DFGDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDisassembler.h; path = dfg/DFGDisassembler.h; sourceTree = "<group>"; };
 		0FF4276E159275D2004CB9FF /* ResolveGlobalStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResolveGlobalStatus.cpp; sourceTree = "<group>"; };
 		0FF4276F159275D2004CB9FF /* ResolveGlobalStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResolveGlobalStatus.h; sourceTree = "<group>"; };
+		0FF7168A15A3B231008F5DAA /* PropertyOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PropertyOffset.h; sourceTree = "<group>"; };
 		0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = JSCLLIntOffsetsExtractor; sourceTree = BUILT_PRODUCTS_DIR; };
 		0FFFC94B14EF909500C72532 /* DFGCFAPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCFAPhase.cpp; path = dfg/DFGCFAPhase.cpp; sourceTree = "<group>"; };
 		0FFFC94C14EF909500C72532 /* DFGCFAPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCFAPhase.h; path = dfg/DFGCFAPhase.h; sourceTree = "<group>"; };
@@ -2107,6 +2109,7 @@
 				86158AB2155C8B3F00B45C9C /* PropertyName.h */,
 				65400C0F0A69BAF200509887 /* PropertyNameArray.cpp */,
 				65400C100A69BAF200509887 /* PropertyNameArray.h */,
+				0FF7168A15A3B231008F5DAA /* PropertyOffset.h */,
 				65621E6B089E859700760F35 /* PropertySlot.cpp */,
 				65621E6C089E859700760F35 /* PropertySlot.h */,
 				65C02FBB0637462A003E7EE6 /* Protect.h */,
@@ -2811,6 +2814,7 @@
 				0FF4274B158EBE91004CB9FF /* udis86.h in Headers */,
 				0FF427651591A1CE004CB9FF /* DFGDisassembler.h in Headers */,
 				0FF42772159275D8004CB9FF /* ResolveGlobalStatus.h in Headers */,
+				0FF7168C15A3B235008F5DAA /* PropertyOffset.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/Source/JavaScriptCore/assembler/ARMv7Assembler.h b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
index 81977e2..eef0ba8 100644
--- a/Source/JavaScriptCore/assembler/ARMv7Assembler.h
+++ b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
@@ -1018,6 +1018,12 @@
         else
             m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDR_imm_T3, rn, rt, imm.getUInt12());
     }
+    
+    ALWAYS_INLINE void ldrWide8BitImmediate(RegisterID rt, RegisterID rn, uint8_t immediate)
+    {
+        ASSERT(rn != ARMRegisters::pc);
+        m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDR_imm_T3, rn, rt, immediate);
+    }
 
     ALWAYS_INLINE void ldrCompact(RegisterID rt, RegisterID rn, ARMThumbImmediate imm)
     {
@@ -2117,6 +2123,46 @@
     {
         return 6;
     }
+    
+    static void replaceWithLoad(void* instructionStart)
+    {
+        ASSERT(!(bitwise_cast<uintptr_t>(instructionStart) & 1));
+        uint16_t* ptr = reinterpret_cast<uint16_t*>(instructionStart);
+        switch (ptr[0] & 0xFFF0) {
+        case OP_LDR_imm_T3:
+            break;
+        case OP_ADD_imm_T3:
+            ASSERT(!(ptr[1] & 0xF000));
+            ptr[0] &= 0x000F;
+            ptr[0] |= OP_LDR_imm_T3;
+            ptr[1] |= (ptr[1] & 0x0F00) << 4;
+            ptr[1] &= 0xF0FF;
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+        cacheFlush(ptr, sizeof(uint16_t) * 2);
+    }
+
+    static void replaceWithAddressComputation(void* instructionStart)
+    {
+        ASSERT(!(bitwise_cast<uintptr_t>(instructionStart) & 1));
+        uint16_t* ptr = reinterpret_cast<uint16_t*>(instructionStart);
+        switch (ptr[0] & 0xFFF0) {
+        case OP_LDR_imm_T3:
+            ASSERT(!(ptr[1] & 0x0F00));
+            ptr[0] &= 0x000F;
+            ptr[0] |= OP_ADD_imm_T3;
+            ptr[1] |= (ptr[1] & 0xF000) >> 4;
+            ptr[1] &= 0x0FFF;
+            break;
+        case OP_ADD_imm_T3:
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+        cacheFlush(ptr, sizeof(uint16_t) * 2);
+    }
 
     unsigned debugOffset() { return m_formatter.debugOffset(); }
 
diff --git a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
index 0080446..a24f757 100644
--- a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
+++ b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
@@ -295,6 +295,36 @@
     private:
         AssemblerLabel m_label;
     };
+    
+    // ConvertibleLoadLabel:
+    //
+    // A ConvertibleLoadLabel records a loadPtr instruction that can be patched to an addPtr
+    // so that:
+    //
+    // loadPtr(Address(a, i), b)
+    //
+    // becomes:
+    //
+    // addPtr(TrustedImmPtr(i), a, b)
+    class ConvertibleLoadLabel {
+        template<class TemplateAssemblerType>
+        friend class AbstractMacroAssembler;
+        friend class LinkBuffer;
+        
+    public:
+        ConvertibleLoadLabel()
+        {
+        }
+        
+        ConvertibleLoadLabel(AbstractMacroAssembler<AssemblerType>* masm)
+            : m_label(masm->m_assembler.labelIgnoringWatchpoints())
+        {
+        }
+        
+        bool isSet() const { return m_label.isSet(); }
+    private:
+        AssemblerLabel m_label;
+    };
 
     // DataLabelPtr:
     //
@@ -562,6 +592,11 @@
         result.m_label = m_assembler.labelIgnoringWatchpoints();
         return result;
     }
+#else
+    Label labelIgnoringWatchpoints()
+    {
+        return label();
+    }
 #endif
     
     Label label()
@@ -672,6 +707,16 @@
     {
         return AssemblerType::readPointer(dataLabelPtr.dataLocation());
     }
+    
+    static void replaceWithLoad(CodeLocationConvertibleLoad label)
+    {
+        AssemblerType::replaceWithLoad(label.dataLocation());
+    }
+    
+    static void replaceWithAddressComputation(CodeLocationConvertibleLoad label)
+    {
+        AssemblerType::replaceWithAddressComputation(label.dataLocation());
+    }
 };
 
 } // namespace JSC
diff --git a/Source/JavaScriptCore/assembler/CodeLocation.h b/Source/JavaScriptCore/assembler/CodeLocation.h
index 9500b1e..86d1f2b 100644
--- a/Source/JavaScriptCore/assembler/CodeLocation.h
+++ b/Source/JavaScriptCore/assembler/CodeLocation.h
@@ -40,6 +40,7 @@
 class CodeLocationDataLabelCompact;
 class CodeLocationDataLabel32;
 class CodeLocationDataLabelPtr;
+class CodeLocationConvertibleLoad;
 
 // The CodeLocation* types are all pretty much do-nothing wrappers around
 // CodePtr (or MacroAssemblerCodePtr, to give it its full name).  These
@@ -62,6 +63,7 @@
     CodeLocationDataLabelPtr dataLabelPtrAtOffset(int offset);
     CodeLocationDataLabel32 dataLabel32AtOffset(int offset);
     CodeLocationDataLabelCompact dataLabelCompactAtOffset(int offset);
+    CodeLocationConvertibleLoad convertibleLoadAtOffset(int offset);
 
 protected:
     CodeLocationCommon()
@@ -146,6 +148,15 @@
         : CodeLocationCommon(MacroAssemblerCodePtr(location)) {}
 };
 
+class CodeLocationConvertibleLoad : public CodeLocationCommon {
+public:
+    CodeLocationConvertibleLoad() { }
+    explicit CodeLocationConvertibleLoad(MacroAssemblerCodePtr location)
+        : CodeLocationCommon(location) { }
+    explicit CodeLocationConvertibleLoad(void* location)
+        : CodeLocationCommon(MacroAssemblerCodePtr(location)) { }
+};
+
 inline CodeLocationInstruction CodeLocationCommon::instructionAtOffset(int offset)
 {
     ASSERT_VALID_CODE_OFFSET(offset);
@@ -194,6 +205,12 @@
     return CodeLocationDataLabelCompact(reinterpret_cast<char*>(dataLocation()) + offset);
 }
 
+inline CodeLocationConvertibleLoad CodeLocationCommon::convertibleLoadAtOffset(int offset)
+{
+    ASSERT_VALID_CODE_OFFSET(offset);
+    return CodeLocationConvertibleLoad(reinterpret_cast<char*>(dataLocation()) + offset);
+}
+
 } // namespace JSC
 
 #endif // ENABLE(ASSEMBLER)
diff --git a/Source/JavaScriptCore/assembler/LinkBuffer.cpp b/Source/JavaScriptCore/assembler/LinkBuffer.cpp
index b21b527..0176e43 100644
--- a/Source/JavaScriptCore/assembler/LinkBuffer.cpp
+++ b/Source/JavaScriptCore/assembler/LinkBuffer.cpp
@@ -54,7 +54,7 @@
     
     dataLog("    Code at [%p, %p):\n", result.code().executableAddress(), static_cast<char*>(result.code().executableAddress()) + result.size());
     if (!tryToDisassemble(result.code(), m_size, "    ", WTF::dataFile()))
-        dataLog("        <no disassembly available>");
+        dataLog("        <no disassembly available>\n");
     
     return result;
 }
diff --git a/Source/JavaScriptCore/assembler/LinkBuffer.h b/Source/JavaScriptCore/assembler/LinkBuffer.h
index a58d6af..484d3a7 100644
--- a/Source/JavaScriptCore/assembler/LinkBuffer.h
+++ b/Source/JavaScriptCore/assembler/LinkBuffer.h
@@ -69,6 +69,7 @@
     typedef MacroAssembler::DataLabelCompact DataLabelCompact;
     typedef MacroAssembler::DataLabel32 DataLabel32;
     typedef MacroAssembler::DataLabelPtr DataLabelPtr;
+    typedef MacroAssembler::ConvertibleLoadLabel ConvertibleLoadLabel;
 #if ENABLE(BRANCH_COMPACTION)
     typedef MacroAssembler::LinkRecord LinkRecord;
     typedef MacroAssembler::JumpLinkType JumpLinkType;
@@ -180,6 +181,11 @@
         return CodeLocationDataLabelCompact(MacroAssembler::getLinkerAddress(code(), applyOffset(label.m_label)));
     }
 
+    CodeLocationConvertibleLoad locationOf(ConvertibleLoadLabel label)
+    {
+        return CodeLocationConvertibleLoad(MacroAssembler::getLinkerAddress(code(), applyOffset(label.m_label)));
+    }
+
     // This method obtains the return address of the call, given as an offset from
     // the start of the code.
     unsigned returnAddressOffset(Call call)
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
index 6c0feff..8e8b753 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
@@ -600,6 +600,14 @@
         move(TrustedImmPtr(address), addressTempRegister);
         m_assembler.ldr(dest, addressTempRegister, ARMThumbImmediate::makeUInt16(0));
     }
+    
+    ConvertibleLoadLabel convertibleLoadPtr(Address address, RegisterID dest)
+    {
+        ConvertibleLoadLabel result(this);
+        ASSERT(address.offset >=0 && address.offset <= 255);
+        m_assembler.ldrWide8BitImmediate(dest, address.base, address.offset);
+        return result;
+    }
 
     void load8(ImplicitAddress address, RegisterID dest)
     {
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86.h
index 3ea40c9..45de813 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86.h
@@ -89,6 +89,13 @@
         m_assembler.movl_mr(address, dest);
     }
 
+    ConvertibleLoadLabel convertibleLoadPtr(Address address, RegisterID dest)
+    {
+        ConvertibleLoadLabel result = ConvertibleLoadLabel(this);
+        m_assembler.movl_mr(address.offset, address.base, dest);
+        return result;
+    }
+
     void addDouble(AbsoluteAddress address, FPRegisterID dest)
     {
         m_assembler.addsd_mr(address.m_ptr, dest);
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
index fa95b33..1fb574b 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
@@ -258,6 +258,13 @@
         m_assembler.movq_mr(address.offset, address.base, dest);
     }
 
+    ConvertibleLoadLabel convertibleLoadPtr(Address address, RegisterID dest)
+    {
+        ConvertibleLoadLabel result = ConvertibleLoadLabel(this);
+        m_assembler.movq_mr(address.offset, address.base, dest);
+        return result;
+    }
+
     void loadPtr(BaseIndex address, RegisterID dest)
     {
         m_assembler.movq_mr(address.offset, address.base, address.index, address.scale, dest);
diff --git a/Source/JavaScriptCore/assembler/RepatchBuffer.h b/Source/JavaScriptCore/assembler/RepatchBuffer.h
index a87294b..531dda9 100644
--- a/Source/JavaScriptCore/assembler/RepatchBuffer.h
+++ b/Source/JavaScriptCore/assembler/RepatchBuffer.h
@@ -122,6 +122,24 @@
     {
         relinkNearCallerToTrampoline(returnAddress, CodeLocationLabel(newCalleeFunction));
     }
+    
+    void replaceWithLoad(CodeLocationConvertibleLoad label)
+    {
+        MacroAssembler::replaceWithLoad(label);
+    }
+    
+    void replaceWithAddressComputation(CodeLocationConvertibleLoad label)
+    {
+        MacroAssembler::replaceWithAddressComputation(label);
+    }
+    
+    void setLoadInstructionIsActive(CodeLocationConvertibleLoad label, bool isActive)
+    {
+        if (isActive)
+            replaceWithLoad(label);
+        else
+            replaceWithAddressComputation(label);
+    }
 
 private:
     void* m_start;
diff --git a/Source/JavaScriptCore/assembler/X86Assembler.h b/Source/JavaScriptCore/assembler/X86Assembler.h
index 9c35be8..cf81332 100644
--- a/Source/JavaScriptCore/assembler/X86Assembler.h
+++ b/Source/JavaScriptCore/assembler/X86Assembler.h
@@ -1839,6 +1839,42 @@
         return 5;
     }
     
+    static void replaceWithLoad(void* instructionStart)
+    {
+        uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
+#if CPU(X86_64)
+        if ((*ptr & ~15) == PRE_REX)
+            ptr++;
+#endif
+        switch (*ptr) {
+        case OP_MOV_GvEv:
+            break;
+        case OP_LEA:
+            *ptr = OP_MOV_GvEv;
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+    }
+    
+    static void replaceWithAddressComputation(void* instructionStart)
+    {
+        uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
+#if CPU(X86_64)
+        if ((*ptr & ~15) == PRE_REX)
+            ptr++;
+#endif
+        switch (*ptr) {
+        case OP_MOV_GvEv:
+            *ptr = OP_LEA;
+            break;
+        case OP_LEA:
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+    }
+    
     static unsigned getCallReturnOffset(AssemblerLabel call)
     {
         ASSERT(call.isSet());
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index a7eabbd..48d0fe7 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -197,6 +197,9 @@
     case op_get_by_id:
         op = "get_by_id";
         break;
+    case op_get_by_id_out_of_line:
+        op = "get_by_id_out_of_line";
+        break;
     case op_get_by_id_self:
         op = "get_by_id_self";
         break;
@@ -1033,6 +1036,7 @@
             break;
         }
         case op_get_by_id:
+        case op_get_by_id_out_of_line:
         case op_get_by_id_self:
         case op_get_by_id_proto:
         case op_get_by_id_chain:
@@ -1059,6 +1063,10 @@
             printPutByIdOp(exec, location, it, "put_by_id");
             break;
         }
+        case op_put_by_id_out_of_line: {
+            printPutByIdOp(exec, location, it, "put_by_id_out_of_line");
+            break;
+        }
         case op_put_by_id_replace: {
             printPutByIdOp(exec, location, it, "put_by_id_replace");
             break;
@@ -1071,10 +1079,18 @@
             printPutByIdOp(exec, location, it, "put_by_id_transition_direct");
             break;
         }
+        case op_put_by_id_transition_direct_out_of_line: {
+            printPutByIdOp(exec, location, it, "put_by_id_transition_direct_out_of_line");
+            break;
+        }
         case op_put_by_id_transition_normal: {
             printPutByIdOp(exec, location, it, "put_by_id_transition_normal");
             break;
         }
+        case op_put_by_id_transition_normal_out_of_line: {
+            printPutByIdOp(exec, location, it, "put_by_id_transition_normal_out_of_line");
+            break;
+        }
         case op_put_by_id_generic: {
             printPutByIdOp(exec, location, it, "put_by_id_generic");
             break;
@@ -2029,7 +2045,9 @@
             Instruction* curInstruction = &instructions()[m_propertyAccessInstructions[i]];
             switch (interpreter->getOpcodeID(curInstruction[0].u.opcode)) {
             case op_get_by_id:
+            case op_get_by_id_out_of_line:
             case op_put_by_id:
+            case op_put_by_id_out_of_line:
                 if (!curInstruction[4].u.structure || Heap::isMarked(curInstruction[4].u.structure.get()))
                     break;
                 if (verboseUnlinking)
@@ -2039,6 +2057,8 @@
                 break;
             case op_put_by_id_transition_direct:
             case op_put_by_id_transition_normal:
+            case op_put_by_id_transition_direct_out_of_line:
+            case op_put_by_id_transition_normal_out_of_line:
                 if (Heap::isMarked(curInstruction[4].u.structure.get())
                     && Heap::isMarked(curInstruction[6].u.structure.get())
                     && Heap::isMarked(curInstruction[7].u.structureChain.get()))
diff --git a/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp b/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
index a62a43f..cb3e8e8 100644
--- a/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
+++ b/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
@@ -48,9 +48,9 @@
     
     unsigned attributesIgnored;
     JSCell* specificValue;
-    size_t offset = structure->get(
+    PropertyOffset offset = structure->get(
         *profiledBlock->globalData(), ident, attributesIgnored, specificValue);
-    if (offset == notFound)
+    if (!isValidOffset(offset))
         return GetByIdStatus(NoInformation, false);
     
     return GetByIdStatus(Simple, false, StructureSet(structure), offset, specificValue);
@@ -88,7 +88,7 @@
         
     result.m_offset = currentStructure->get(
         *profiledBlock->globalData(), ident, attributesIgnored, specificValue);
-    if (result.m_offset == notFound)
+    if (!isValidOffset(result.m_offset))
         return;
         
     result.m_structureSet.add(structure);
@@ -156,12 +156,12 @@
         result.m_offset = structure->get(
             *profiledBlock->globalData(), ident, attributesIgnored, specificValue);
         
-        if (result.m_offset != notFound) {
+        if (isValidOffset(result.m_offset)) {
             result.m_structureSet.add(structure);
             result.m_specificValue = JSValue(specificValue);
         }
         
-        if (result.m_offset != notFound)
+        if (isValidOffset(result.m_offset))
             ASSERT(result.m_structureSet.size());
         break;
     }
@@ -176,11 +176,11 @@
             
             unsigned attributesIgnored;
             JSCell* specificValue;
-            size_t myOffset = structure->get(
+            PropertyOffset myOffset = structure->get(
                 *profiledBlock->globalData(), ident, attributesIgnored, specificValue);
             
-            if (myOffset == notFound) {
-                result.m_offset = notFound;
+            if (!isValidOffset(myOffset)) {
+                result.m_offset = invalidOffset;
                 break;
             }
                     
@@ -188,7 +188,7 @@
                 result.m_offset = myOffset;
                 result.m_specificValue = JSValue(specificValue);
             } else if (result.m_offset != myOffset) {
-                result.m_offset = notFound;
+                result.m_offset = invalidOffset;
                 break;
             } else if (result.m_specificValue != JSValue(specificValue))
                 result.m_specificValue = JSValue();
@@ -196,7 +196,7 @@
             result.m_structureSet.add(structure);
         }
                     
-        if (result.m_offset != notFound)
+        if (isValidOffset(result.m_offset))
             ASSERT(result.m_structureSet.size());
         break;
     }
@@ -223,11 +223,11 @@
     }
         
     default:
-        ASSERT(result.m_offset == notFound);
+        ASSERT(!isValidOffset(result.m_offset));
         break;
     }
     
-    if (result.m_offset == notFound) {
+    if (!isValidOffset(result.m_offset)) {
         result.m_state = TakesSlowPath;
         result.m_structureSet.clear();
         result.m_chain.clear();
diff --git a/Source/JavaScriptCore/bytecode/GetByIdStatus.h b/Source/JavaScriptCore/bytecode/GetByIdStatus.h
index 42eadfd..297ec33 100644
--- a/Source/JavaScriptCore/bytecode/GetByIdStatus.h
+++ b/Source/JavaScriptCore/bytecode/GetByIdStatus.h
@@ -26,6 +26,7 @@
 #ifndef GetByIdStatus_h
 #define GetByIdStatus_h
 
+#include "PropertyOffset.h"
 #include "StructureSet.h"
 #include <wtf/NotFound.h>
 
@@ -46,13 +47,13 @@
 
     GetByIdStatus()
         : m_state(NoInformation)
-        , m_offset(notFound)
+        , m_offset(invalidOffset)
     {
     }
     
     GetByIdStatus(
         State state, bool wasSeenInJIT, const StructureSet& structureSet = StructureSet(),
-        size_t offset = notFound, JSValue specificValue = JSValue(), Vector<Structure*> chain = Vector<Structure*>())
+        size_t offset = invalidOffset, JSValue specificValue = JSValue(), Vector<Structure*> chain = Vector<Structure*>())
         : m_state(state)
         , m_structureSet(structureSet)
         , m_chain(chain)
@@ -76,7 +77,7 @@
     const StructureSet& structureSet() const { return m_structureSet; }
     const Vector<Structure*>& chain() const { return m_chain; } // Returns empty vector if this is a direct access.
     JSValue specificValue() const { return m_specificValue; } // Returns JSValue() if there is no specific value.
-    size_t offset() const { return m_offset; }
+    PropertyOffset offset() const { return m_offset; }
     
     bool wasSeenInJIT() const { return m_wasSeenInJIT; }
     
@@ -88,7 +89,7 @@
     StructureSet m_structureSet;
     Vector<Structure*> m_chain;
     JSValue m_specificValue;
-    size_t m_offset;
+    PropertyOffset m_offset;
     bool m_wasSeenInJIT;
 };
 
diff --git a/Source/JavaScriptCore/bytecode/Opcode.h b/Source/JavaScriptCore/bytecode/Opcode.h
index e0cff16..14cefb9 100644
--- a/Source/JavaScriptCore/bytecode/Opcode.h
+++ b/Source/JavaScriptCore/bytecode/Opcode.h
@@ -108,6 +108,7 @@
         macro(op_resolve_with_base, 5) /* has value profiling */ \
         macro(op_resolve_with_this, 5) /* has value profiling */ \
         macro(op_get_by_id, 9) /* has value profiling */ \
+        macro(op_get_by_id_out_of_line, 9) /* has value profiling */ \
         macro(op_get_by_id_self, 9) /* has value profiling */ \
         macro(op_get_by_id_proto, 9) /* has value profiling */ \
         macro(op_get_by_id_chain, 9) /* has value profiling */ \
@@ -122,9 +123,12 @@
         macro(op_get_string_length, 9) /* has value profiling */ \
         macro(op_get_arguments_length, 4) \
         macro(op_put_by_id, 9) \
+        macro(op_put_by_id_out_of_line, 9) \
         macro(op_put_by_id_transition, 9) \
         macro(op_put_by_id_transition_direct, 9) \
+        macro(op_put_by_id_transition_direct_out_of_line, 9) \
         macro(op_put_by_id_transition_normal, 9) \
+        macro(op_put_by_id_transition_normal_out_of_line, 9) \
         macro(op_put_by_id_replace, 9) \
         macro(op_put_by_id_generic, 9) \
         macro(op_del_by_id, 4) \
diff --git a/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp b/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp
index 3715606..ce25a52 100644
--- a/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp
+++ b/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp
@@ -43,12 +43,13 @@
 
     Structure* structure = instruction[4].u.structure.get();
     if (!structure)
-        return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
+        return PutByIdStatus(NoInformation, 0, 0, 0, invalidOffset);
     
-    if (instruction[0].u.opcode == llint_op_put_by_id) {
-        size_t offset = structure->get(*profiledBlock->globalData(), ident);
-        if (offset == notFound)
-            return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
+    if (instruction[0].u.opcode == llint_op_put_by_id
+        || instruction[0].u.opcode == llint_op_put_by_id_out_of_line) {
+        PropertyOffset offset = structure->get(*profiledBlock->globalData(), ident);
+        if (!isValidOffset(offset))
+            return PutByIdStatus(NoInformation, 0, 0, 0, invalidOffset);
         
         return PutByIdStatus(SimpleReplace, structure, 0, 0, offset);
     }
@@ -56,16 +57,18 @@
     ASSERT(structure->transitionWatchpointSetHasBeenInvalidated());
     
     ASSERT(instruction[0].u.opcode == llint_op_put_by_id_transition_direct
-           || instruction[0].u.opcode == llint_op_put_by_id_transition_normal);
+           || instruction[0].u.opcode == llint_op_put_by_id_transition_normal
+           || instruction[0].u.opcode == llint_op_put_by_id_transition_direct_out_of_line
+           || instruction[0].u.opcode == llint_op_put_by_id_transition_normal_out_of_line);
     
     Structure* newStructure = instruction[6].u.structure.get();
     StructureChain* chain = instruction[7].u.structureChain.get();
     ASSERT(newStructure);
     ASSERT(chain);
     
-    size_t offset = newStructure->get(*profiledBlock->globalData(), ident);
-    if (offset == notFound)
-        return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
+    PropertyOffset offset = newStructure->get(*profiledBlock->globalData(), ident);
+    if (!isValidOffset(offset))
+        return PutByIdStatus(NoInformation, 0, 0, 0, invalidOffset);
     
     return PutByIdStatus(SimpleTransition, structure, newStructure, chain, offset);
 #else
@@ -83,7 +86,7 @@
         return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
     
     if (profiledBlock->likelyToTakeSlowCase(bytecodeIndex))
-        return PutByIdStatus(TakesSlowPath, 0, 0, 0, notFound);
+        return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
     
     StructureStubInfo& stubInfo = profiledBlock->getStubInfo(bytecodeIndex);
     if (!stubInfo.seen)
@@ -94,24 +97,24 @@
         return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
         
     case access_put_by_id_replace: {
-        size_t offset = stubInfo.u.putByIdReplace.baseObjectStructure->get(
+        PropertyOffset offset = stubInfo.u.putByIdReplace.baseObjectStructure->get(
             *profiledBlock->globalData(), ident);
-        if (offset != notFound) {
+        if (isValidOffset(offset)) {
             return PutByIdStatus(
                 SimpleReplace,
                 stubInfo.u.putByIdReplace.baseObjectStructure.get(),
                 0, 0,
                 offset);
         }
-        return PutByIdStatus(TakesSlowPath, 0, 0, 0, notFound);
+        return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
     }
         
     case access_put_by_id_transition_normal:
     case access_put_by_id_transition_direct: {
         ASSERT(stubInfo.u.putByIdTransition.previousStructure->transitionWatchpointSetHasBeenInvalidated());
-        size_t offset = stubInfo.u.putByIdTransition.structure->get(
+        PropertyOffset offset = stubInfo.u.putByIdTransition.structure->get(
             *profiledBlock->globalData(), ident);
-        if (offset != notFound) {
+        if (isValidOffset(offset)) {
             return PutByIdStatus(
                 SimpleTransition,
                 stubInfo.u.putByIdTransition.previousStructure.get(),
@@ -119,14 +122,14 @@
                 stubInfo.u.putByIdTransition.chain.get(),
                 offset);
         }
-        return PutByIdStatus(TakesSlowPath, 0, 0, 0, notFound);
+        return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
     }
         
     default:
-        return PutByIdStatus(TakesSlowPath, 0, 0, 0, notFound);
+        return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
     }
 #else // ENABLE(JIT)
-    return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
+    return PutByIdStatus(NoInformation, 0, 0, 0, invalidOffset);
 #endif // ENABLE(JIT)
 }
 
diff --git a/Source/JavaScriptCore/bytecode/PutByIdStatus.h b/Source/JavaScriptCore/bytecode/PutByIdStatus.h
index a6d95a4..6949152 100644
--- a/Source/JavaScriptCore/bytecode/PutByIdStatus.h
+++ b/Source/JavaScriptCore/bytecode/PutByIdStatus.h
@@ -26,6 +26,7 @@
 #ifndef PutByIdStatus_h
 #define PutByIdStatus_h
 
+#include "PropertyOffset.h"
 #include <wtf/NotFound.h>
 
 namespace JSC {
@@ -55,7 +56,7 @@
         , m_oldStructure(0)
         , m_newStructure(0)
         , m_structureChain(0)
-        , m_offset(notFound)
+        , m_offset(invalidOffset)
     {
     }
     
@@ -64,7 +65,7 @@
         Structure* oldStructure,
         Structure* newStructure,
         StructureChain* structureChain,
-        size_t offset)
+        PropertyOffset offset)
         : m_state(state)
         , m_oldStructure(oldStructure)
         , m_newStructure(newStructure)
@@ -74,7 +75,7 @@
         ASSERT((m_state == NoInformation || m_state == TakesSlowPath) == !m_oldStructure);
         ASSERT((m_state != SimpleTransition) == !m_newStructure);
         ASSERT((m_state != SimpleTransition) == !m_structureChain);
-        ASSERT((m_state == NoInformation || m_state == TakesSlowPath) == (m_offset == notFound));
+        ASSERT((m_state == NoInformation || m_state == TakesSlowPath) == (m_offset == invalidOffset));
     }
     
     static PutByIdStatus computeFor(CodeBlock*, unsigned bytecodeIndex, Identifier&);
@@ -90,7 +91,7 @@
     Structure* oldStructure() const { return m_oldStructure; }
     Structure* newStructure() const { return m_newStructure; }
     StructureChain* structureChain() const { return m_structureChain; }
-    size_t offset() const { return m_offset; }
+    PropertyOffset offset() const { return m_offset; }
     
 private:
     static PutByIdStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex, Identifier&);
@@ -99,7 +100,7 @@
     Structure* m_oldStructure;
     Structure* m_newStructure;
     StructureChain* m_structureChain;
-    size_t m_offset;
+    PropertyOffset m_offset;
 };
 
 } // namespace JSC
diff --git a/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp b/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp
index ff13870..4afee24 100644
--- a/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp
+++ b/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp
@@ -32,17 +32,19 @@
 
 namespace JSC {
 
+#if ENABLE(LLINT) || ENABLE(JIT)
 static ResolveGlobalStatus computeForStructure(CodeBlock* codeBlock, Structure* structure, Identifier& identifier)
 {
     unsigned attributesIgnored;
     JSCell* specificValue;
-    size_t offset = structure->get(
+    PropertyOffset offset = structure->get(
         *codeBlock->globalData(), identifier, attributesIgnored, specificValue);
-    if (offset == notFound)
+    if (!isValidOffset(offset))
         return ResolveGlobalStatus();
     
     return ResolveGlobalStatus(ResolveGlobalStatus::Simple, structure, offset, specificValue);
 }
+#endif // ENABLE(LLINT) || ENABLE(JIT)
 
 static ResolveGlobalStatus computeForLLInt(CodeBlock* codeBlock, unsigned bytecodeIndex, Identifier& identifier)
 {
diff --git a/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.h b/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.h
index 4698332..cbe4d3b 100644
--- a/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.h
+++ b/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.h
@@ -27,6 +27,7 @@
 #define ResolveGlobalStatus_h
 
 #include "JSValue.h"
+#include "PropertyOffset.h"
 #include <wtf/NotFound.h>
 
 namespace JSC {
@@ -46,12 +47,12 @@
     ResolveGlobalStatus()
         : m_state(NoInformation)
         , m_structure(0)
-        , m_offset(notFound)
+        , m_offset(invalidOffset)
     {
     }
     
     ResolveGlobalStatus(
-        State state, Structure* structure = 0, size_t offset = notFound,
+        State state, Structure* structure = 0, PropertyOffset offset = invalidOffset,
         JSValue specificValue = JSValue())
         : m_state(state)
         , m_structure(structure)
@@ -70,13 +71,13 @@
     bool takesSlowPath() const { return m_state == TakesSlowPath; }
     
     Structure* structure() const { return m_structure; }
-    size_t offset() const { return m_offset; }
+    PropertyOffset offset() const { return m_offset; }
     JSValue specificValue() const { return m_specificValue; }
 
 private:
     State m_state;
     Structure* m_structure;
-    size_t m_offset;
+    PropertyOffset m_offset;
     JSValue m_specificValue;
 }; // class ResolveGlobalStatus
 
diff --git a/Source/JavaScriptCore/bytecode/StructureSet.h b/Source/JavaScriptCore/bytecode/StructureSet.h
index 2bbc50c..ebde977 100644
--- a/Source/JavaScriptCore/bytecode/StructureSet.h
+++ b/Source/JavaScriptCore/bytecode/StructureSet.h
@@ -113,15 +113,6 @@
     
     size_t size() const { return m_structures.size(); }
     
-    bool allAreUsingInlinePropertyStorage() const
-    {
-        for (size_t i = 0; i < m_structures.size(); ++i) {
-            if (!m_structures[i]->isUsingInlineStorage())
-                return false;
-        }
-        return true;
-    }
-    
     // Call this if you know that the structure set must consist of exactly
     // one structure.
     Structure* singletonStructure() const
diff --git a/Source/JavaScriptCore/bytecode/StructureStubInfo.h b/Source/JavaScriptCore/bytecode/StructureStubInfo.h
index 573f6e9..2ed0e4a 100644
--- a/Source/JavaScriptCore/bytecode/StructureStubInfo.h
+++ b/Source/JavaScriptCore/bytecode/StructureStubInfo.h
@@ -204,6 +204,7 @@
                 int8_t valueGPR;
                 int8_t scratchGPR;
                 int32_t deltaCallToDone;
+                int32_t deltaCallToStorageLoad;
                 int32_t deltaCallToStructCheck;
                 int32_t deltaCallToSlowCase;
                 int32_t deltaCheckImmToCall;
@@ -219,6 +220,7 @@
                     struct {
                         int16_t structureToCompare;
                         int16_t structureCheck;
+                        int16_t propertyStorageLoad;
 #if USE(JSVALUE64)
                         int16_t displacementLabel;
 #else
@@ -230,6 +232,7 @@
                     } get;
                     struct {
                         int16_t structureToCompare;
+                        int16_t propertyStorageLoad;
 #if USE(JSVALUE64)
                         int16_t displacementLabel;
 #else
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index c7765f7..2574dee 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -99,7 +99,7 @@
     bool handleConstantInternalFunction(bool usesResult, int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, CodeSpecializationKind);
     void handleGetByOffset(
         int destinationOperand, SpeculatedType, NodeIndex base, unsigned identifierNumber,
-        bool useInlineStorage, size_t offset);
+        PropertyOffset);
     void handleGetById(
         int destinationOperand, SpeculatedType, NodeIndex base, unsigned identifierNumber,
         const GetByIdStatus&);
@@ -1630,25 +1630,20 @@
 
 void ByteCodeParser::handleGetByOffset(
     int destinationOperand, SpeculatedType prediction, NodeIndex base, unsigned identifierNumber,
-    bool useInlineStorage, size_t offset)
+    PropertyOffset offset)
 {
     NodeIndex propertyStorage;
-    size_t offsetOffset;
-    if (useInlineStorage) {
+    if (isInlineOffset(offset))
         propertyStorage = base;
-        ASSERT(!(sizeof(JSObject) % sizeof(EncodedJSValue)));
-        offsetOffset = sizeof(JSObject) / sizeof(EncodedJSValue);
-    } else {
+    else
         propertyStorage = addToGraph(GetPropertyStorage, base);
-        offsetOffset = 0;
-    }
     set(destinationOperand,
         addToGraph(
             GetByOffset, OpInfo(m_graph.m_storageAccessData.size()), OpInfo(prediction),
             propertyStorage));
         
     StorageAccessData storageAccessData;
-    storageAccessData.offset = offset + offsetOffset;
+    storageAccessData.offset = indexRelativeToBase(offset);
     storageAccessData.identifierNumber = identifierNumber;
     m_graph.m_storageAccessData.append(storageAccessData);
 }
@@ -1677,7 +1672,6 @@
                 
     addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(getByIdStatus.structureSet())), base);
     
-    bool useInlineStorage;
     if (!getByIdStatus.chain().isEmpty()) {
         Structure* currentStructure = getByIdStatus.structureSet().singletonStructure();
         JSObject* currentObject = 0;
@@ -1686,9 +1680,7 @@
             currentStructure = getByIdStatus.chain()[i];
             base = addStructureTransitionCheck(currentObject, currentStructure);
         }
-        useInlineStorage = currentStructure->isUsingInlineStorage();
-    } else
-        useInlineStorage = getByIdStatus.structureSet().allAreUsingInlinePropertyStorage();
+    }
     
     // Unless we want bugs like https://bugs.webkit.org/show_bug.cgi?id=88783, we need to
     // ensure that the base of the original get_by_id is kept alive until we're done with
@@ -1707,8 +1699,7 @@
     }
     
     handleGetByOffset(
-        destinationOperand, prediction, base, identifierNumber, useInlineStorage,
-        getByIdStatus.offset());
+        destinationOperand, prediction, base, identifierNumber, getByIdStatus.offset());
 }
 
 void ByteCodeParser::prepareToParseBlock()
@@ -2172,7 +2163,8 @@
             
             SpeculatedType prediction = getPrediction();
             
-            ASSERT(interpreter->getOpcodeID(getInstruction->u.opcode) == op_get_by_id);
+            ASSERT(interpreter->getOpcodeID(getInstruction->u.opcode) == op_get_by_id
+                   || interpreter->getOpcodeID(getInstruction->u.opcode) == op_get_by_id_out_of_line);
             
             NodeIndex base = get(getInstruction[2].u.operand);
             unsigned identifier = m_inlineStackTop->m_identifierRemap[getInstruction[3].u.operand];
@@ -2225,7 +2217,8 @@
             addToGraph(PutScopedVar, OpInfo(slot), getScopeChain, get(source));
             NEXT_OPCODE(op_put_scoped_var);
         }
-        case op_get_by_id: {
+        case op_get_by_id:
+        case op_get_by_id_out_of_line: {
             SpeculatedType prediction = getPredictionWithoutOSRExit();
             
             NodeIndex base = get(currentInstruction[2].u.operand);
@@ -2241,8 +2234,11 @@
             NEXT_OPCODE(op_get_by_id);
         }
         case op_put_by_id:
+        case op_put_by_id_out_of_line:
         case op_put_by_id_transition_direct:
-        case op_put_by_id_transition_normal: {
+        case op_put_by_id_transition_normal:
+        case op_put_by_id_transition_direct_out_of_line:
+        case op_put_by_id_transition_normal_out_of_line: {
             NodeIndex value = get(currentInstruction[3].u.operand);
             NodeIndex base = get(currentInstruction[1].u.operand);
             unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
@@ -2259,25 +2255,20 @@
             
             if (!hasExitSite && putByIdStatus.isSimpleReplace()) {
                 addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(putByIdStatus.oldStructure())), base);
-                size_t offsetOffset;
                 NodeIndex propertyStorage;
-                if (putByIdStatus.oldStructure()->isUsingInlineStorage()) {
+                if (isInlineOffset(putByIdStatus.offset()))
                     propertyStorage = base;
-                    ASSERT(!(sizeof(JSObject) % sizeof(EncodedJSValue)));
-                    offsetOffset = sizeof(JSObject) / sizeof(EncodedJSValue);
-                } else {
+                else
                     propertyStorage = addToGraph(GetPropertyStorage, base);
-                    offsetOffset = 0;
-                }
                 addToGraph(PutByOffset, OpInfo(m_graph.m_storageAccessData.size()), propertyStorage, base, value);
                 
                 StorageAccessData storageAccessData;
-                storageAccessData.offset = putByIdStatus.offset() + offsetOffset;
+                storageAccessData.offset = indexRelativeToBase(putByIdStatus.offset());
                 storageAccessData.identifierNumber = identifierNumber;
                 m_graph.m_storageAccessData.append(storageAccessData);
             } else if (!hasExitSite
                        && putByIdStatus.isSimpleTransition()
-                       && putByIdStatus.oldStructure()->propertyStorageCapacity() == putByIdStatus.newStructure()->propertyStorageCapacity()
+                       && putByIdStatus.oldStructure()->outOfLineCapacity() == putByIdStatus.newStructure()->outOfLineCapacity()
                        && structureChainIsStillValid(
                            direct,
                            putByIdStatus.oldStructure(),
@@ -2308,16 +2299,11 @@
                                 putByIdStatus.newStructure()))),
                     base);
                 
-                size_t offsetOffset;
                 NodeIndex propertyStorage;
-                if (putByIdStatus.newStructure()->isUsingInlineStorage()) {
+                if (isInlineOffset(putByIdStatus.offset()))
                     propertyStorage = base;
-                    ASSERT(!(sizeof(JSObject) % sizeof(EncodedJSValue)));
-                    offsetOffset = sizeof(JSObject) / sizeof(EncodedJSValue);
-                } else {
+                else
                     propertyStorage = addToGraph(GetPropertyStorage, base);
-                    offsetOffset = 0;
-                }
                 addToGraph(
                     PutByOffset,
                     OpInfo(m_graph.m_storageAccessData.size()),
@@ -2326,7 +2312,7 @@
                     value);
                 
                 StorageAccessData storageAccessData;
-                storageAccessData.offset = putByIdStatus.offset() + offsetOffset;
+                storageAccessData.offset = indexRelativeToBase(putByIdStatus.offset());
                 storageAccessData.identifierNumber = identifierNumber;
                 m_graph.m_storageAccessData.append(storageAccessData);
             } else {
@@ -2738,8 +2724,7 @@
                 } else {
                     handleGetByOffset(
                         currentInstruction[1].u.operand, prediction, globalObject,
-                        identifierNumber, status.structure()->isUsingInlineStorage(),
-                        status.offset());
+                        identifierNumber, status.offset());
                 }
                 
                 m_globalResolveNumber++; // Skip over the unused global resolve info.
diff --git a/Source/JavaScriptCore/dfg/DFGCapabilities.h b/Source/JavaScriptCore/dfg/DFGCapabilities.h
index 8c51491..2bc9b29 100644
--- a/Source/JavaScriptCore/dfg/DFGCapabilities.h
+++ b/Source/JavaScriptCore/dfg/DFGCapabilities.h
@@ -119,9 +119,13 @@
     case op_get_scoped_var:
     case op_put_scoped_var:
     case op_get_by_id:
+    case op_get_by_id_out_of_line:
     case op_put_by_id:
+    case op_put_by_id_out_of_line:
     case op_put_by_id_transition_direct:
+    case op_put_by_id_transition_direct_out_of_line:
     case op_put_by_id_transition_normal:
+    case op_put_by_id_transition_normal_out_of_line:
     case op_get_global_var:
     case op_get_global_var_watchable:
     case op_put_global_var:
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
index 9cd60c5..497fc34 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
@@ -172,6 +172,7 @@
 #endif
         info.patch.dfg.deltaCallToSlowCase = differenceBetweenCodePtr(callReturnLocation, linkBuffer.locationOf(m_propertyAccesses[i].m_slowPathGenerator->label()));
         info.patch.dfg.deltaCallToDone = differenceBetweenCodePtr(callReturnLocation, linkBuffer.locationOf(m_propertyAccesses[i].m_done));
+        info.patch.dfg.deltaCallToStorageLoad = differenceBetweenCodePtr(callReturnLocation, linkBuffer.locationOf(m_propertyAccesses[i].m_propertyStorageLoad));
         info.patch.dfg.baseGPR = m_propertyAccesses[i].m_baseGPR;
 #if USE(JSVALUE64)
         info.patch.dfg.valueGPR = m_propertyAccesses[i].m_valueGPR;
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.h b/Source/JavaScriptCore/dfg/DFGJITCompiler.h
index ed16459..24dbbdc 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.h
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.h
@@ -136,6 +136,7 @@
         CodeOrigin codeOrigin,
         MacroAssembler::DataLabelPtr structureImm,
         MacroAssembler::PatchableJump structureCheck,
+        MacroAssembler::ConvertibleLoadLabel propertyStorageLoad,
         MacroAssembler::DataLabelCompact loadOrStore,
         SlowPathGenerator* slowPathGenerator,
         MacroAssembler::Label done,
@@ -148,6 +149,7 @@
         CodeOrigin codeOrigin,
         MacroAssembler::DataLabelPtr structureImm,
         MacroAssembler::PatchableJump structureCheck,
+        MacroAssembler::ConvertibleLoadLabel propertyStorageLoad,
         MacroAssembler::DataLabelCompact tagLoadOrStore,
         MacroAssembler::DataLabelCompact payloadLoadOrStore,
         SlowPathGenerator* slowPathGenerator,
@@ -161,6 +163,7 @@
         : m_codeOrigin(codeOrigin)
         , m_structureImm(structureImm)
         , m_structureCheck(structureCheck)
+        , m_propertyStorageLoad(propertyStorageLoad)
 #if USE(JSVALUE64)
         , m_loadOrStore(loadOrStore)
 #elif USE(JSVALUE32_64)
@@ -182,6 +185,7 @@
     CodeOrigin m_codeOrigin;
     MacroAssembler::DataLabelPtr m_structureImm;
     MacroAssembler::PatchableJump m_structureCheck;
+    MacroAssembler::ConvertibleLoadLabel m_propertyStorageLoad;
 #if USE(JSVALUE64)
     MacroAssembler::DataLabelCompact m_loadOrStore;
 #elif USE(JSVALUE32_64)
diff --git a/Source/JavaScriptCore/dfg/DFGRepatch.cpp b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
index 9c3391b..060e5fc 100644
--- a/Source/JavaScriptCore/dfg/DFGRepatch.cpp
+++ b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
@@ -43,7 +43,7 @@
     repatchBuffer.relink(call, newCalleeFunction);
 }
 
-static void dfgRepatchByIdSelfAccess(CodeBlock* codeBlock, StructureStubInfo& stubInfo, Structure* structure, size_t offset, const FunctionPtr &slowPathFunction, bool compact)
+static void dfgRepatchByIdSelfAccess(CodeBlock* codeBlock, StructureStubInfo& stubInfo, Structure* structure, PropertyOffset offset, const FunctionPtr &slowPathFunction, bool compact)
 {
     RepatchBuffer repatchBuffer(codeBlock);
 
@@ -52,18 +52,19 @@
 
     // Patch the structure check & the offset of the load.
     repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabelPtrAtOffset(-(intptr_t)stubInfo.patch.dfg.deltaCheckImmToCall), structure);
+    repatchBuffer.setLoadInstructionIsActive(stubInfo.callReturnLocation.convertibleLoadAtOffset(stubInfo.patch.dfg.deltaCallToStorageLoad), isOutOfLineOffset(offset));
 #if USE(JSVALUE64)
     if (compact)
-        repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.dfg.deltaCallToLoadOrStore), sizeof(JSValue) * offset);
+        repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.dfg.deltaCallToLoadOrStore), offsetRelativeToPatchedStorage(offset));
     else
-        repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.dfg.deltaCallToLoadOrStore), sizeof(JSValue) * offset);
+        repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.dfg.deltaCallToLoadOrStore), offsetRelativeToPatchedStorage(offset));
 #elif USE(JSVALUE32_64)
     if (compact) {
-        repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.dfg.deltaCallToTagLoadOrStore), sizeof(JSValue) * offset + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
-        repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.dfg.deltaCallToPayloadLoadOrStore), sizeof(JSValue) * offset + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
+        repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.dfg.deltaCallToTagLoadOrStore), offsetRelativeToPatchedStorage(offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
+        repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.dfg.deltaCallToPayloadLoadOrStore), offsetRelativeToPatchedStorage(offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
     } else {
-        repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.dfg.deltaCallToTagLoadOrStore), sizeof(JSValue) * offset + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
-        repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.dfg.deltaCallToPayloadLoadOrStore), sizeof(JSValue) * offset + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
+        repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.dfg.deltaCallToTagLoadOrStore), offsetRelativeToPatchedStorage(offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
+        repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.dfg.deltaCallToPayloadLoadOrStore), offsetRelativeToPatchedStorage(offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
     }
 #endif
 }
@@ -105,7 +106,7 @@
     linkRestoreScratch(patchBuffer, needToRestoreScratch, success, fail, failureCases, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone), stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToSlowCase));
 }
 
-static void generateProtoChainAccessStub(ExecState* exec, StructureStubInfo& stubInfo, StructureChain* chain, size_t count, size_t offset, Structure* structure, CodeLocationLabel successLabel, CodeLocationLabel slowCaseLabel, MacroAssemblerCodeRef& stubRoutine)
+static void generateProtoChainAccessStub(ExecState* exec, StructureStubInfo& stubInfo, StructureChain* chain, size_t count, PropertyOffset offset, Structure* structure, CodeLocationLabel successLabel, CodeLocationLabel slowCaseLabel, MacroAssemblerCodeRef& stubRoutine)
 {
     JSGlobalData* globalData = &exec->globalData();
 
@@ -139,13 +140,23 @@
         currStructure = it->get();
     }
     
-    stubJit.loadPtr(protoObject->addressOfPropertyStorage(), resultGPR);
+    if (isInlineOffset(offset)) {
 #if USE(JSVALUE64)
-    stubJit.loadPtr(MacroAssembler::Address(resultGPR, offset * sizeof(WriteBarrier<Unknown>)), resultGPR);
+        stubJit.loadPtr(protoObject->locationForOffset(offset), resultGPR);
 #elif USE(JSVALUE32_64)
-    stubJit.load32(MacroAssembler::Address(resultGPR, offset * sizeof(WriteBarrier<Unknown>) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
-    stubJit.load32(MacroAssembler::Address(resultGPR, offset * sizeof(WriteBarrier<Unknown>) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultGPR);
+        stubJit.move(MacroAssembler::TrustedImmPtr(protoObject->locationForOffset(offset)), resultGPR);
+        stubJit.load32(MacroAssembler::Address(resultGPR, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
+        stubJit.load32(MacroAssembler::Address(resultGPR, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultGPR);
 #endif
+    } else {
+        stubJit.loadPtr(protoObject->addressOfOutOfLineStorage(), resultGPR);
+#if USE(JSVALUE64)
+        stubJit.loadPtr(MacroAssembler::Address(resultGPR, offsetInOutOfLineStorage(offset) * sizeof(WriteBarrier<Unknown>)), resultGPR);
+#elif USE(JSVALUE32_64)
+        stubJit.load32(MacroAssembler::Address(resultGPR, offsetInOutOfLineStorage(offset) * sizeof(WriteBarrier<Unknown>) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
+        stubJit.load32(MacroAssembler::Address(resultGPR, offsetInOutOfLineStorage(offset) * sizeof(WriteBarrier<Unknown>) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultGPR);
+#endif
+    }
 
     MacroAssembler::Jump success, fail;
     
@@ -253,7 +264,7 @@
     if (slot.cachedPropertyType() != PropertySlot::Value)
         return false;
     
-    size_t offset = slot.cachedOffset();
+    PropertyOffset offset = slot.cachedOffset();
     size_t count = normalizePrototypeChain(exec, baseValue, slot.slotBase(), propertyName, offset);
     if (!count)
         return false;
@@ -349,12 +360,20 @@
             || slot.cachedPropertyType() == PropertySlot::Custom) {
             if (slot.cachedPropertyType() == PropertySlot::Getter) {
                 ASSERT(baseGPR != scratchGPR);
-                stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), scratchGPR);
+                if (isInlineOffset(slot.cachedOffset())) {
 #if USE(JSVALUE64)
-                stubJit.loadPtr(MacroAssembler::Address(scratchGPR, slot.cachedOffset() * sizeof(JSValue)), scratchGPR);
-#elif USE(JSVALUE32_64)
-                stubJit.load32(MacroAssembler::Address(scratchGPR, slot.cachedOffset() * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), scratchGPR);
+                    stubJit.loadPtr(MacroAssembler::Address(baseGPR, offsetRelativeToBase(slot.cachedOffset())), scratchGPR);
+#else
+                    stubJit.load32(MacroAssembler::Address(baseGPR, offsetRelativeToBase(slot.cachedOffset())), scratchGPR);
 #endif
+                } else {
+                    stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR);
+#if USE(JSVALUE64)
+                    stubJit.loadPtr(MacroAssembler::Address(scratchGPR, offsetRelativeToBase(slot.cachedOffset())), scratchGPR);
+#else
+                    stubJit.load32(MacroAssembler::Address(scratchGPR, offsetRelativeToBase(slot.cachedOffset())), scratchGPR);
+#endif
+                }
                 stubJit.setupArgumentsWithExecState(baseGPR, scratchGPR);
                 operationFunction = operationCallGetter;
             } else {
@@ -385,13 +404,27 @@
             handlerCall = stubJit.call();
             stubJit.jump(GPRInfo::returnValueGPR2);
         } else {
-            stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
+            if (isInlineOffset(slot.cachedOffset())) {
 #if USE(JSVALUE64)
-            stubJit.loadPtr(MacroAssembler::Address(resultGPR, slot.cachedOffset() * sizeof(JSValue)), resultGPR);
-#elif USE(JSVALUE32_64)
-            stubJit.load32(MacroAssembler::Address(resultGPR, slot.cachedOffset() * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
-            stubJit.load32(MacroAssembler::Address(resultGPR, slot.cachedOffset() * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultGPR);
+                stubJit.loadPtr(MacroAssembler::Address(baseGPR, offsetRelativeToBase(slot.cachedOffset())), resultGPR);
+#else
+                if (baseGPR == resultTagGPR) {
+                    stubJit.load32(MacroAssembler::Address(baseGPR, offsetRelativeToBase(slot.cachedOffset()) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultGPR);
+                    stubJit.load32(MacroAssembler::Address(baseGPR, offsetRelativeToBase(slot.cachedOffset()) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
+                } else {
+                    stubJit.load32(MacroAssembler::Address(baseGPR, offsetRelativeToBase(slot.cachedOffset()) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
+                    stubJit.load32(MacroAssembler::Address(baseGPR, offsetRelativeToBase(slot.cachedOffset()) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultGPR);
+                }
 #endif
+            } else {
+                stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), resultGPR);
+#if USE(JSVALUE64)
+                stubJit.loadPtr(MacroAssembler::Address(resultGPR, offsetRelativeToBase(slot.cachedOffset())), resultGPR);
+#else
+                stubJit.load32(MacroAssembler::Address(resultGPR, offsetRelativeToBase(slot.cachedOffset()) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
+                stubJit.load32(MacroAssembler::Address(resultGPR, offsetRelativeToBase(slot.cachedOffset()) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultGPR);
+#endif
+            }
             success = stubJit.jump();
             isDirect = true;
         }
@@ -450,7 +483,7 @@
     
     ASSERT(slot.slotBase().isObject());
     
-    size_t offset = slot.cachedOffset();
+    PropertyOffset offset = slot.cachedOffset();
     size_t count = normalizePrototypeChain(exec, baseValue, slot.slotBase(), propertyName, offset);
     if (!count)
         return false;
@@ -567,7 +600,7 @@
     
     MacroAssembler stubJit;
     
-    if (scratchGPR == InvalidGPRReg && (writeBarrierNeeded || !structure->isUsingInlineStorage())) {
+    if (scratchGPR == InvalidGPRReg && (writeBarrierNeeded || isOutOfLineOffset(slot.cachedOffset()))) {
         scratchGPR = SpeculativeJIT::selectScratchGPR(baseGPR, valueGPR);
         needToRestoreScratch = true;
         stubJit.push(scratchGPR);
@@ -586,20 +619,20 @@
 #endif
     
 #if USE(JSVALUE64)
-    if (structure->isUsingInlineStorage())
-        stubJit.storePtr(valueGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + slot.cachedOffset() * sizeof(JSValue)));
+    if (isInlineOffset(slot.cachedOffset()))
+        stubJit.storePtr(valueGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue)));
     else {
-        stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), scratchGPR);
-        stubJit.storePtr(valueGPR, MacroAssembler::Address(scratchGPR, slot.cachedOffset() * sizeof(JSValue)));
+        stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR);
+        stubJit.storePtr(valueGPR, MacroAssembler::Address(scratchGPR, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue)));
     }
 #elif USE(JSVALUE32_64)
-    if (structure->isUsingInlineStorage()) {
-        stubJit.store32(valueGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + slot.cachedOffset() * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
-        stubJit.store32(valueTagGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + slot.cachedOffset() * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
+    if (isInlineOffset(slot.cachedOffset())) {
+        stubJit.store32(valueGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
+        stubJit.store32(valueTagGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
     } else {
-        stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), scratchGPR);
-        stubJit.store32(valueGPR, MacroAssembler::Address(scratchGPR, slot.cachedOffset() * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
-        stubJit.store32(valueTagGPR, MacroAssembler::Address(scratchGPR, slot.cachedOffset() * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
+        stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR);
+        stubJit.store32(valueGPR, MacroAssembler::Address(scratchGPR, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
+        stubJit.store32(valueTagGPR, MacroAssembler::Address(scratchGPR, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
     }
 #endif
     
@@ -685,20 +718,20 @@
 
     stubJit.storePtr(MacroAssembler::TrustedImmPtr(structure), MacroAssembler::Address(baseGPR, JSCell::structureOffset()));
 #if USE(JSVALUE64)
-    if (structure->isUsingInlineStorage())
-        stubJit.storePtr(valueGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + slot.cachedOffset() * sizeof(JSValue)));
+    if (isInlineOffset(slot.cachedOffset()))
+        stubJit.storePtr(valueGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue)));
     else {
-        stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), scratchGPR);
-        stubJit.storePtr(valueGPR, MacroAssembler::Address(scratchGPR, slot.cachedOffset() * sizeof(JSValue)));
+        stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR);
+        stubJit.storePtr(valueGPR, MacroAssembler::Address(scratchGPR, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue)));
     }
 #elif USE(JSVALUE32_64)
-    if (structure->isUsingInlineStorage()) {
-        stubJit.store32(valueGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + slot.cachedOffset() * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
-        stubJit.store32(valueTagGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + slot.cachedOffset() * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
+    if (isInlineOffset(slot.cachedOffset())) {
+        stubJit.store32(valueGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
+        stubJit.store32(valueTagGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
     } else {
-        stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), scratchGPR);
-        stubJit.store32(valueGPR, MacroAssembler::Address(scratchGPR, slot.cachedOffset() * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
-        stubJit.store32(valueTagGPR, MacroAssembler::Address(scratchGPR, slot.cachedOffset() * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
+        stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR);
+        stubJit.store32(valueGPR, MacroAssembler::Address(scratchGPR, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
+        stubJit.store32(valueTagGPR, MacroAssembler::Address(scratchGPR, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
     }
 #endif
             
@@ -752,7 +785,7 @@
                 return false;
             
             // skip optimizing the case where we need a realloc
-            if (oldStructure->propertyStorageCapacity() != structure->propertyStorageCapacity())
+            if (oldStructure->outOfLineCapacity() != structure->outOfLineCapacity())
                 return false;
             
             normalizePrototypeChain(exec, baseCell);
@@ -815,7 +848,7 @@
                 return false;
             
             // skip optimizing the case where we need a realloc
-            if (oldStructure->propertyStorageCapacity() != structure->propertyStorageCapacity())
+            if (oldStructure->outOfLineCapacity() != structure->outOfLineCapacity())
                 return false;
             
             normalizePrototypeChain(exec, baseCell);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
index 14316ac..57bc84a 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
@@ -2103,8 +2103,7 @@
         m_jit.storePtr(MacroAssembler::TrustedImmPtr(0), MacroAssembler::Address(resultGPR, JSObject::offsetOfInheritorID()));
         
         // Initialize the object's property storage pointer.
-        m_jit.addPtr(MacroAssembler::TrustedImm32(sizeof(JSObject)), resultGPR, scratchGPR);
-        m_jit.storePtr(scratchGPR, MacroAssembler::Address(resultGPR, ClassType::offsetOfPropertyStorage()));
+        m_jit.storePtr(MacroAssembler::TrustedImmPtr(0), MacroAssembler::Address(resultGPR, ClassType::offsetOfOutOfLineStorage()));
     }
 
     // It is acceptable to have structure be equal to scratch, so long as you're fine
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index df543a9..09bc334 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -508,7 +508,7 @@
     JITCompiler::DataLabelPtr structureToCompare;
     JITCompiler::PatchableJump structureCheck = m_jit.patchableBranchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(basePayloadGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
     
-    m_jit.loadPtr(JITCompiler::Address(basePayloadGPR, JSObject::offsetOfPropertyStorage()), resultPayloadGPR);
+    JITCompiler::ConvertibleLoadLabel propertyStorageLoad = m_jit.convertibleLoadPtr(JITCompiler::Address(basePayloadGPR, JSObject::offsetOfOutOfLineStorage()), resultPayloadGPR);
     JITCompiler::DataLabelCompact tagLoadWithPatch = m_jit.load32WithCompactAddressOffsetPatch(JITCompiler::Address(resultPayloadGPR, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
     JITCompiler::DataLabelCompact payloadLoadWithPatch = m_jit.load32WithCompactAddressOffsetPatch(JITCompiler::Address(resultPayloadGPR, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayloadGPR);
     
@@ -550,7 +550,7 @@
     }
     m_jit.addPropertyAccess(
         PropertyAccessRecord(
-            codeOrigin, structureToCompare, structureCheck,
+            codeOrigin, structureToCompare, structureCheck, propertyStorageLoad,
             tagLoadWithPatch, payloadLoadWithPatch, slowPath.get(), doneLabel,
             safeCast<int8_t>(basePayloadGPR), safeCast<int8_t>(resultTagGPR),
             safeCast<int8_t>(resultPayloadGPR), safeCast<int8_t>(scratchGPR),
@@ -565,7 +565,7 @@
 
     writeBarrier(basePayloadGPR, valueTagGPR, valueUse, WriteBarrierForPropertyAccess, scratchGPR);
 
-    m_jit.loadPtr(JITCompiler::Address(basePayloadGPR, JSObject::offsetOfPropertyStorage()), scratchGPR);
+    JITCompiler::ConvertibleLoadLabel propertyStorageLoad = m_jit.convertibleLoadPtr(JITCompiler::Address(basePayloadGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR);
     JITCompiler::DataLabel32 tagStoreWithPatch = m_jit.store32WithAddressOffsetPatch(valueTagGPR, JITCompiler::Address(scratchGPR, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
     JITCompiler::DataLabel32 payloadStoreWithPatch = m_jit.store32WithAddressOffsetPatch(valuePayloadGPR, JITCompiler::Address(scratchGPR, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
 
@@ -597,7 +597,7 @@
     }
     m_jit.addPropertyAccess(
         PropertyAccessRecord(
-            codeOrigin, structureToCompare, structureCheck,
+            codeOrigin, structureToCompare, structureCheck, propertyStorageLoad,
             JITCompiler::DataLabelCompact(tagStoreWithPatch.label()),
             JITCompiler::DataLabelCompact(payloadStoreWithPatch.label()),
             slowPath.get(), doneLabel, safeCast<int8_t>(basePayloadGPR),
@@ -3550,7 +3550,7 @@
         GPRReg baseGPR = base.gpr();
         GPRReg resultGPR = result.gpr();
         
-        m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
+        m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), resultGPR);
         
         storageResult(resultGPR, m_compileIndex);
         break;
@@ -3891,8 +3891,13 @@
         JITCompiler::Jump structuresNotMatch = m_jit.branchPtr(JITCompiler::NotEqual, resultPayloadGPR, JITCompiler::Address(globalObjectGPR, JSCell::structureOffset()));
 
         // Fast case
-        m_jit.loadPtr(JITCompiler::Address(globalObjectGPR, JSObject::offsetOfPropertyStorage()), resultPayloadGPR);
+        m_jit.loadPtr(JITCompiler::Address(globalObjectGPR, JSObject::offsetOfOutOfLineStorage()), resultPayloadGPR);
         m_jit.load32(JITCompiler::Address(resolveInfoGPR, OBJECT_OFFSETOF(GlobalResolveInfo, offset)), resolveInfoGPR);
+#if DFG_ENABLE(JIT_ASSERT)
+        JITCompiler::Jump isOutOfLine = m_jit.branch32(JITCompiler::GreaterThanOrEqual, resolveInfoGPR, TrustedImm32(inlineStorageCapacity));
+        m_jit.breakpoint();
+        isOutOfLine.link(&m_jit);
+#endif
         m_jit.load32(JITCompiler::BaseIndex(resultPayloadGPR, resolveInfoGPR, JITCompiler::TimesEight, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
         m_jit.load32(JITCompiler::BaseIndex(resultPayloadGPR, resolveInfoGPR, JITCompiler::TimesEight, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayloadGPR);
 
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index 54575aa..27eb28f 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -497,7 +497,8 @@
     JITCompiler::DataLabelPtr structureToCompare;
     JITCompiler::PatchableJump structureCheck = m_jit.patchableBranchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
     
-    m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
+    JITCompiler::ConvertibleLoadLabel propertyStorageLoad =
+        m_jit.convertibleLoadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), resultGPR);
     JITCompiler::DataLabelCompact loadWithPatch = m_jit.loadPtrWithCompactAddressOffsetPatch(JITCompiler::Address(resultGPR, 0), resultGPR);
     
     JITCompiler::Label doneLabel = m_jit.label();
@@ -517,8 +518,8 @@
     }
     m_jit.addPropertyAccess(
         PropertyAccessRecord(
-            codeOrigin, structureToCompare, structureCheck, loadWithPatch, slowPath.get(),
-            doneLabel, safeCast<int8_t>(baseGPR), safeCast<int8_t>(resultGPR),
+            codeOrigin, structureToCompare, structureCheck, propertyStorageLoad, loadWithPatch,
+            slowPath.get(), doneLabel, safeCast<int8_t>(baseGPR), safeCast<int8_t>(resultGPR),
             safeCast<int8_t>(scratchGPR),
             spillMode == NeedToSpill ? PropertyAccessRecord::RegistersInUse : PropertyAccessRecord::RegistersFlushed));
     addSlowPathGenerator(slowPath.release());
@@ -536,7 +537,8 @@
 
     writeBarrier(baseGPR, valueGPR, valueUse, WriteBarrierForPropertyAccess, scratchGPR);
 
-    m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), scratchGPR);
+    JITCompiler::ConvertibleLoadLabel propertyStorageLoad =
+        m_jit.convertibleLoadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR);
     JITCompiler::DataLabel32 storeWithPatch = m_jit.storePtrWithAddressOffsetPatch(valueGPR, JITCompiler::Address(scratchGPR, 0));
 
     JITCompiler::Label doneLabel = m_jit.label();
@@ -566,7 +568,11 @@
             slowCases, this, optimizedCall, NoResult, valueGPR, baseGPR,
             identifier(identifierNumber));
     }
-    m_jit.addPropertyAccess(PropertyAccessRecord(codeOrigin, structureToCompare, structureCheck, JITCompiler::DataLabelCompact(storeWithPatch.label()), slowPath.get(), doneLabel, safeCast<int8_t>(baseGPR), safeCast<int8_t>(valueGPR), safeCast<int8_t>(scratchGPR)));
+    m_jit.addPropertyAccess(
+        PropertyAccessRecord(
+            codeOrigin, structureToCompare, structureCheck, propertyStorageLoad,
+            JITCompiler::DataLabelCompact(storeWithPatch.label()), slowPath.get(), doneLabel,
+            safeCast<int8_t>(baseGPR), safeCast<int8_t>(valueGPR), safeCast<int8_t>(scratchGPR)));
     addSlowPathGenerator(slowPath.release());
 }
 
@@ -3574,7 +3580,7 @@
         GPRReg baseGPR = base.gpr();
         GPRReg resultGPR = result.gpr();
         
-        m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
+        m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), resultGPR);
         
         storageResult(resultGPR, m_compileIndex);
         break;
@@ -3890,9 +3896,14 @@
         JITCompiler::Jump structuresDontMatch = m_jit.branchPtr(JITCompiler::NotEqual, resultGPR, JITCompiler::Address(globalObjectGPR, JSCell::structureOffset()));
 
         // Fast case
-        m_jit.loadPtr(JITCompiler::Address(globalObjectGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
         m_jit.load32(JITCompiler::Address(resolveInfoGPR, OBJECT_OFFSETOF(GlobalResolveInfo, offset)), resolveInfoGPR);
-        m_jit.loadPtr(JITCompiler::BaseIndex(resultGPR, resolveInfoGPR, JITCompiler::ScalePtr), resultGPR);
+#if DFG_ENABLE(JIT_ASSERT)
+        JITCompiler::Jump isOutOfLine = m_jit.branch32(JITCompiler::GreaterThanOrEqual, resolveInfoGPR, TrustedImm32(inlineStorageCapacity));
+        m_jit.breakpoint();
+        isOutOfLine.link(&m_jit);
+#endif
+        m_jit.loadPtr(JITCompiler::Address(globalObjectGPR, JSObject::offsetOfOutOfLineStorage()), resultGPR);
+        m_jit.loadPtr(JITCompiler::BaseIndex(resultGPR, resolveInfoGPR, JITCompiler::ScalePtr, -inlineStorageCapacity * static_cast<ptrdiff_t>(sizeof(JSValue))), resultGPR);
         
         addSlowPathGenerator(
             slowPathCall(
diff --git a/Source/JavaScriptCore/heap/MarkStack.cpp b/Source/JavaScriptCore/heap/MarkStack.cpp
index 8c0fe66..f547b31 100644
--- a/Source/JavaScriptCore/heap/MarkStack.cpp
+++ b/Source/JavaScriptCore/heap/MarkStack.cpp
@@ -354,7 +354,7 @@
     }
 
     if (isJSFinalObject(cell)) {
-        JSObject::visitChildren(const_cast<JSCell*>(cell), visitor);
+        JSFinalObject::visitChildren(const_cast<JSCell*>(cell), visitor);
         return;
     }
 
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index 4fdd79a..b6072a5 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -1822,7 +1822,7 @@
         ASSERT(slot.slotBase().isObject());
 
         JSObject* baseObject = asObject(slot.slotBase());
-        size_t offset = slot.cachedOffset();
+        PropertyOffset offset = slot.cachedOffset();
 
         // Since we're accessing a prototype in a loop, it's a good bet that it
         // should not be treated as a dictionary.
@@ -1851,7 +1851,7 @@
         return;
     }
 
-    size_t offset = slot.cachedOffset();
+    PropertyOffset offset = slot.cachedOffset();
     size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset);
     if (!count) {
         vPC[0] = getOpcode(op_get_by_id_generic);
@@ -3045,6 +3045,7 @@
         vPC += OPCODE_LENGTH(op_resolve_with_this);
         NEXT_INSTRUCTION();
     }
+    DEFINE_OPCODE(op_get_by_id_out_of_line)
     DEFINE_OPCODE(op_get_by_id) {
         /* get_by_id dst(r) base(r) property(id) structure(sID) nop(n) nop(n) nop(n)
 
@@ -3527,6 +3528,7 @@
     skip_get_string_length:
     goto *(&&skip_put_by_id);
 #endif
+    DEFINE_OPCODE(op_put_by_id_out_of_line)
     DEFINE_OPCODE(op_put_by_id) {
         /* put_by_id base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) direct(b)
 
@@ -3565,6 +3567,8 @@
 #endif
     DEFINE_OPCODE(op_put_by_id_transition_direct)
     DEFINE_OPCODE(op_put_by_id_transition_normal)
+    DEFINE_OPCODE(op_put_by_id_transition_direct_out_of_line)
+    DEFINE_OPCODE(op_put_by_id_transition_normal_out_of_line)
     DEFINE_OPCODE(op_put_by_id_transition) {
         /* op_put_by_id_transition base(r) property(id) value(r) oldStructure(sID) newStructure(sID) structureChain(chain) offset(n) direct(b)
          
@@ -3605,7 +3609,7 @@
                 baseObject->setStructureAndReallocateStorageIfNecessary(*globalData, newStructure);
 
                 int value = vPC[3].u.operand;
-                unsigned offset = vPC[7].u.operand;
+                int offset = vPC[7].u.operand;
                 ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(*globalData, codeBlock->identifier(vPC[2].u.operand))) == offset);
                 baseObject->putDirectOffset(callFrame->globalData(), offset, callFrame->r(value).jsValue());
 
@@ -3639,7 +3643,7 @@
                 ASSERT(baseCell->isObject());
                 JSObject* baseObject = asObject(baseCell);
                 int value = vPC[3].u.operand;
-                unsigned offset = vPC[5].u.operand;
+                int offset = vPC[5].u.operand;
                 
                 ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(*globalData, codeBlock->identifier(vPC[2].u.operand))) == offset);
                 baseObject->putDirectOffset(callFrame->globalData(), offset, callFrame->r(value).jsValue());
@@ -3717,7 +3721,7 @@
         JSValue expectedSubscript = callFrame->r(expected).jsValue();
         int index = callFrame->r(i).i() - 1;
         JSValue result;
-        int offset = 0;
+        PropertyOffset offset = 0;
         if (subscript == expectedSubscript && baseValue.isCell() && (baseValue.asCell()->structure() == it->cachedStructure()) && it->getOffset(index, offset)) {
             callFrame->uncheckedR(dst) = JSValue(asObject(baseValue)->getDirectOffset(offset));
             vPC += OPCODE_LENGTH(op_get_by_pname);
diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp
index 1bc4fff..285355f 100644
--- a/Source/JavaScriptCore/jit/JIT.cpp
+++ b/Source/JavaScriptCore/jit/JIT.cpp
@@ -255,6 +255,7 @@
         DEFINE_OP(op_create_activation)
         DEFINE_OP(op_eq)
         DEFINE_OP(op_eq_null)
+        case op_get_by_id_out_of_line:
         DEFINE_OP(op_get_by_id)
         DEFINE_OP(op_get_arguments_length)
         DEFINE_OP(op_get_by_val)
@@ -319,8 +320,11 @@
         DEFINE_OP(op_profile_will_call)
         DEFINE_OP(op_push_new_scope)
         DEFINE_OP(op_push_scope)
+        case op_put_by_id_out_of_line:
         case op_put_by_id_transition_direct:
         case op_put_by_id_transition_normal:
+        case op_put_by_id_transition_direct_out_of_line:
+        case op_put_by_id_transition_normal_out_of_line:
         DEFINE_OP(op_put_by_id)
         DEFINE_OP(op_put_by_index)
         DEFINE_OP(op_put_by_val)
@@ -441,6 +445,7 @@
         DEFINE_SLOWCASE_OP(op_create_this)
         DEFINE_SLOWCASE_OP(op_div)
         DEFINE_SLOWCASE_OP(op_eq)
+        case op_get_by_id_out_of_line:
         DEFINE_SLOWCASE_OP(op_get_by_id)
         DEFINE_SLOWCASE_OP(op_get_arguments_length)
         DEFINE_SLOWCASE_OP(op_get_by_val)
@@ -478,8 +483,11 @@
         DEFINE_SLOWCASE_OP(op_post_inc)
         DEFINE_SLOWCASE_OP(op_pre_dec)
         DEFINE_SLOWCASE_OP(op_pre_inc)
+        case op_put_by_id_out_of_line:
         case op_put_by_id_transition_direct:
         case op_put_by_id_transition_normal:
+        case op_put_by_id_transition_direct_out_of_line:
+        case op_put_by_id_transition_normal_out_of_line:
         DEFINE_SLOWCASE_OP(op_put_by_id)
         DEFINE_SLOWCASE_OP(op_put_by_val)
         DEFINE_SLOWCASE_OP(op_put_global_var_check);
@@ -537,6 +545,7 @@
         CodeLocationLabel hotPathBeginLocation = linkBuffer.locationOf(hotPathBegin);
         info.patch.baseline.u.get.structureToCompare = MacroAssembler::differenceBetweenCodePtr(hotPathBeginLocation, linkBuffer.locationOf(getStructureToCompare));
         info.patch.baseline.u.get.structureCheck = MacroAssembler::differenceBetweenCodePtr(hotPathBeginLocation, linkBuffer.locationOf(getStructureCheck));
+        info.patch.baseline.u.get.propertyStorageLoad = MacroAssembler::differenceBetweenCodePtr(hotPathBeginLocation, linkBuffer.locationOf(propertyStorageLoad));
 #if USE(JSVALUE64)
         info.patch.baseline.u.get.displacementLabel = MacroAssembler::differenceBetweenCodePtr(hotPathBeginLocation, linkBuffer.locationOf(getDisplacementLabel));
 #else
@@ -550,6 +559,7 @@
     case PutById:
         CodeLocationLabel hotPathBeginLocation = linkBuffer.locationOf(hotPathBegin);
         info.patch.baseline.u.put.structureToCompare = MacroAssembler::differenceBetweenCodePtr(hotPathBeginLocation, linkBuffer.locationOf(putStructureToCompare));
+        info.patch.baseline.u.put.propertyStorageLoad = MacroAssembler::differenceBetweenCodePtr(hotPathBeginLocation, linkBuffer.locationOf(propertyStorageLoad));
 #if USE(JSVALUE64)
         info.patch.baseline.u.put.displacementLabel = MacroAssembler::differenceBetweenCodePtr(hotPathBeginLocation, linkBuffer.locationOf(putDisplacementLabel));
 #else
diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h
index 67aa185..987c4a1 100644
--- a/Source/JavaScriptCore/jit/JIT.h
+++ b/Source/JavaScriptCore/jit/JIT.h
@@ -157,6 +157,7 @@
         MacroAssembler::Label hotPathBegin;
         MacroAssembler::DataLabelPtr getStructureToCompare;
         MacroAssembler::PatchableJump getStructureCheck;
+        MacroAssembler::ConvertibleLoadLabel propertyStorageLoad;
 #if USE(JSVALUE64)
         MacroAssembler::DataLabelCompact getDisplacementLabel;
 #else
@@ -185,17 +186,24 @@
 #endif
 
 
-        PropertyStubCompilationInfo(PropertyStubGetById_T, unsigned bytecodeIndex, MacroAssembler::Label hotPathBegin,
+        PropertyStubCompilationInfo(
+            PropertyStubGetById_T, unsigned bytecodeIndex, MacroAssembler::Label hotPathBegin,
+            MacroAssembler::DataLabelPtr structureToCompare,
+            MacroAssembler::PatchableJump structureCheck,
+            MacroAssembler::ConvertibleLoadLabel propertyStorageLoad,
 #if USE(JSVALUE64)
-            MacroAssembler::DataLabelPtr structureToCompare, MacroAssembler::PatchableJump structureCheck, MacroAssembler::DataLabelCompact displacementLabel, MacroAssembler::Label putResult)
+            MacroAssembler::DataLabelCompact displacementLabel,
 #else
-            MacroAssembler::DataLabelPtr structureToCompare, MacroAssembler::PatchableJump structureCheck, MacroAssembler::DataLabelCompact displacementLabel1, MacroAssembler::DataLabelCompact displacementLabel2, MacroAssembler::Label putResult)
+            MacroAssembler::DataLabelCompact displacementLabel1,
+            MacroAssembler::DataLabelCompact displacementLabel2,
 #endif
+            MacroAssembler::Label putResult)
             : m_type(GetById)
             , bytecodeIndex(bytecodeIndex)
             , hotPathBegin(hotPathBegin)
             , getStructureToCompare(structureToCompare)
             , getStructureCheck(structureCheck)
+            , propertyStorageLoad(propertyStorageLoad)
 #if USE(JSVALUE64)
             , getDisplacementLabel(displacementLabel)
 #else
@@ -206,15 +214,21 @@
         {
         }
 
-        PropertyStubCompilationInfo(PropertyStubPutById_T, unsigned bytecodeIndex, MacroAssembler::Label hotPathBegin,
+        PropertyStubCompilationInfo(
+            PropertyStubPutById_T, unsigned bytecodeIndex, MacroAssembler::Label hotPathBegin,
+            MacroAssembler::DataLabelPtr structureToCompare,
+            MacroAssembler::ConvertibleLoadLabel propertyStorageLoad,
 #if USE(JSVALUE64)
-            MacroAssembler::DataLabelPtr structureToCompare, MacroAssembler::DataLabel32 displacementLabel)
+            MacroAssembler::DataLabel32 displacementLabel
 #else
-            MacroAssembler::DataLabelPtr structureToCompare, MacroAssembler::DataLabel32 displacementLabel1, MacroAssembler::DataLabel32 displacementLabel2)
+            MacroAssembler::DataLabel32 displacementLabel1,
+            MacroAssembler::DataLabel32 displacementLabel2
 #endif
+            )
             : m_type(PutById)
             , bytecodeIndex(bytecodeIndex)
             , hotPathBegin(hotPathBegin)
+            , propertyStorageLoad(propertyStorageLoad)
             , putStructureToCompare(structureToCompare)
 #if USE(JSVALUE64)
             , putDisplacementLabel(displacementLabel)
@@ -295,40 +309,40 @@
             return JIT(globalData, codeBlock).privateCompile(functionEntryArityCheck, effort);
         }
 
-        static void compileGetByIdProto(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress)
+        static void compileGetByIdProto(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress)
         {
             JIT jit(globalData, codeBlock);
             jit.m_bytecodeOffset = stubInfo->bytecodeIndex;
             jit.privateCompileGetByIdProto(stubInfo, structure, prototypeStructure, ident, slot, cachedOffset, returnAddress, callFrame);
         }
 
-        static void compileGetByIdSelfList(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset)
+        static void compileGetByIdSelfList(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
         {
             JIT jit(globalData, codeBlock);
             jit.m_bytecodeOffset = stubInfo->bytecodeIndex;
             jit.privateCompileGetByIdSelfList(stubInfo, polymorphicStructures, currentIndex, structure, ident, slot, cachedOffset);
         }
-        static void compileGetByIdProtoList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset)
+        static void compileGetByIdProtoList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
         {
             JIT jit(globalData, codeBlock);
             jit.m_bytecodeOffset = stubInfo->bytecodeIndex;
             jit.privateCompileGetByIdProtoList(stubInfo, prototypeStructureList, currentIndex, structure, prototypeStructure, ident, slot, cachedOffset, callFrame);
         }
-        static void compileGetByIdChainList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset)
+        static void compileGetByIdChainList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
         {
             JIT jit(globalData, codeBlock);
             jit.m_bytecodeOffset = stubInfo->bytecodeIndex;
             jit.privateCompileGetByIdChainList(stubInfo, prototypeStructureList, currentIndex, structure, chain, count, ident, slot, cachedOffset, callFrame);
         }
 
-        static void compileGetByIdChain(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress)
+        static void compileGetByIdChain(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress)
         {
             JIT jit(globalData, codeBlock);
             jit.m_bytecodeOffset = stubInfo->bytecodeIndex;
             jit.privateCompileGetByIdChain(stubInfo, structure, chain, count, ident, slot, cachedOffset, returnAddress, callFrame);
         }
         
-        static void compilePutByIdTransition(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
+        static void compilePutByIdTransition(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, PropertyOffset cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
         {
             JIT jit(globalData, codeBlock);
             jit.m_bytecodeOffset = stubInfo->bytecodeIndex;
@@ -358,9 +372,9 @@
 
         static void resetPatchGetById(RepatchBuffer&, StructureStubInfo*);
         static void resetPatchPutById(RepatchBuffer&, StructureStubInfo*);
-        static void patchGetByIdSelf(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress);
-        static void patchPutByIdReplace(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress, bool direct);
-        static void patchMethodCallProto(JSGlobalData&, CodeBlock* codeblock, MethodCallLinkInfo&, StructureStubInfo&, JSObject*, Structure*, JSObject*, ReturnAddressPtr);
+        static void patchGetByIdSelf(CodeBlock*, StructureStubInfo*, Structure*, PropertyOffset cachedOffset, ReturnAddressPtr);
+        static void patchPutByIdReplace(CodeBlock*, StructureStubInfo*, Structure*, PropertyOffset cachedOffset, ReturnAddressPtr, bool direct);
+        static void patchMethodCallProto(JSGlobalData&, CodeBlock*, MethodCallLinkInfo&, StructureStubInfo&, JSObject*, Structure*, JSObject*, ReturnAddressPtr);
 
         static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, ReturnAddressPtr returnAddress)
         {
@@ -377,12 +391,12 @@
         void privateCompileLinkPass();
         void privateCompileSlowCases();
         JITCode privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffort);
-        void privateCompileGetByIdProto(StructureStubInfo*, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame);
-        void privateCompileGetByIdSelfList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, const Identifier&, const PropertySlot&, size_t cachedOffset);
-        void privateCompileGetByIdProtoList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, size_t cachedOffset, CallFrame* callFrame);
-        void privateCompileGetByIdChainList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, StructureChain* chain, size_t count, const Identifier&, const PropertySlot&, size_t cachedOffset, CallFrame* callFrame);
-        void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, const Identifier&, const PropertySlot&, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame);
-        void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, ReturnAddressPtr returnAddress, bool direct);
+        void privateCompileGetByIdProto(StructureStubInfo*, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, PropertyOffset cachedOffset, ReturnAddressPtr, CallFrame*);
+        void privateCompileGetByIdSelfList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, const Identifier&, const PropertySlot&, PropertyOffset cachedOffset);
+        void privateCompileGetByIdProtoList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, PropertyOffset cachedOffset, CallFrame*);
+        void privateCompileGetByIdChainList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, StructureChain*, size_t count, const Identifier&, const PropertySlot&, PropertyOffset cachedOffset, CallFrame*);
+        void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, const Identifier&, const PropertySlot&, PropertyOffset cachedOffset, ReturnAddressPtr, CallFrame*);
+        void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, PropertyOffset cachedOffset, StructureChain*, ReturnAddressPtr, bool direct);
 
         PassRefPtr<ExecutableMemoryHandle> privateCompileCTIMachineTrampolines(JSGlobalData*, TrampolineStructure*);
         Label privateCompileCTINativeCall(JSGlobalData*, bool isConstruct = false);
@@ -436,6 +450,8 @@
         void emitValueProfilingSite() { }
 #endif
 
+        enum FinalObjectMode { MayBeFinal, KnownNotFinal };
+
 #if USE(JSVALUE32_64)
         bool getOperandConstantImmediateInt(unsigned op1, unsigned op2, unsigned& op, int32_t& constant);
 
@@ -468,10 +484,10 @@
 
         void compileGetByIdHotPath();
         void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false);
-        void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset);
-        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, size_t cachedOffset);
+        void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, PropertyOffset cachedOffset);
+        void compileGetDirectOffset(JSObject* base, RegisterID resultTag, RegisterID resultPayload, PropertyOffset cachedOffset);
+        void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID offset, FinalObjectMode = MayBeFinal);
+        void compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, PropertyOffset cachedOffset);
 
         // Arithmetic opcode helpers
         void emitAdd32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType);
@@ -547,10 +563,10 @@
 
         void compileGetByIdHotPath(int baseVReg, Identifier*);
         void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false);
-        void compileGetDirectOffset(RegisterID base, RegisterID result, size_t cachedOffset);
-        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, size_t cachedOffset);
+        void compileGetDirectOffset(RegisterID base, RegisterID result, PropertyOffset cachedOffset);
+        void compileGetDirectOffset(JSObject* base, RegisterID result, PropertyOffset cachedOffset);
+        void compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID offset, RegisterID scratch, FinalObjectMode = MayBeFinal);
+        void compilePutDirectOffset(RegisterID base, RegisterID value, PropertyOffset cachedOffset);
 
 #endif // USE(JSVALUE32_64)
 
diff --git a/Source/JavaScriptCore/jit/JITInlineMethods.h b/Source/JavaScriptCore/jit/JITInlineMethods.h
index fdb9564..d1cee7e 100644
--- a/Source/JavaScriptCore/jit/JITInlineMethods.h
+++ b/Source/JavaScriptCore/jit/JITInlineMethods.h
@@ -429,11 +429,7 @@
     storePtr(TrustedImmPtr(0), Address(result, JSObject::offsetOfInheritorID()));
 
     // initialize the object's property storage pointer
-    if (ClassType::hasInlineStorage()) {
-        addPtr(TrustedImm32(sizeof(JSObject)), result, storagePtr);
-        storePtr(storagePtr, Address(result, ClassType::offsetOfPropertyStorage()));
-    } else
-        storePtr(TrustedImmPtr(0), Address(result, ClassType::offsetOfPropertyStorage()));
+    storePtr(TrustedImmPtr(0), Address(result, ClassType::offsetOfOutOfLineStorage()));
 }
 
 template <typename T> inline void JIT::emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID scratch)
diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp
index d96cfd9..c0af6f9 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp
@@ -701,9 +701,8 @@
 
     // Load cached property
     // Assume that the global object always uses external storage.
-    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_propertyStorage)), regT0);
     load32(Address(regT2, OBJECT_OFFSETOF(GlobalResolveInfo, offset)), regT1);
-    loadPtr(BaseIndex(regT0, regT1, ScalePtr), regT0);
+    compileGetDirectOffset(regT0, regT0, regT1, regT0, KnownNotFinal);
     emitValueProfilingSite();
     emitPutVirtualRegister(currentInstruction[1].u.operand);
 }
diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
index 4f85895..095ea57 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -794,16 +794,14 @@
 
 
     // Verify structure.
-    move(TrustedImmPtr(globalObject), regT0);
+    move(TrustedImmPtr(globalObject), regT2);
     move(TrustedImmPtr(resolveInfoAddress), regT3);
     loadPtr(Address(regT3, OBJECT_OFFSETOF(GlobalResolveInfo, structure)), regT1);
-    addSlowCase(branchPtr(NotEqual, regT1, Address(regT0, JSCell::structureOffset())));
+    addSlowCase(branchPtr(NotEqual, regT1, Address(regT2, JSCell::structureOffset())));
 
     // Load property.
-    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_propertyStorage)), regT2);
     load32(Address(regT3, OBJECT_OFFSETOF(GlobalResolveInfo, offset)), 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
+    compileGetDirectOffset(regT2, regT1, regT0, regT3, KnownNotFinal);
     emitValueProfilingSite();
     emitStore(dst, regT1, regT0);
     map(m_bytecodeOffset + (dynamic ? OPCODE_LENGTH(op_resolve_global_dynamic) : OPCODE_LENGTH(op_resolve_global)), dst, regT1, regT0);
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
index 7478f91..72f8d47 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -151,10 +151,26 @@
     emitValueProfilingSite();
 }
 
-void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID offset, RegisterID scratch)
+void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID offset, RegisterID scratch, FinalObjectMode finalObjectMode)
 {
-    loadPtr(Address(base, JSObject::offsetOfPropertyStorage()), scratch);
-    loadPtr(BaseIndex(scratch, offset, ScalePtr, 0), result);
+    ASSERT(sizeof(JSValue) == 8);
+    
+    if (finalObjectMode == MayBeFinal) {
+        Jump isInline = branch32(LessThan, offset, TrustedImm32(inlineStorageCapacity));
+        loadPtr(Address(base, JSObject::offsetOfOutOfLineStorage()), scratch);
+        Jump done = jump();
+        isInline.link(this);
+        addPtr(TrustedImm32(JSObject::offsetOfInlineStorage() + inlineStorageCapacity * sizeof(EncodedJSValue)), base, scratch);
+        done.link(this);
+    } else {
+#if !ASSERT_DISABLED
+        Jump isOutOfLine = branch32(GreaterThanOrEqual, offset, TrustedImm32(inlineStorageCapacity));
+        breakpoint();
+        isOutOfLine.link(this);
+#endif
+        loadPtr(Address(base, JSObject::offsetOfOutOfLineStorage()), scratch);
+    }
+    loadPtr(BaseIndex(scratch, offset, ScalePtr, -inlineStorageCapacity * static_cast<ptrdiff_t>(sizeof(JSValue))), result);
 }
 
 void JIT::emit_op_get_by_pname(Instruction* currentInstruction)
@@ -283,7 +299,8 @@
 void JIT::emit_op_method_check(Instruction* currentInstruction)
 {
     // Assert that the following instruction is a get_by_id.
-    ASSERT(m_interpreter->getOpcodeID((currentInstruction + OPCODE_LENGTH(op_method_check))->u.opcode) == op_get_by_id);
+    ASSERT(m_interpreter->getOpcodeID((currentInstruction + OPCODE_LENGTH(op_method_check))->u.opcode) == op_get_by_id
+        || m_interpreter->getOpcodeID((currentInstruction + OPCODE_LENGTH(op_method_check))->u.opcode) == op_get_by_id_out_of_line);
 
     currentInstruction += OPCODE_LENGTH(op_method_check);
     unsigned resultVReg = currentInstruction[1].u.operand;
@@ -373,14 +390,14 @@
     PatchableJump structureCheck = patchableBranchPtrWithPatch(NotEqual, Address(regT0, JSCell::structureOffset()), structureToCompare, TrustedImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
     addSlowCase(structureCheck);
 
-    loadPtr(Address(regT0, JSObject::offsetOfPropertyStorage()), regT0);
+    ConvertibleLoadLabel propertyStorageLoad = convertibleLoadPtr(Address(regT0, JSObject::offsetOfOutOfLineStorage()), regT0);
     DataLabelCompact displacementLabel = loadPtrWithCompactAddressOffsetPatch(Address(regT0, patchGetByIdDefaultOffset), regT0);
 
     Label putResult(this);
 
     END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdHotPath);
 
-    m_propertyAccessCompilationInfo.append(PropertyStubCompilationInfo(PropertyStubGetById, m_bytecodeOffset, hotPathBegin, structureToCompare, structureCheck, displacementLabel, putResult));
+    m_propertyAccessCompilationInfo.append(PropertyStubCompilationInfo(PropertyStubGetById, m_bytecodeOffset, hotPathBegin, structureToCompare, structureCheck, propertyStorageLoad, displacementLabel, putResult));
 }
 
 void JIT::emitSlow_op_get_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
@@ -440,14 +457,14 @@
     DataLabelPtr structureToCompare;
     addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, JSCell::structureOffset()), structureToCompare, TrustedImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))));
 
-    loadPtr(Address(regT0, JSObject::offsetOfPropertyStorage()), regT2);
+    ConvertibleLoadLabel propertyStorageLoad = convertibleLoadPtr(Address(regT0, JSObject::offsetOfOutOfLineStorage()), regT2);
     DataLabel32 displacementLabel = storePtrWithAddressOffsetPatch(regT1, Address(regT2, patchPutByIdDefaultOffset));
 
     END_UNINTERRUPTED_SEQUENCE(sequencePutById);
 
     emitWriteBarrier(regT0, regT1, regT2, regT3, ShouldFilterImmediates, WriteBarrierForPropertyAccess);
 
-    m_propertyAccessCompilationInfo.append(PropertyStubCompilationInfo(PropertyStubPutById, m_bytecodeOffset, hotPathBegin, structureToCompare, displacementLabel));
+    m_propertyAccessCompilationInfo.append(PropertyStubCompilationInfo(PropertyStubPutById, m_bytecodeOffset, hotPathBegin, structureToCompare, propertyStorageLoad, displacementLabel));
 }
 
 void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
@@ -471,28 +488,41 @@
 
 // Compile a store into an object's property storage.  May overwrite the
 // value in objectReg.
-void JIT::compilePutDirectOffset(RegisterID base, RegisterID value, size_t cachedOffset)
+void JIT::compilePutDirectOffset(RegisterID base, RegisterID value, PropertyOffset cachedOffset)
 {
-    int offset = cachedOffset * sizeof(JSValue);
-    loadPtr(Address(base, JSObject::offsetOfPropertyStorage()), base);
-    storePtr(value, Address(base, offset));
+    if (isInlineOffset(cachedOffset)) {
+        storePtr(value, Address(base, JSObject::offsetOfInlineStorage() + sizeof(JSValue) * offsetInInlineStorage(cachedOffset)));
+        return;
+    }
+    
+    loadPtr(Address(base, JSObject::offsetOfOutOfLineStorage()), base);
+    storePtr(value, Address(base, sizeof(JSValue) * offsetInOutOfLineStorage(cachedOffset)));
 }
 
 // Compile a load from an object's property storage.  May overwrite base.
-void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, size_t cachedOffset)
+void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, PropertyOffset cachedOffset)
 {
-    int offset = cachedOffset * sizeof(JSValue);
-    loadPtr(Address(base, JSObject::offsetOfPropertyStorage()), result);
-    loadPtr(Address(result, offset), result);
+    if (isInlineOffset(cachedOffset)) {
+        loadPtr(Address(base, JSObject::offsetOfInlineStorage() + sizeof(JSValue) * offsetInInlineStorage(cachedOffset)), result);
+        return;
+    }
+    
+    loadPtr(Address(base, JSObject::offsetOfOutOfLineStorage()), result);
+    loadPtr(Address(result, sizeof(JSValue) * offsetInOutOfLineStorage(cachedOffset)), result);
 }
 
-void JIT::compileGetDirectOffset(JSObject* base, RegisterID result, size_t cachedOffset)
+void JIT::compileGetDirectOffset(JSObject* base, RegisterID result, PropertyOffset cachedOffset)
 {
-    loadPtr(base->addressOfPropertyStorage(), result);
-    loadPtr(Address(result, cachedOffset * sizeof(WriteBarrier<Unknown>)), result);
+    if (isInlineOffset(cachedOffset)) {
+        loadPtr(base->locationForOffset(cachedOffset), result);
+        return;
+    }
+    
+    loadPtr(base->addressOfOutOfLineStorage(), result);
+    loadPtr(Address(result, offsetInOutOfLineStorage(cachedOffset) * sizeof(WriteBarrier<Unknown>)), result);
 }
 
-void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
+void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, PropertyOffset cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
 {
     JumpList failureCases;
     // Check eax is an object of the right Structure.
@@ -522,7 +552,7 @@
 #endif
     
     // emit a call only if storage realloc is needed
-    bool willNeedStorageRealloc = oldStructure->propertyStorageCapacity() != newStructure->propertyStorageCapacity();
+    bool willNeedStorageRealloc = oldStructure->outOfLineCapacity() != newStructure->outOfLineCapacity();
     if (willNeedStorageRealloc) {
         // This trampoline was called to like a JIT stub; before we can can call again we need to
         // remove the return address from the stack, to prevent the stack from becoming misaligned.
@@ -532,7 +562,7 @@
         stubCall.skipArgument(); // base
         stubCall.skipArgument(); // ident
         stubCall.skipArgument(); // value
-        stubCall.addArgument(TrustedImm32(oldStructure->propertyStorageCapacity()));
+        stubCall.addArgument(TrustedImm32(oldStructure->outOfLineCapacity()));
         stubCall.addArgument(TrustedImmPtr(newStructure));
         stubCall.call(regT0);
         emitGetJITStubArg(2, regT1);
@@ -572,7 +602,7 @@
     repatchBuffer.relinkCallerToTrampoline(returnAddress, CodeLocationLabel(stubInfo->stubRoutine.code()));
 }
 
-void JIT::patchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress)
+void JIT::patchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress)
 {
     RepatchBuffer repatchBuffer(codeBlock);
 
@@ -580,14 +610,13 @@
     // Should probably go to cti_op_get_by_id_fail, but that doesn't do anything interesting right now.
     repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_self_fail));
 
-    int offset = sizeof(JSValue) * cachedOffset;
-
     // Patch the offset into the propoerty map to load from, then patch the Structure to look for.
     repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(stubInfo->patch.baseline.u.get.structureToCompare), structure);
-    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelCompactAtOffset(stubInfo->patch.baseline.u.get.displacementLabel), offset);
+    repatchBuffer.setLoadInstructionIsActive(stubInfo->hotPathBegin.convertibleLoadAtOffset(stubInfo->patch.baseline.u.get.propertyStorageLoad), isOutOfLineOffset(cachedOffset));
+    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelCompactAtOffset(stubInfo->patch.baseline.u.get.displacementLabel), offsetRelativeToPatchedStorage(cachedOffset));
 }
 
-void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress, bool direct)
+void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress, bool direct)
 {
     RepatchBuffer repatchBuffer(codeBlock);
 
@@ -595,11 +624,10 @@
     // Should probably go to cti_op_put_by_id_fail, but that doesn't do anything interesting right now.
     repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
 
-    int offset = sizeof(JSValue) * cachedOffset;
-
     // Patch the offset into the propoerty map to load from, then patch the Structure to look for.
     repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(stubInfo->patch.baseline.u.put.structureToCompare), structure);
-    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(stubInfo->patch.baseline.u.put.displacementLabel), offset);
+    repatchBuffer.setLoadInstructionIsActive(stubInfo->hotPathBegin.convertibleLoadAtOffset(stubInfo->patch.baseline.u.put.propertyStorageLoad), isOutOfLineOffset(cachedOffset));
+    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(stubInfo->patch.baseline.u.put.displacementLabel), offsetRelativeToPatchedStorage(cachedOffset));
 }
 
 void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
@@ -643,7 +671,7 @@
     repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_array_fail));
 }
 
-void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
+void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
 {
     // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is
     // referencing the prototype object - let's speculatively load it's table nice and early!)
@@ -710,7 +738,7 @@
     repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list));
 }
 
-void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset)
+void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
 {
     Jump failureCase = checkStructure(regT0, structure);
     bool needsStubLink = false;
@@ -770,7 +798,7 @@
     repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubCode.code()));
 }
 
-void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, CallFrame* callFrame)
+void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, CallFrame* callFrame)
 {
     // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is
     // referencing the prototype object - let's speculatively load it's table nice and early!)
@@ -839,7 +867,7 @@
     repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubCode.code()));
 }
 
-void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, CallFrame* callFrame)
+void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, CallFrame* callFrame)
 {
     ASSERT(count);
     JumpList bucketsOfFail;
@@ -914,7 +942,7 @@
     repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine.code()));
 }
 
-void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
+void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
 {
     ASSERT(count);
 
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
index a44c576..799e958 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
@@ -93,7 +93,8 @@
 void JIT::emit_op_method_check(Instruction* currentInstruction)
 {
     // Assert that the following instruction is a get_by_id.
-    ASSERT(m_interpreter->getOpcodeID((currentInstruction + OPCODE_LENGTH(op_method_check))->u.opcode) == op_get_by_id);
+    ASSERT(m_interpreter->getOpcodeID((currentInstruction + OPCODE_LENGTH(op_method_check))->u.opcode) == op_get_by_id
+        || m_interpreter->getOpcodeID((currentInstruction + OPCODE_LENGTH(op_method_check))->u.opcode) == op_get_by_id_out_of_line);
     
     currentInstruction += OPCODE_LENGTH(op_method_check);
     
@@ -333,7 +334,7 @@
     PatchableJump structureCheck = patchableBranchPtrWithPatch(NotEqual, Address(regT0, JSCell::structureOffset()), structureToCompare, TrustedImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
     addSlowCase(structureCheck);
     
-    loadPtr(Address(regT0, JSObject::offsetOfPropertyStorage()), regT2);
+    ConvertibleLoadLabel propertyStorageLoad = convertibleLoadPtr(Address(regT0, JSObject::offsetOfOutOfLineStorage()), regT2);
     DataLabelCompact displacementLabel1 = loadPtrWithCompactAddressOffsetPatch(Address(regT2, patchGetByIdDefaultOffset), regT0); // payload
     DataLabelCompact displacementLabel2 = loadPtrWithCompactAddressOffsetPatch(Address(regT2, patchGetByIdDefaultOffset), regT1); // tag
     
@@ -341,7 +342,7 @@
     
     END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdHotPath);
 
-    m_propertyAccessCompilationInfo.append(PropertyStubCompilationInfo(PropertyStubGetById, m_bytecodeOffset, hotPathBegin, structureToCompare, structureCheck, displacementLabel1, displacementLabel2, putResult));
+    m_propertyAccessCompilationInfo.append(PropertyStubCompilationInfo(PropertyStubGetById, m_bytecodeOffset, hotPathBegin, structureToCompare, structureCheck, propertyStorageLoad, displacementLabel1, displacementLabel2, putResult));
 }
 
 void JIT::emitSlow_op_get_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
@@ -399,7 +400,7 @@
     DataLabelPtr structureToCompare;
     addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, JSCell::structureOffset()), structureToCompare, TrustedImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))));
     
-    loadPtr(Address(regT0, JSObject::offsetOfPropertyStorage()), regT1);
+    ConvertibleLoadLabel propertyStorageLoad = convertibleLoadPtr(Address(regT0, JSObject::offsetOfOutOfLineStorage()), regT1);
     DataLabel32 displacementLabel1 = storePtrWithAddressOffsetPatch(regT2, Address(regT1, patchPutByIdDefaultOffset)); // payload
     DataLabel32 displacementLabel2 = storePtrWithAddressOffsetPatch(regT3, Address(regT1, patchPutByIdDefaultOffset)); // tag
     
@@ -407,7 +408,7 @@
 
     emitWriteBarrier(regT0, regT2, regT1, regT2, ShouldFilterImmediates, WriteBarrierForPropertyAccess);
 
-    m_propertyAccessCompilationInfo.append(PropertyStubCompilationInfo(PropertyStubPutById, m_bytecodeOffset, hotPathBegin, structureToCompare, displacementLabel1, displacementLabel2));
+    m_propertyAccessCompilationInfo.append(PropertyStubCompilationInfo(PropertyStubPutById, m_bytecodeOffset, hotPathBegin, structureToCompare, propertyStorageLoad, displacementLabel1, displacementLabel2));
 }
 
 void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
@@ -430,30 +431,41 @@
 }
 
 // Compile a store into an object's property storage.  May overwrite base.
-void JIT::compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, size_t cachedOffset)
+void JIT::compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, PropertyOffset cachedOffset)
 {
-    int offset = cachedOffset;
-    loadPtr(Address(base, JSObject::offsetOfPropertyStorage()), base);
-    emitStore(offset, valueTag, valuePayload, base);
+    if (isOutOfLineOffset(cachedOffset))
+        loadPtr(Address(base, JSObject::offsetOfOutOfLineStorage()), base);
+    emitStore(indexRelativeToBase(cachedOffset), valueTag, valuePayload, base);
 }
 
 // Compile a load from an object's property storage.  May overwrite base.
-void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset)
+void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, PropertyOffset cachedOffset)
 {
-    int offset = cachedOffset;
+    if (isInlineOffset(cachedOffset)) {
+        emitLoad(indexRelativeToBase(cachedOffset), resultTag, resultPayload, base);
+        return;
+    }
+    
     RegisterID temp = resultPayload;
-    loadPtr(Address(base, JSObject::offsetOfPropertyStorage()), temp);
-    emitLoad(offset, resultTag, resultPayload, temp);
+    loadPtr(Address(base, JSObject::offsetOfOutOfLineStorage()), temp);
+    emitLoad(indexRelativeToBase(cachedOffset), resultTag, resultPayload, temp);
 }
 
-void JIT::compileGetDirectOffset(JSObject* base, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset)
+void JIT::compileGetDirectOffset(JSObject* base, RegisterID resultTag, RegisterID resultPayload, PropertyOffset cachedOffset)
 {
-    loadPtr(base->addressOfPropertyStorage(), resultTag);
-    load32(Address(resultTag, cachedOffset * sizeof(WriteBarrier<Unknown>) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload);
-    load32(Address(resultTag, cachedOffset * sizeof(WriteBarrier<Unknown>) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag);
+    if (isInlineOffset(cachedOffset)) {
+        move(TrustedImmPtr(base->locationForOffset(cachedOffset)), resultTag);
+        load32(Address(resultTag, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload);
+        load32(Address(resultTag, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag);
+        return;
+    }
+    
+    loadPtr(base->addressOfOutOfLineStorage(), resultTag);
+    load32(Address(resultTag, offsetInOutOfLineStorage(cachedOffset) * sizeof(WriteBarrier<Unknown>) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload);
+    load32(Address(resultTag, offsetInOutOfLineStorage(cachedOffset) * sizeof(WriteBarrier<Unknown>) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag);
 }
 
-void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
+void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, PropertyOffset cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
 {
     // The code below assumes that regT0 contains the basePayload and regT1 contains the baseTag. Restore them from the stack.
 #if CPU(MIPS) || CPU(SH4) || CPU(ARM)
@@ -489,7 +501,7 @@
     
     // Reallocate property storage if needed.
     Call callTarget;
-    bool willNeedStorageRealloc = oldStructure->propertyStorageCapacity() != newStructure->propertyStorageCapacity();
+    bool willNeedStorageRealloc = oldStructure->outOfLineCapacity() != newStructure->outOfLineCapacity();
     if (willNeedStorageRealloc) {
         // This trampoline was called to like a JIT stub; before we can can call again we need to
         // remove the return address from the stack, to prevent the stack from becoming misaligned.
@@ -499,7 +511,7 @@
         stubCall.skipArgument(); // base
         stubCall.skipArgument(); // ident
         stubCall.skipArgument(); // value
-        stubCall.addArgument(TrustedImm32(oldStructure->propertyStorageCapacity()));
+        stubCall.addArgument(TrustedImm32(oldStructure->outOfLineCapacity()));
         stubCall.addArgument(TrustedImmPtr(newStructure));
         stubCall.call(regT0);
 
@@ -553,7 +565,7 @@
     repatchBuffer.relinkCallerToTrampoline(returnAddress, CodeLocationLabel(stubInfo->stubRoutine.code()));
 }
 
-void JIT::patchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress)
+void JIT::patchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress)
 {
     RepatchBuffer repatchBuffer(codeBlock);
     
@@ -561,15 +573,14 @@
     // Should probably go to JITStubs::cti_op_get_by_id_fail, but that doesn't do anything interesting right now.
     repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_self_fail));
     
-    int offset = sizeof(JSValue) * cachedOffset;
-
     // Patch the offset into the propoerty map to load from, then patch the Structure to look for.
     repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(stubInfo->patch.baseline.u.get.structureToCompare), structure);
-    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelCompactAtOffset(stubInfo->patch.baseline.u.get.displacementLabel1), offset + OBJECT_OFFSETOF(JSValue, u.asBits.payload)); // payload
-    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelCompactAtOffset(stubInfo->patch.baseline.u.get.displacementLabel2), offset + OBJECT_OFFSETOF(JSValue, u.asBits.tag)); // tag
+    repatchBuffer.setLoadInstructionIsActive(stubInfo->hotPathBegin.convertibleLoadAtOffset(stubInfo->patch.baseline.u.get.propertyStorageLoad), isOutOfLineOffset(cachedOffset));
+    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelCompactAtOffset(stubInfo->patch.baseline.u.get.displacementLabel1), offsetRelativeToPatchedStorage(cachedOffset) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)); // payload
+    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelCompactAtOffset(stubInfo->patch.baseline.u.get.displacementLabel2), offsetRelativeToPatchedStorage(cachedOffset) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)); // tag
 }
 
-void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress, bool direct)
+void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress, bool direct)
 {
     RepatchBuffer repatchBuffer(codeBlock);
     
@@ -577,12 +588,11 @@
     // Should probably go to cti_op_put_by_id_fail, but that doesn't do anything interesting right now.
     repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
     
-    int offset = sizeof(JSValue) * cachedOffset;
-
     // Patch the offset into the propoerty map to load from, then patch the Structure to look for.
     repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(stubInfo->patch.baseline.u.put.structureToCompare), structure);
-    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(stubInfo->patch.baseline.u.put.displacementLabel1), offset + OBJECT_OFFSETOF(JSValue, u.asBits.payload)); // payload
-    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(stubInfo->patch.baseline.u.put.displacementLabel2), offset + OBJECT_OFFSETOF(JSValue, u.asBits.tag)); // tag
+    repatchBuffer.setLoadInstructionIsActive(stubInfo->hotPathBegin.convertibleLoadAtOffset(stubInfo->patch.baseline.u.put.propertyStorageLoad), isOutOfLineOffset(cachedOffset));
+    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(stubInfo->patch.baseline.u.put.displacementLabel1), offsetRelativeToPatchedStorage(cachedOffset) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)); // payload
+    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(stubInfo->patch.baseline.u.put.displacementLabel2), offsetRelativeToPatchedStorage(cachedOffset) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)); // tag
 }
 
 void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
@@ -629,7 +639,7 @@
     repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_array_fail));
 }
 
-void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
+void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
 {
     // regT0 holds a JSCell*
     
@@ -700,7 +710,7 @@
 }
 
 
-void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset)
+void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
 {
     // regT0 holds a JSCell*
     Jump failureCase = checkStructure(regT0, structure);
@@ -760,7 +770,7 @@
     repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine.code()));
 }
 
-void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, CallFrame* callFrame)
+void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, CallFrame* callFrame)
 {
     // regT0 holds a JSCell*
     
@@ -829,7 +839,7 @@
     repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine.code()));
 }
 
-void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, CallFrame* callFrame)
+void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, CallFrame* callFrame)
 {
     // regT0 holds a JSCell*
     ASSERT(count);
@@ -904,7 +914,7 @@
     repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine.code()));
 }
 
-void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
+void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
 {
     // regT0 holds a JSCell*
     ASSERT(count);
@@ -975,13 +985,27 @@
     repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list));
 }
 
-void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID offset)
+void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID offset, FinalObjectMode finalObjectMode)
 {
     ASSERT(sizeof(JSValue) == 8);
     
-    loadPtr(Address(base, JSObject::offsetOfPropertyStorage()), base);
-    loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload);
-    loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag);
+    if (finalObjectMode == MayBeFinal) {
+        Jump isInline = branch32(LessThan, offset, TrustedImm32(inlineStorageCapacity));
+        loadPtr(Address(base, JSObject::offsetOfOutOfLineStorage()), base);
+        Jump done = jump();
+        isInline.link(this);
+        addPtr(TrustedImmPtr(JSObject::offsetOfInlineStorage() + inlineStorageCapacity * sizeof(EncodedJSValue)), base);
+        done.link(this);
+    } else {
+#if !ASSERT_DISABLED
+        Jump isOutOfLine = branch32(GreaterThanOrEqual, offset, TrustedImm32(inlineStorageCapacity));
+        breakpoint();
+        isOutOfLine.link(this);
+#endif
+        loadPtr(Address(base, JSObject::offsetOfOutOfLineStorage()), base);
+    }
+    load32(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) - inlineStorageCapacity * sizeof(EncodedJSValue)), resultPayload);
+    load32(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) - inlineStorageCapacity * sizeof(EncodedJSValue)), resultTag);
 }
 
 void JIT::emit_op_get_by_pname(Instruction* currentInstruction)
@@ -1006,6 +1030,7 @@
     load32(addressFor(i), regT3);
     sub32(TrustedImm32(1), regT3);
     addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots))));
+    add32(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_offsetBase)), regT3);
     compileGetDirectOffset(regT2, regT1, regT0, regT3);    
     
     emitStore(dst, regT1, regT0);
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp
index 59dc5f1..72aa0dc 100644
--- a/Source/JavaScriptCore/jit/JITStubs.cpp
+++ b/Source/JavaScriptCore/jit/JITStubs.cpp
@@ -962,7 +962,7 @@
         return;
     }
 
-    size_t offset = slot.cachedOffset();
+    PropertyOffset offset = slot.cachedOffset();
     size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset);
     if (!count) {
         stubInfo->accessType = access_get_by_id_generic;
@@ -1494,13 +1494,16 @@
     JSValue baseValue = stackFrame.args[0].jsValue();
     int32_t oldSize = stackFrame.args[3].int32();
     Structure* newStructure = stackFrame.args[4].structure();
-    int32_t newSize = newStructure->propertyStorageCapacity();
+    int32_t newSize = newStructure->outOfLineCapacity();
+    
+    ASSERT(oldSize >= 0);
+    ASSERT(newSize > oldSize);
 
     ASSERT(baseValue.isObject());
     JSObject* base = asObject(baseValue);
     JSGlobalData& globalData = *stackFrame.globalData;
-    PropertyStorage newStorage = base->growPropertyStorage(globalData, oldSize, newSize);
-    base->setPropertyStorage(globalData, newStorage, newStructure);
+    PropertyStorage newStorage = base->growOutOfLineStorage(globalData, oldSize, newSize);
+    base->setOutOfLineStorage(globalData, newStorage, newStructure);
 
     return base;
 }
@@ -1822,7 +1825,7 @@
     ASSERT(slot.slotBase().isObject());
     JSObject* slotBaseObject = asObject(slot.slotBase());
     
-    size_t offset = slot.cachedOffset();
+    PropertyOffset offset = slot.cachedOffset();
 
     if (slot.slotBase() == baseValue)
         ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
index a7698be3..fbc0146 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
@@ -895,7 +895,13 @@
             && !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 @@
             && 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 @@
                     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 @@
                     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 e59ddeb..492535b 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
@@ -84,6 +84,13 @@
 # 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 @@
         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 @@
     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 d27fd82..9d6304d 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
@@ -919,6 +919,24 @@
     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 @@
     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 @@
     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)
+    .opGetByIdSlow:
+        callSlowPath(_llint_slow_path_get_by_id)
+        dispatch(9)
+end
+
+_llint_op_get_by_id:
+    getById(withInlineStorage)
+
+
+_llint_op_get_by_id_out_of_line:
+    getById(withOutOfLineStorage)
 
 
 _llint_op_get_arguments_length:
@@ -1130,68 +1159,96 @@
     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 @@
     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 a153586..a7a2ce8 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
@@ -778,6 +778,22 @@
     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 @@
     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 @@
     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 @@
     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
 
-.opGetByIdSlow:
-    callSlowPath(_llint_slow_path_get_by_id)
-    dispatch(9)
+_llint_op_get_by_id:
+    getById(withInlineStorage)
+
+
+_llint_op_get_by_id_out_of_line:
+    getById(withOutOfLineStorage)
 
 
 _llint_op_get_arguments_length:
@@ -978,65 +1005,93 @@
     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 @@
     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)
diff --git a/Source/JavaScriptCore/offlineasm/x86.rb b/Source/JavaScriptCore/offlineasm/x86.rb
index e6a5c92..383526b 100644
--- a/Source/JavaScriptCore/offlineasm/x86.rb
+++ b/Source/JavaScriptCore/offlineasm/x86.rb
@@ -555,7 +555,11 @@
     end
     
     def handleX86Add(kind)
-        if operands.size == 3 and operands[0].is_a? Immediate
+        if operands.size == 3 and operands[1] == operands[2]
+            unless Immediate.new(nil, 0) == operands[0]
+                $asm.puts "add#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
+            end
+        elsif operands.size == 3 and operands[0].is_a? Immediate
             raise unless operands[1].is_a? RegisterID
             raise unless operands[2].is_a? RegisterID
             if operands[0].value == 0
@@ -568,7 +572,11 @@
         elsif operands.size == 3 and operands[0].is_a? RegisterID
             raise unless operands[1].is_a? RegisterID
             raise unless operands[2].is_a? RegisterID
-            $asm.puts "lea#{x86Suffix(kind)} (#{operands[0].x86Operand(kind)}, #{operands[1].x86Operand(kind)}), #{operands[2].x86Operand(kind)}"
+            if operands[0] == operands[2]
+                $asm.puts "add#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
+            else
+                $asm.puts "lea#{x86Suffix(kind)} (#{operands[0].x86Operand(kind)}, #{operands[1].x86Operand(kind)}), #{operands[2].x86Operand(kind)}"
+            end
         else
             unless Immediate.new(nil, 0) == operands[0]
                 $asm.puts "add#{x86Suffix(kind)} #{x86Operands(kind, kind)}"
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h
index 1dcfc63..af03f32 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h
@@ -132,7 +132,7 @@
         WriteBarrier<Structure> m_functionStructure;
         WriteBarrier<Structure> m_boundFunctionStructure;
         WriteBarrier<Structure> m_namedFunctionStructure;
-        size_t m_functionNameOffset;
+        PropertyOffset m_functionNameOffset;
         WriteBarrier<Structure> m_numberObjectStructure;
         WriteBarrier<Structure> m_privateNameStructure;
         WriteBarrier<Structure> m_regExpMatchesArrayStructure;
@@ -262,7 +262,7 @@
         Structure* functionStructure() const { return m_functionStructure.get(); }
         Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(); }
         Structure* namedFunctionStructure() const { return m_namedFunctionStructure.get(); }
-        size_t functionNameOffset() const { return m_functionNameOffset; }
+        PropertyOffset functionNameOffset() const { return m_functionNameOffset; }
         Structure* numberObjectStructure() const { return m_numberObjectStructure.get(); }
         Structure* privateNameStructure() const { return m_privateNameStructure.get(); }
         Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); }
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index 66cc898..ccc49fd 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -93,19 +93,17 @@
     bool wasCheckingForDefaultMarkViolation = visitor.m_isCheckingForDefaultMarkViolation;
     visitor.m_isCheckingForDefaultMarkViolation = false;
 #endif
-
+    
     JSCell::visitChildren(thisObject, visitor);
 
-    PropertyStorage storage = thisObject->propertyStorage();
-    size_t storageSize = thisObject->structure()->propertyStorageSize();
-    if (thisObject->isUsingInlineStorage())
-        visitor.appendValues(storage, storageSize);
-    else {
+    PropertyStorage storage = thisObject->outOfLineStorage();
+    if (storage) {
+        size_t storageSize = thisObject->structure()->outOfLineSizeForKnownNonFinalObject();
         // We have this extra temp here to slake GCC's thirst for the blood of those who dereference type-punned pointers.
         void* temp = storage;
-        visitor.copyAndAppend(&temp, thisObject->structure()->propertyStorageCapacity() * sizeof(WriteBarrierBase<Unknown>), storage->slot(), storageSize);
+        visitor.copyAndAppend(&temp, thisObject->structure()->outOfLineCapacity() * sizeof(WriteBarrierBase<Unknown>), storage->slot(), storageSize);
         storage = static_cast<PropertyStorage>(temp);
-        thisObject->m_propertyStorage.set(storage, StorageBarrier::Unchecked);
+        thisObject->m_outOfLineStorage.set(storage, StorageBarrier::Unchecked);
     }
 
     if (thisObject->m_inheritorID)
@@ -116,6 +114,38 @@
 #endif
 }
 
+void JSFinalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    JSFinalObject* thisObject = jsCast<JSFinalObject*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);
+#if !ASSERT_DISABLED
+    bool wasCheckingForDefaultMarkViolation = visitor.m_isCheckingForDefaultMarkViolation;
+    visitor.m_isCheckingForDefaultMarkViolation = false;
+#endif
+    
+    JSCell::visitChildren(thisObject, visitor);
+
+    PropertyStorage storage = thisObject->outOfLineStorage();
+    if (storage) {
+        size_t storageSize = thisObject->structure()->outOfLineSizeForKnownFinalObject();
+        // We have this extra temp here to slake GCC's thirst for the blood of those who dereference type-punned pointers.
+        void* temp = storage;
+        visitor.copyAndAppend(&temp, thisObject->structure()->outOfLineCapacity() * sizeof(WriteBarrierBase<Unknown>), storage->slot(), storageSize);
+        storage = static_cast<PropertyStorage>(temp);
+        thisObject->m_outOfLineStorage.set(storage, StorageBarrier::Unchecked);
+    }
+
+    if (thisObject->m_inheritorID)
+        visitor.append(&thisObject->m_inheritorID);
+
+    size_t storageSize = thisObject->structure()->inlineSizeForKnownFinalObject();
+    visitor.appendValues(thisObject->inlineStorage(), storageSize);
+
+#if !ASSERT_DISABLED
+    visitor.m_isCheckingForDefaultMarkViolation = wasCheckingForDefaultMarkViolation;
+#endif
+}
+
 UString JSObject::className(const JSObject* object)
 {
     const ClassInfo* info = object->classInfo();
@@ -153,8 +183,8 @@
     for (JSObject* obj = thisObject; ; obj = asObject(prototype)) {
         unsigned attributes;
         JSCell* specificValue;
-        size_t offset = obj->structure()->get(globalData, propertyName, attributes, specificValue);
-        if (offset != WTF::notFound) {
+        PropertyOffset offset = obj->structure()->get(globalData, propertyName, attributes, specificValue);
+        if (offset != invalidOffset) {
             if (attributes & ReadOnly) {
                 if (slot.isStrictMode())
                     throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
@@ -272,7 +302,7 @@
 
     unsigned attributes;
     JSCell* specificValue;
-    if (thisObject->structure()->get(exec->globalData(), propertyName, attributes, specificValue) != WTF::notFound) {
+    if (isValidOffset(thisObject->structure()->get(exec->globalData(), propertyName, attributes, specificValue))) {
         if (attributes & DontDelete && !exec->globalData().isInDefineOwnProperty())
             return false;
         thisObject->removeDirect(exec->globalData(), propertyName);
@@ -394,7 +424,7 @@
 bool JSObject::getPropertySpecificValue(ExecState* exec, PropertyName propertyName, JSCell*& specificValue) const
 {
     unsigned attributes;
-    if (structure()->get(exec->globalData(), propertyName, attributes, specificValue) != WTF::notFound)
+    if (isValidOffset(structure()->get(exec->globalData(), propertyName, attributes, specificValue)))
         return true;
 
     // This could be a function within the static table? - should probably
@@ -516,20 +546,20 @@
 
 bool JSObject::removeDirect(JSGlobalData& globalData, PropertyName propertyName)
 {
-    if (structure()->get(globalData, propertyName) == WTF::notFound)
+    if (!isValidOffset(structure()->get(globalData, propertyName)))
         return false;
 
-    size_t offset;
+    PropertyOffset offset;
     if (structure()->isUncacheableDictionary()) {
         offset = structure()->removePropertyWithoutTransition(globalData, propertyName);
-        if (offset == WTF::notFound)
+        if (offset == invalidOffset)
             return false;
         putUndefinedAtDirectOffset(offset);
         return true;
     }
 
     setStructure(globalData, Structure::removePropertyTransition(globalData, structure(), propertyName, offset));
-    if (offset == WTF::notFound)
+    if (offset == invalidOffset)
         return false;
     putUndefinedAtDirectOffset(offset);
     return true;
@@ -559,25 +589,22 @@
     return m_inheritorID.get();
 }
 
-PropertyStorage JSObject::growPropertyStorage(JSGlobalData& globalData, size_t oldSize, size_t newSize)
+PropertyStorage JSObject::growOutOfLineStorage(JSGlobalData& globalData, size_t oldSize, size_t newSize)
 {
     ASSERT(newSize > oldSize);
 
     // It's important that this function not rely on structure(), since
     // we might be in the middle of a transition.
 
-    PropertyStorage oldPropertyStorage = m_propertyStorage.get();
+    PropertyStorage oldPropertyStorage = m_outOfLineStorage.get();
     PropertyStorage newPropertyStorage = 0;
 
-    if (isUsingInlineStorage()) {
+    if (!oldPropertyStorage) {
         // We have this extra temp here to slake GCC's thirst for the blood of those who dereference type-punned pointers.
         void* temp = newPropertyStorage;
         if (!globalData.heap.tryAllocateStorage(sizeof(WriteBarrierBase<Unknown>) * newSize, &temp))
             CRASH();
         newPropertyStorage = static_cast<PropertyStorage>(temp);
-
-        for (unsigned i = 0; i < oldSize; ++i)
-            newPropertyStorage[i] = oldPropertyStorage[i];
     } else {
         // We have this extra temp here to slake GCC's thirst for the blood of those who dereference type-punned pointers.
         void* temp = oldPropertyStorage;
@@ -594,8 +621,8 @@
 {
     unsigned attributes = 0;
     JSCell* cell = 0;
-    size_t offset = object->structure()->get(exec->globalData(), propertyName, attributes, cell);
-    if (offset == WTF::notFound)
+    PropertyOffset offset = object->structure()->get(exec->globalData(), propertyName, attributes, cell);
+    if (offset == invalidOffset)
         return false;
     descriptor.setDescriptor(object->getDirectOffset(offset), attributes);
     return true;
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index db05591..7056623 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -79,18 +79,13 @@
         Accessor     = 1 << 5,  // property is a getter/setter
     };
 
-#if USE(JSVALUE32_64)
-#define JSFinalObject_inlineStorageCapacity 6
-#else
-#define JSFinalObject_inlineStorageCapacity 4
-#endif
-
-COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= 0), final_storage_non_negative);
+    class JSFinalObject;
 
     class JSObject : public JSCell {
         friend class BatchedTransitionOptimizer;
         friend class JIT;
         friend class JSCell;
+        friend class JSFinalObject;
         friend class MarkedBlock;
         JS_EXPORT_PRIVATE friend bool setUpStaticFunctionSlot(ExecState*, const HashEntry*, JSObject*, PropertyName, PropertySlot&);
 
@@ -169,26 +164,72 @@
         // This get function only looks at the property map.
         JSValue getDirect(JSGlobalData& globalData, PropertyName propertyName) const
         {
-            size_t offset = structure()->get(globalData, propertyName);
-            return offset != WTF::notFound ? getDirectOffset(offset) : JSValue();
+            PropertyOffset offset = structure()->get(globalData, propertyName);
+            checkOffset(offset, structure()->typeInfo().type());
+            return offset != invalidOffset ? getDirectOffset(offset) : JSValue();
         }
 
         WriteBarrierBase<Unknown>* getDirectLocation(JSGlobalData& globalData, PropertyName propertyName)
         {
-            size_t offset = structure()->get(globalData, propertyName);
-            return offset != WTF::notFound ? locationForOffset(offset) : 0;
+            PropertyOffset offset = structure()->get(globalData, propertyName);
+            checkOffset(offset, structure()->typeInfo().type());
+            return offset != invalidOffset ? locationForOffset(offset) : 0;
         }
 
         WriteBarrierBase<Unknown>* getDirectLocation(JSGlobalData& globalData, PropertyName propertyName, unsigned& attributes)
         {
             JSCell* specificFunction;
-            size_t offset = structure()->get(globalData, propertyName, attributes, specificFunction);
-            return offset != WTF::notFound ? locationForOffset(offset) : 0;
+            PropertyOffset offset = structure()->get(globalData, propertyName, attributes, specificFunction);
+            return offset != invalidOffset ? locationForOffset(offset) : 0;
         }
 
-        size_t offsetForLocation(WriteBarrierBase<Unknown>* location) const
+        bool hasInlineStorage() const { return structure()->hasInlineStorage(); }
+        ConstPropertyStorage inlineStorageUnsafe() const
         {
-            return location - propertyStorage();
+            return bitwise_cast<ConstPropertyStorage>(this + 1);
+        }
+        PropertyStorage inlineStorageUnsafe()
+        {
+            return bitwise_cast<PropertyStorage>(this + 1);
+        }
+        ConstPropertyStorage inlineStorage() const
+        {
+            ASSERT(hasInlineStorage());
+            return inlineStorageUnsafe();
+        }
+        PropertyStorage inlineStorage()
+        {
+            ASSERT(hasInlineStorage());
+            return inlineStorageUnsafe();
+        }
+        
+        ConstPropertyStorage outOfLineStorage() const { return m_outOfLineStorage.get(); }
+        PropertyStorage outOfLineStorage() { return m_outOfLineStorage.get(); }
+
+        const WriteBarrierBase<Unknown>* locationForOffset(PropertyOffset offset) const
+        {
+            if (isInlineOffset(offset))
+                return &inlineStorage()[offsetInInlineStorage(offset)];
+            return &outOfLineStorage()[offsetInOutOfLineStorage(offset)];
+        }
+
+        WriteBarrierBase<Unknown>* locationForOffset(PropertyOffset offset)
+        {
+            if (isInlineOffset(offset))
+                return &inlineStorage()[offsetInInlineStorage(offset)];
+            return &outOfLineStorage()[offsetInOutOfLineStorage(offset)];
+        }
+
+        PropertyOffset offsetForLocation(WriteBarrierBase<Unknown>* location) const
+        {
+            PropertyOffset result;
+            size_t offsetInInlineStorage = location - inlineStorageUnsafe();
+            if (offsetInInlineStorage < static_cast<size_t>(inlineStorageCapacity))
+                result = offsetInInlineStorage;
+            else
+                result = location - outOfLineStorage() + firstOutOfLineOffset;
+            validateOffset(result, structure()->typeInfo().type());
+            return result;
         }
 
         void transitionTo(JSGlobalData&, Structure*);
@@ -205,9 +246,9 @@
         bool putOwnDataProperty(JSGlobalData&, PropertyName, JSValue, PutPropertySlot&);
 
         // Fast access to known property offsets.
-        JSValue getDirectOffset(size_t offset) const { return propertyStorage()[offset].get(); }
-        void putDirectOffset(JSGlobalData& globalData, size_t offset, JSValue value) { propertyStorage()[offset].set(globalData, this, value); }
-        void putUndefinedAtDirectOffset(size_t offset) { propertyStorage()[offset].setUndefined(); }
+        JSValue getDirectOffset(PropertyOffset offset) const { return locationForOffset(offset)->get(); }
+        void putDirectOffset(JSGlobalData& globalData, PropertyOffset offset, JSValue value) { locationForOffset(offset)->set(globalData, this, value); }
+        void putUndefinedAtDirectOffset(PropertyOffset offset) { locationForOffset(offset)->setUndefined(); }
 
         JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow);
 
@@ -228,24 +269,16 @@
         bool staticFunctionsReified() { return structure()->staticFunctionsReified(); }
         void reifyStaticFunctionsForDelete(ExecState* exec);
 
-        JS_EXPORT_PRIVATE PropertyStorage growPropertyStorage(JSGlobalData&, size_t oldSize, size_t newSize);
-        bool isUsingInlineStorage() const
-        {
-            bool result =
-                !m_propertyStorage.get()
-                || static_cast<const void*>(m_propertyStorage.get()) == static_cast<const void*>(this + 1);
-            ASSERT(result == structure()->isUsingInlineStorage());
-            return result;
-        }
-        void setPropertyStorage(JSGlobalData&, PropertyStorage, Structure*);
+        JS_EXPORT_PRIVATE PropertyStorage growOutOfLineStorage(JSGlobalData&, size_t oldSize, size_t newSize);
+        void setOutOfLineStorage(JSGlobalData&, PropertyStorage, Structure*);
         
         bool reallocateStorageIfNecessary(JSGlobalData&, unsigned oldCapacity, Structure*);
         void setStructureAndReallocateStorageIfNecessary(JSGlobalData&, unsigned oldCapacity, Structure*);
         void setStructureAndReallocateStorageIfNecessary(JSGlobalData&, Structure*);
 
-        void* addressOfPropertyStorage()
+        void* addressOfOutOfLineStorage()
         {
-            return &m_propertyStorage;
+            return &m_outOfLineStorage;
         }
 
         void flattenDictionaryObject(JSGlobalData& globalData)
@@ -261,7 +294,7 @@
         }
         
         static size_t offsetOfInlineStorage();
-        static size_t offsetOfPropertyStorage();
+        static size_t offsetOfOutOfLineStorage();
         static size_t offsetOfInheritorID();
 
         static JS_EXPORTDATA const ClassInfo s_info;
@@ -271,7 +304,7 @@
         {
             Base::finishCreation(globalData);
             ASSERT(inherits(&s_info));
-            ASSERT(structure()->isUsingInlineStorage());
+            ASSERT(!structure()->outOfLineCapacity());
             ASSERT(structure()->isEmpty());
             ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype()));
             ASSERT(structure()->isObject());
@@ -287,7 +320,7 @@
 
         // To instantiate objects you likely want JSFinalObject, below.
         // To create derived types you likely want JSNonFinalObject, below.
-        JSObject(JSGlobalData&, Structure*, PropertyStorage inlineStorage);
+        JSObject(JSGlobalData&, Structure*);
         
         void resetInheritorID()
         {
@@ -305,19 +338,6 @@
         void isObject();
         void isString();
         
-        ConstPropertyStorage propertyStorage() const { return m_propertyStorage.get(); }
-        PropertyStorage propertyStorage() { return m_propertyStorage.get(); }
-
-        const WriteBarrierBase<Unknown>* locationForOffset(size_t offset) const
-        {
-            return &propertyStorage()[offset];
-        }
-
-        WriteBarrierBase<Unknown>* locationForOffset(size_t offset)
-        {
-            return &propertyStorage()[offset];
-        }
-
         template<PutMode>
         bool putDirectInternal(JSGlobalData&, PropertyName, JSValue, unsigned attr, PutPropertySlot&, JSCell*);
 
@@ -327,7 +347,7 @@
         const HashEntry* findPropertyHashEntry(ExecState*, PropertyName) const;
         Structure* createInheritorID(JSGlobalData&);
 
-        StorageBarrier m_propertyStorage;
+        StorageBarrier m_outOfLineStorage;
         WriteBarrier<Structure> m_inheritorID;
     };
 
@@ -353,14 +373,14 @@
 
     protected:
         explicit JSNonFinalObject(JSGlobalData& globalData, Structure* structure)
-            : JSObject(globalData, structure, 0)
+            : JSObject(globalData, structure)
         {
         }
 
         void finishCreation(JSGlobalData& globalData)
         {
             Base::finishCreation(globalData);
-            ASSERT(!this->structure()->propertyStorageCapacity());
+            ASSERT(!this->structure()->totalStorageCapacity());
             ASSERT(classInfo());
         }
     };
@@ -381,6 +401,8 @@
             return Structure::create(globalData, globalObject, prototype, TypeInfo(FinalObjectType, StructureFlags), &s_info);
         }
 
+        JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
+
         static JS_EXPORTDATA const ClassInfo s_info;
 
         static bool hasInlineStorage()
@@ -388,11 +410,14 @@
             return true;
         }
     protected:
+        void visitChildrenCommon(SlotVisitor&);
+        
         void finishCreation(JSGlobalData& globalData)
         {
             Base::finishCreation(globalData);
             ASSERT(!(OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage) % sizeof(double)));
-            ASSERT(this->structure()->propertyStorageCapacity() == JSFinalObject_inlineStorageCapacity);
+            ASSERT(this->structure()->inlineCapacity() == inlineStorageCapacity);
+            ASSERT(this->structure()->totalStorageCapacity() == inlineStorageCapacity);
             ASSERT(classInfo());
         }
 
@@ -400,13 +425,13 @@
         friend class LLIntOffsetsExtractor;
         
         explicit JSFinalObject(JSGlobalData& globalData, Structure* structure)
-            : JSObject(globalData, structure, m_inlineStorage)
+            : JSObject(globalData, structure)
         {
         }
 
         static const unsigned StructureFlags = JSObject::StructureFlags;
 
-        WriteBarrierBase<Unknown> m_inlineStorage[JSFinalObject_inlineStorageCapacity];
+        WriteBarrierBase<Unknown> m_inlineStorage[INLINE_STORAGE_CAPACITY];
     };
 
 inline JSFinalObject* JSFinalObject::create(ExecState* exec, Structure* structure)
@@ -431,9 +456,9 @@
     return OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage);
 }
 
-inline size_t JSObject::offsetOfPropertyStorage()
+inline size_t JSObject::offsetOfOutOfLineStorage()
 {
-    return OBJECT_OFFSETOF(JSObject, m_propertyStorage);
+    return OBJECT_OFFSETOF(JSObject, m_outOfLineStorage);
 }
 
 inline size_t JSObject::offsetOfInheritorID()
@@ -471,14 +496,18 @@
     return structure()->typeInfo().type() == GlobalThisType;
 }
 
-inline void JSObject::setPropertyStorage(JSGlobalData& globalData, PropertyStorage storage, Structure* structure)
+inline void JSObject::setOutOfLineStorage(JSGlobalData& globalData, PropertyStorage storage, Structure* structure)
 {
-    ASSERT(storage);
     ASSERT(structure);
-    ASSERT(!structure->isUsingInlineStorage()
-           || (classInfo() == &JSFinalObject::s_info && static_cast<void*>(storage) == static_cast<void*>(this + 1)));
+    if (!storage) {
+        ASSERT(!structure->outOfLineCapacity());
+        ASSERT(!structure->outOfLineSize());
+    } else {
+        ASSERT(structure->outOfLineCapacity());
+        ASSERT(structure->outOfLineSize());
+    }
     setStructure(globalData, structure);
-    m_propertyStorage.set(globalData, this, storage);
+    m_outOfLineStorage.set(globalData, this, storage);
 }
 
 inline JSObject* constructEmptyObject(ExecState* exec, Structure* structure)
@@ -516,9 +545,9 @@
     return asObject(value.asCell());
 }
 
-inline JSObject::JSObject(JSGlobalData& globalData, Structure* structure, PropertyStorage inlineStorage)
+inline JSObject::JSObject(JSGlobalData& globalData, Structure* structure)
     : JSCell(globalData, structure)
-    , m_propertyStorage(globalData, this, inlineStorage)
+    , m_outOfLineStorage(globalData, this, 0)
 {
 }
 
@@ -542,19 +571,6 @@
     return createInheritorID(globalData);
 }
 
-inline size_t Structure::inlineStorageCapacity() const
-{
-    if (classInfo() == &JSFinalObject::s_info)
-        return JSFinalObject_inlineStorageCapacity;
-    return 0;
-}
-
-inline bool Structure::isUsingInlineStorage() const
-{
-    ASSERT(propertyStorageCapacity() >= inlineStorageCapacity());
-    return propertyStorageCapacity() == inlineStorageCapacity();
-}
-
 inline bool JSCell::inherits(const ClassInfo* info) const
 {
     return classInfo()->isSubClassOf(info);
@@ -611,10 +627,10 @@
 ALWAYS_INLINE JSValue JSCell::fastGetOwnProperty(ExecState* exec, const UString& name)
 {
     if (!structure()->typeInfo().overridesGetOwnPropertySlot() && !structure()->hasGetterSetterProperties()) {
-        size_t offset = name.impl()->hasHash()
+        PropertyOffset offset = name.impl()->hasHash()
             ? structure()->get(exec->globalData(), Identifier(exec, name))
             : structure()->get(exec->globalData(), name);
-        if (offset != WTF::notFound)
+        if (offset != invalidOffset)
             return asObject(this)->locationForOffset(offset)->get();
     }
     return JSValue();
@@ -676,8 +692,8 @@
     if (structure()->isDictionary()) {
         unsigned currentAttributes;
         JSCell* currentSpecificFunction;
-        size_t offset = structure()->get(globalData, propertyName, currentAttributes, currentSpecificFunction);
-        if (offset != WTF::notFound) {
+        PropertyOffset offset = structure()->get(globalData, propertyName, currentAttributes, currentSpecificFunction);
+        if (offset != invalidOffset) {
             // If there is currently a specific function, and there now either isn't,
             // or the new value is different, then despecify.
             if (currentSpecificFunction && (specificFunction != currentSpecificFunction))
@@ -700,13 +716,14 @@
         if ((mode == PutModePut) && !isExtensible())
             return false;
 
-        PropertyStorage newStorage = propertyStorage();
-        if (structure()->putWillGrowPropertyStorage())
-            newStorage = growPropertyStorage(globalData, structure()->propertyStorageCapacity(), structure()->suggestedNewPropertyStorageSize());
+        PropertyStorage newStorage = outOfLineStorage();
+        if (structure()->putWillGrowOutOfLineStorage())
+            newStorage = growOutOfLineStorage(globalData, structure()->outOfLineCapacity(), structure()->suggestedNewOutOfLineStorageCapacity());
         offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, specificFunction);
-        setPropertyStorage(globalData, newStorage, structure());
+        setOutOfLineStorage(globalData, newStorage, structure());
 
-        ASSERT(offset < structure()->propertyStorageCapacity());
+        validateOffset(offset);
+        ASSERT(structure()->isValidOffset(offset));
         putDirectOffset(globalData, offset, value);
         // See comment on setNewProperty call below.
         if (!specificFunction)
@@ -714,15 +731,16 @@
         return true;
     }
 
-    size_t offset;
-    size_t currentCapacity = structure()->propertyStorageCapacity();
+    PropertyOffset offset;
+    size_t currentCapacity = structure()->outOfLineCapacity();
     if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(this->structure(), propertyName, attributes, specificFunction, offset)) {
-        PropertyStorage newStorage = propertyStorage(); 
-        if (currentCapacity != structure->propertyStorageCapacity())
-            newStorage = growPropertyStorage(globalData, currentCapacity, structure->propertyStorageCapacity());
+        PropertyStorage newStorage = outOfLineStorage(); 
+        if (currentCapacity != structure->outOfLineCapacity())
+            newStorage = growOutOfLineStorage(globalData, currentCapacity, structure->outOfLineCapacity());
 
-        ASSERT(offset < structure->propertyStorageCapacity());
-        setPropertyStorage(globalData, newStorage, structure);
+        validateOffset(offset);
+        ASSERT(structure->isValidOffset(offset));
+        setOutOfLineStorage(globalData, newStorage, structure);
         putDirectOffset(globalData, offset, value);
         // This is a new property; transitions with specific values are not currently cachable,
         // so leave the slot in an uncachable state.
@@ -734,7 +752,7 @@
     unsigned currentAttributes;
     JSCell* currentSpecificFunction;
     offset = structure()->get(globalData, propertyName, currentAttributes, currentSpecificFunction);
-    if (offset != WTF::notFound) {
+    if (offset != invalidOffset) {
         if ((mode == PutModePut) && currentAttributes & ReadOnly)
             return false;
 
@@ -768,7 +786,8 @@
 
     Structure* structure = Structure::addPropertyTransition(globalData, this->structure(), propertyName, attributes, specificFunction, offset);
     
-    ASSERT(offset < structure->propertyStorageCapacity());
+    validateOffset(offset);
+    ASSERT(structure->isValidOffset(offset));
     setStructureAndReallocateStorageIfNecessary(globalData, structure);
 
     putDirectOffset(globalData, offset, value);
@@ -781,22 +800,22 @@
 
 inline void JSObject::setStructureAndReallocateStorageIfNecessary(JSGlobalData& globalData, unsigned oldCapacity, Structure* newStructure)
 {
-    ASSERT(oldCapacity <= newStructure->propertyStorageCapacity());
+    ASSERT(oldCapacity <= newStructure->outOfLineCapacity());
     
-    if (oldCapacity == newStructure->propertyStorageCapacity()) {
+    if (oldCapacity == newStructure->outOfLineCapacity()) {
         setStructure(globalData, newStructure);
         return;
     }
     
-    PropertyStorage newStorage = growPropertyStorage(
-        globalData, oldCapacity, newStructure->propertyStorageCapacity());
-    setPropertyStorage(globalData, newStorage, newStructure);
+    PropertyStorage newStorage = growOutOfLineStorage(
+        globalData, oldCapacity, newStructure->outOfLineCapacity());
+    setOutOfLineStorage(globalData, newStorage, newStructure);
 }
 
 inline void JSObject::setStructureAndReallocateStorageIfNecessary(JSGlobalData& globalData, Structure* newStructure)
 {
     setStructureAndReallocateStorageIfNecessary(
-        globalData, structure()->propertyStorageCapacity(), newStructure);
+        globalData, structure()->outOfLineCapacity(), newStructure);
 }
 
 inline bool JSObject::putOwnDataProperty(JSGlobalData& globalData, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
@@ -824,11 +843,11 @@
 inline void JSObject::putDirectWithoutTransition(JSGlobalData& globalData, PropertyName propertyName, JSValue value, unsigned attributes)
 {
     ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
-    PropertyStorage newStorage = propertyStorage();
-    if (structure()->putWillGrowPropertyStorage())
-        newStorage = growPropertyStorage(globalData, structure()->propertyStorageCapacity(), structure()->suggestedNewPropertyStorageSize());
-    size_t offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, getCallableObject(value));
-    setPropertyStorage(globalData, newStorage, structure());
+    PropertyStorage newStorage = outOfLineStorage();
+    if (structure()->putWillGrowOutOfLineStorage())
+        newStorage = growOutOfLineStorage(globalData, structure()->outOfLineCapacity(), structure()->suggestedNewOutOfLineStorageCapacity());
+    PropertyOffset offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, getCallableObject(value));
+    setOutOfLineStorage(globalData, newStorage, structure());
     putDirectOffset(globalData, offset, value);
 }
 
@@ -906,8 +925,6 @@
     asCell()->methodTable()->putByIndex(asCell(), exec, propertyName, value, shouldThrow);
 }
 
-// --- JSValue inlines ----------------------------
-
 ALWAYS_INLINE JSObject* Register::function() const
 {
     if (!jsValue())
@@ -922,6 +939,32 @@
     return r;
 }
 
+// This is a helper for patching code where you want to emit a load or store and
+// the base is:
+// For inline offsets: a pointer to the out-of-line storage pointer.
+// For out-of-line offsets: the base of the out-of-line storage.
+inline size_t offsetRelativeToPatchedStorage(PropertyOffset offset)
+{
+    if (isOutOfLineOffset(offset))
+        return sizeof(EncodedJSValue) * offsetInOutOfLineStorage(offset);
+    return JSObject::offsetOfInlineStorage() - JSObject::offsetOfOutOfLineStorage() + sizeof(EncodedJSValue) * offsetInInlineStorage(offset);
+}
+
+inline int indexRelativeToBase(PropertyOffset offset)
+{
+    if (isOutOfLineOffset(offset))
+        return offsetInOutOfLineStorage(offset);
+    ASSERT(!(JSObject::offsetOfInlineStorage() % sizeof(EncodedJSValue)));
+    return JSObject::offsetOfInlineStorage() / sizeof(EncodedJSValue) + offsetInInlineStorage(offset);
+}
+
+inline int offsetRelativeToBase(PropertyOffset offset)
+{
+    if (isOutOfLineOffset(offset))
+        return offsetInOutOfLineStorage(offset) * sizeof(EncodedJSValue);
+    return JSObject::offsetOfInlineStorage() + offsetInInlineStorage(offset) * sizeof(EncodedJSValue);
+}
+
 } // namespace JSC
 
 #endif // JSObject_h
diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
index 6ceb3c4..aaf946d 100644
--- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
+++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
@@ -56,10 +56,10 @@
     size_t numCacheableSlots = 0;
     if (!o->structure()->hasNonEnumerableProperties() && !o->structure()->hasGetterSetterProperties()
         && !o->structure()->isUncacheableDictionary() && !o->structure()->typeInfo().overridesGetPropertyNames())
-        numCacheableSlots = o->structure()->propertyStorageSize();
+        numCacheableSlots = o->structure()->totalStorageSize();
     
     JSPropertyNameIterator* jsPropertyNameIterator = new (NotNull, allocateCell<JSPropertyNameIterator>(*exec->heap())) JSPropertyNameIterator(exec, propertyNames.data(), numCacheableSlots);
-    jsPropertyNameIterator->finishCreation(exec, propertyNames.data());
+    jsPropertyNameIterator->finishCreation(exec, propertyNames.data(), o);
 
     if (o->structure()->isDictionary())
         return jsPropertyNameIterator;
diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
index 5b65e59..653ee04 100644
--- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
+++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
@@ -47,12 +47,6 @@
         typedef JSCell Base;
 
         static JSPropertyNameIterator* create(ExecState*, JSObject*);
-        static JSPropertyNameIterator* create(ExecState* exec, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlot)
-        {
-            JSPropertyNameIterator* iterator = new (NotNull, allocateCell<JSPropertyNameIterator>(*exec->heap())) JSPropertyNameIterator(exec, propertyNameArrayData, numCacheableSlot);
-            iterator->finishCreation(exec, propertyNameArrayData);
-            return iterator;
-        }
 
         static void destroy(JSCell*);
        
@@ -63,11 +57,11 @@
 
         static void visitChildren(JSCell*, SlotVisitor&);
 
-        bool getOffset(size_t i, int& offset)
+        bool getOffset(size_t i, PropertyOffset& offset)
         {
             if (i >= m_numCacheableSlots)
                 return false;
-            offset = i;
+            offset = i + m_offsetBase;
             return true;
         }
 
@@ -88,12 +82,13 @@
         static const ClassInfo s_info;
 
     protected:
-        void finishCreation(ExecState* exec, PropertyNameArrayData* propertyNameArrayData)
+        void finishCreation(ExecState* exec, PropertyNameArrayData* propertyNameArrayData, JSObject* object)
         {
             Base::finishCreation(exec->globalData());
             PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector();
             for (size_t i = 0; i < m_jsStringsSize; ++i)
                 m_jsStrings[i].set(exec->globalData(), this, jsOwnedString(exec, propertyNameVector[i].ustring()));
+            m_offsetBase = object->structure()->firstValidOffset();
         }
 
     private:
@@ -105,6 +100,7 @@
         WriteBarrier<StructureChain> m_cachedPrototypeChain;
         uint32_t m_numCacheableSlots;
         uint32_t m_jsStringsSize;
+        PropertyOffset m_offsetBase;
         OwnArrayPtr<WriteBarrier<Unknown> > m_jsStrings;
     };
 
diff --git a/Source/JavaScriptCore/runtime/JSValue.cpp b/Source/JavaScriptCore/runtime/JSValue.cpp
index e108671..c344311 100644
--- a/Source/JavaScriptCore/runtime/JSValue.cpp
+++ b/Source/JavaScriptCore/runtime/JSValue.cpp
@@ -130,8 +130,8 @@
     for (; ; obj = asObject(prototype)) {
         unsigned attributes;
         JSCell* specificValue;
-        size_t offset = obj->structure()->get(globalData, propertyName, attributes, specificValue);
-        if (offset != WTF::notFound) {
+        PropertyOffset offset = obj->structure()->get(globalData, propertyName, attributes, specificValue);
+        if (offset != invalidOffset) {
             if (attributes & ReadOnly) {
                 if (slot.isStrictMode())
                     throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
diff --git a/Source/JavaScriptCore/runtime/Operations.h b/Source/JavaScriptCore/runtime/Operations.h
index b2081f3..497b19d 100644
--- a/Source/JavaScriptCore/runtime/Operations.h
+++ b/Source/JavaScriptCore/runtime/Operations.h
@@ -297,7 +297,7 @@
         return jsAddSlowCase(callFrame, v1, v2);
     }
 
-    inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase, const Identifier& propertyName, size_t& slotOffset)
+    inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase, const Identifier& propertyName, PropertyOffset& slotOffset)
     {
         JSCell* cell = base.asCell();
         size_t count = 0;
diff --git a/Source/JavaScriptCore/runtime/Options.cpp b/Source/JavaScriptCore/runtime/Options.cpp
index 17743d3..b5ce39c 100644
--- a/Source/JavaScriptCore/runtime/Options.cpp
+++ b/Source/JavaScriptCore/runtime/Options.cpp
@@ -106,7 +106,6 @@
     return cpusToUse;
 }
 
-
 Options::Entry Options::s_options[Options::numberOfOptions];
 
 // Realize the names for each of the options:
@@ -124,7 +123,7 @@
     name_() = defaultValue_;
     JSC_OPTIONS(FOR_EACH_OPTION)
 #undef FOR_EACH_OPTION
-
+        
     // Allow environment vars to override options if applicable.
     // The evn var should be the name of the option prefixed with
     // "JSC_".
@@ -133,9 +132,12 @@
     overrideOptionWithHeuristic(name_(), "JSC_" #name_);
     JSC_OPTIONS(FOR_EACH_OPTION)
 #undef FOR_EACH_OPTION
-    
 #endif // RUN_TIME_HEURISTICS
 
+#if 0
+    ; // Deconfuse editors that do auto indentation
+#endif
+    
     // Do range checks where needed and make corrections to the options:
     ASSERT(thresholdForOptimizeAfterLongWarmUp() >= thresholdForOptimizeAfterWarmUp());
     ASSERT(thresholdForOptimizeAfterWarmUp() >= thresholdForOptimizeSoon());
diff --git a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
index c47f347..5953f5e 100644
--- a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
+++ b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
@@ -21,6 +21,7 @@
 #ifndef PropertyMapHashTable_h
 #define PropertyMapHashTable_h
 
+#include "PropertyOffset.h"
 #include "UString.h"
 #include "WriteBarrier.h"
 #include <wtf/HashTable.h>
@@ -72,11 +73,11 @@
 
 struct PropertyMapEntry {
     StringImpl* key;
-    unsigned offset;
+    PropertyOffset offset;
     unsigned attributes;
     WriteBarrier<JSCell> specificValue;
 
-    PropertyMapEntry(JSGlobalData& globalData, JSCell* owner, StringImpl* key, unsigned offset, unsigned attributes, JSCell* specificValue)
+    PropertyMapEntry(JSGlobalData& globalData, JSCell* owner, StringImpl* key, PropertyOffset offset, unsigned attributes, JSCell* specificValue)
         : key(key)
         , offset(offset)
         , attributes(attributes)
@@ -174,8 +175,10 @@
     // Used to maintain a list of unused entries in the property storage.
     void clearDeletedOffsets();
     bool hasDeletedOffset();
-    unsigned getDeletedOffset();
-    void addDeletedOffset(unsigned offset);
+    PropertyOffset getDeletedOffset();
+    void addDeletedOffset(PropertyOffset);
+    
+    PropertyOffset nextOffset(JSType);
 
     // Copy this PropertyTable, ensuring the copy has at least the capacity provided.
     PassOwnPtr<PropertyTable> copy(JSGlobalData&, JSCell* owner, unsigned newCapacity);
@@ -230,7 +233,7 @@
     unsigned* m_index;
     unsigned m_keyCount;
     unsigned m_deletedCount;
-    OwnPtr< Vector<unsigned> > m_deletedOffsets;
+    OwnPtr< Vector<PropertyOffset> > m_deletedOffsets;
 
     static const unsigned MinimumTableSize = 16;
     static const unsigned EmptyEntryIndex = 0;
@@ -264,9 +267,9 @@
     }
 
     // Copy the m_deletedOffsets vector.
-    Vector<unsigned>* otherDeletedOffsets = other.m_deletedOffsets.get();
+    Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
     if (otherDeletedOffsets)
-        m_deletedOffsets = adoptPtr(new Vector<unsigned>(*otherDeletedOffsets));
+        m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>(*otherDeletedOffsets));
 }
 
 inline PropertyTable::PropertyTable(JSGlobalData&, JSCell* owner, unsigned initialCapacity, const PropertyTable& other)
@@ -288,9 +291,9 @@
     }
 
     // Copy the m_deletedOffsets vector.
-    Vector<unsigned>* otherDeletedOffsets = other.m_deletedOffsets.get();
+    Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
     if (otherDeletedOffsets)
-        m_deletedOffsets = adoptPtr(new Vector<unsigned>(*otherDeletedOffsets));
+        m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>(*otherDeletedOffsets));
 }
 
 inline PropertyTable::~PropertyTable()
@@ -469,20 +472,31 @@
     return m_deletedOffsets && !m_deletedOffsets->isEmpty();
 }
 
-inline unsigned PropertyTable::getDeletedOffset()
+inline PropertyOffset PropertyTable::getDeletedOffset()
 {
-    unsigned offset = m_deletedOffsets->last();
+    PropertyOffset offset = m_deletedOffsets->last();
     m_deletedOffsets->removeLast();
     return offset;
 }
 
-inline void PropertyTable::addDeletedOffset(unsigned offset)
+inline void PropertyTable::addDeletedOffset(PropertyOffset offset)
 {
     if (!m_deletedOffsets)
-        m_deletedOffsets = adoptPtr(new Vector<unsigned>);
+        m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>);
     m_deletedOffsets->append(offset);
 }
 
+inline PropertyOffset PropertyTable::nextOffset(JSType type)
+{
+    if (hasDeletedOffset())
+        return getDeletedOffset();
+    
+    if (type == FinalObjectType)
+        return size();
+    
+    return size() + firstOutOfLineOffset;
+}
+
 inline PassOwnPtr<PropertyTable> PropertyTable::copy(JSGlobalData& globalData, JSCell* owner, unsigned newCapacity)
 {
     ASSERT(newCapacity >= m_keyCount);
@@ -499,7 +513,7 @@
 {
     size_t result = sizeof(PropertyTable) + dataSize();
     if (m_deletedOffsets)
-        result += (m_deletedOffsets->capacity() * sizeof(unsigned));
+        result += (m_deletedOffsets->capacity() * sizeof(PropertyOffset));
     return result;
 }
 #endif
diff --git a/Source/JavaScriptCore/runtime/PropertyOffset.h b/Source/JavaScriptCore/runtime/PropertyOffset.h
new file mode 100644
index 0000000..c0d1316
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/PropertyOffset.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef PropertyOffset_h
+#define PropertyOffset_h
+
+#include "JSType.h"
+#include <wtf/Platform.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/UnusedParam.h>
+
+namespace JSC {
+
+#if USE(JSVALUE32_64)
+#define INLINE_STORAGE_CAPACITY 6
+#else
+#define INLINE_STORAGE_CAPACITY 4
+#endif
+
+typedef int PropertyOffset;
+
+static const PropertyOffset invalidOffset = -1;
+static const PropertyOffset inlineStorageCapacity = INLINE_STORAGE_CAPACITY;
+static const PropertyOffset firstOutOfLineOffset = inlineStorageCapacity;
+
+// Declare all of the functions because they tend to do forward calls.
+inline void checkOffset(PropertyOffset);
+inline void checkOffset(PropertyOffset, JSType);
+inline void validateOffset(PropertyOffset);
+inline void validateOffset(PropertyOffset, JSType);
+inline bool isValidOffset(PropertyOffset);
+inline bool isInlineOffset(PropertyOffset);
+inline bool isOutOfLineOffset(PropertyOffset);
+inline size_t offsetInInlineStorage(PropertyOffset);
+inline size_t offsetInOutOfLineStorage(PropertyOffset);
+inline size_t offsetInRespectiveStorage(PropertyOffset);
+inline size_t numberOfOutOfLineSlotsForLastOffset(PropertyOffset);
+inline size_t numberOfSlotsForLastOffset(PropertyOffset, JSType);
+inline PropertyOffset nextPropertyOffsetFor(PropertyOffset, JSType);
+inline PropertyOffset firstPropertyOffsetFor(JSType);
+
+inline void checkOffset(PropertyOffset offset)
+{
+    UNUSED_PARAM(offset);
+    ASSERT(offset >= invalidOffset);
+}
+
+inline void checkOffset(PropertyOffset offset, JSType type)
+{
+    UNUSED_PARAM(offset);
+    UNUSED_PARAM(type);
+    ASSERT(offset >= invalidOffset);
+    ASSERT(offset == invalidOffset
+           || type == FinalObjectType
+           || isOutOfLineOffset(offset));
+}
+
+inline void validateOffset(PropertyOffset offset)
+{
+    checkOffset(offset);
+    ASSERT(isValidOffset(offset));
+}
+
+inline void validateOffset(PropertyOffset offset, JSType type)
+{
+    checkOffset(offset, type);
+    ASSERT(isValidOffset(offset));
+}
+
+inline bool isValidOffset(PropertyOffset offset)
+{
+    checkOffset(offset);
+    return offset != invalidOffset;
+}
+
+inline bool isInlineOffset(PropertyOffset offset)
+{
+    checkOffset(offset);
+    return offset < inlineStorageCapacity;
+}
+
+inline bool isOutOfLineOffset(PropertyOffset offset)
+{
+    checkOffset(offset);
+    return !isInlineOffset(offset);
+}
+
+inline size_t offsetInInlineStorage(PropertyOffset offset)
+{
+    validateOffset(offset);
+    ASSERT(isInlineOffset(offset));
+    return offset;
+}
+
+inline size_t offsetInOutOfLineStorage(PropertyOffset offset)
+{
+    validateOffset(offset);
+    ASSERT(isOutOfLineOffset(offset));
+    return offset - firstOutOfLineOffset;
+}
+
+inline size_t offsetInRespectiveStorage(PropertyOffset offset)
+{
+    if (isInlineOffset(offset))
+        return offsetInInlineStorage(offset);
+    return offsetInOutOfLineStorage(offset);
+}
+
+inline size_t numberOfOutOfLineSlotsForLastOffset(PropertyOffset offset)
+{
+    checkOffset(offset);
+    if (offset < firstOutOfLineOffset)
+        return 0;
+    return offset - firstOutOfLineOffset + 1;
+}
+
+inline size_t numberOfSlotsForLastOffset(PropertyOffset offset, JSType type)
+{
+    checkOffset(offset, type);
+    if (type == FinalObjectType)
+        return offset + 1;
+    return numberOfOutOfLineSlotsForLastOffset(offset);
+}
+
+inline PropertyOffset nextPropertyOffsetFor(PropertyOffset offset, JSType type)
+{
+    checkOffset(offset, type);
+    if (type != FinalObjectType && offset == invalidOffset)
+        return firstOutOfLineOffset;
+    return offset + 1;
+}
+
+inline PropertyOffset firstPropertyOffsetFor(JSType type)
+{
+    return nextPropertyOffsetFor(invalidOffset, type);
+}
+
+} // namespace JSC
+
+#endif // PropertyOffset_h
+
diff --git a/Source/JavaScriptCore/runtime/PropertySlot.h b/Source/JavaScriptCore/runtime/PropertySlot.h
index 131cf7a9..c673eaa 100644
--- a/Source/JavaScriptCore/runtime/PropertySlot.h
+++ b/Source/JavaScriptCore/runtime/PropertySlot.h
@@ -23,6 +23,7 @@
 
 #include "JSValue.h"
 #include "PropertyName.h"
+#include "PropertyOffset.h"
 #include "Register.h"
 #include <wtf/Assertions.h>
 #include <wtf/NotFound.h>
@@ -89,7 +90,7 @@
         CachedPropertyType cachedPropertyType() const { return m_cachedPropertyType; }
         bool isCacheable() const { return m_cachedPropertyType != Uncacheable; }
         bool isCacheableValue() const { return m_cachedPropertyType == Value; }
-        size_t cachedOffset() const
+        PropertyOffset cachedOffset() const
         {
             ASSERT(isCacheable());
             return m_offset;
@@ -104,7 +105,7 @@
             m_value = value;
         }
         
-        void setValue(JSValue slotBase, JSValue value, size_t offset)
+        void setValue(JSValue slotBase, JSValue value, PropertyOffset offset)
         {
             ASSERT(value);
             m_getValue = JSC_VALUE_MARKER;
@@ -160,7 +161,7 @@
             m_data.getterFunc = getterFunc;
         }
 
-        void setCacheableGetterSlot(JSValue slotBase, JSObject* getterFunc, unsigned offset)
+        void setCacheableGetterSlot(JSValue slotBase, JSObject* getterFunc, PropertyOffset offset)
         {
             ASSERT(getterFunc);
             m_getValue = GETTER_FUNCTION_MARKER;
@@ -206,7 +207,7 @@
         {
             // Clear offset even in release builds, in case this PropertySlot has been used before.
             // (For other data members, we don't need to clear anything because reuse would meaningfully overwrite them.)
-            m_offset = 0;
+            m_offset = invalidOffset;
             m_cachedPropertyType = Uncacheable;
         }
 
@@ -232,7 +233,7 @@
         JSValue m_value;
         JSValue m_thisValue;
 
-        size_t m_offset;
+        PropertyOffset m_offset;
         CachedPropertyType m_cachedPropertyType;
     };
 
diff --git a/Source/JavaScriptCore/runtime/PutPropertySlot.h b/Source/JavaScriptCore/runtime/PutPropertySlot.h
index 69d1f8b..0f694e3 100644
--- a/Source/JavaScriptCore/runtime/PutPropertySlot.h
+++ b/Source/JavaScriptCore/runtime/PutPropertySlot.h
@@ -45,14 +45,14 @@
         {
         }
 
-        void setExistingProperty(JSObject* base, size_t offset)
+        void setExistingProperty(JSObject* base, PropertyOffset offset)
         {
             m_type = ExistingProperty;
             m_base = base;
             m_offset = offset;
         }
 
-        void setNewProperty(JSObject* base, size_t offset)
+        void setNewProperty(JSObject* base, PropertyOffset offset)
         {
             m_type = NewProperty;
             m_base = base;
@@ -64,7 +64,8 @@
 
         bool isStrictMode() const { return m_isStrictMode; }
         bool isCacheable() const { return m_type != Uncachable; }
-        size_t cachedOffset() const {
+        PropertyOffset cachedOffset() const
+        {
             ASSERT(isCacheable());
             return m_offset;
         }
@@ -72,7 +73,7 @@
     private:
         Type m_type;
         JSObject* m_base;
-        size_t m_offset;
+        PropertyOffset m_offset;
         bool m_isStrictMode;
     };
 
diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp
index a2585b0..509ff3d 100644
--- a/Source/JavaScriptCore/runtime/Structure.cpp
+++ b/Source/JavaScriptCore/runtime/Structure.cpp
@@ -156,8 +156,8 @@
     , m_prototype(globalData, this, prototype)
     , m_classInfo(classInfo)
     , m_transitionWatchpointSet(InitializedWatching)
-    , m_propertyStorageCapacity(typeInfo.isFinalObject() ? JSFinalObject_inlineStorageCapacity : 0)
-    , m_offset(noOffset)
+    , m_outOfLineCapacity(0)
+    , m_offset(invalidOffset)
     , m_dictionaryKind(NoneDictionaryKind)
     , m_isPinnedPropertyTable(false)
     , m_hasGetterSetterProperties(false)
@@ -179,8 +179,8 @@
     , m_prototype(globalData, this, jsNull())
     , m_classInfo(&s_info)
     , m_transitionWatchpointSet(InitializedWatching)
-    , m_propertyStorageCapacity(0)
-    , m_offset(noOffset)
+    , m_outOfLineCapacity(0)
+    , m_offset(invalidOffset)
     , m_dictionaryKind(NoneDictionaryKind)
     , m_isPinnedPropertyTable(false)
     , m_hasGetterSetterProperties(false)
@@ -200,8 +200,8 @@
     , m_prototype(globalData, this, previous->storedPrototype())
     , m_classInfo(previous->m_classInfo)
     , m_transitionWatchpointSet(InitializedWatching)
-    , m_propertyStorageCapacity(previous->m_propertyStorageCapacity)
-    , m_offset(noOffset)
+    , m_outOfLineCapacity(previous->m_outOfLineCapacity)
+    , m_offset(invalidOffset)
     , m_dictionaryKind(previous->m_dictionaryKind)
     , m_isPinnedPropertyTable(false)
     , m_hasGetterSetterProperties(previous->m_hasGetterSetterProperties)
@@ -239,7 +239,7 @@
             ASSERT(structure->m_propertyTable);
             ASSERT(!structure->m_previous);
 
-            m_propertyTable = structure->m_propertyTable->copy(globalData, 0, m_offset + 1);
+            m_propertyTable = structure->m_propertyTable->copy(globalData, 0, numberOfSlotsForLastOffset(m_offset, m_typeInfo.type()));
             break;
         }
 
@@ -247,7 +247,7 @@
     }
 
     if (!m_propertyTable)
-        createPropertyMap(m_offset + 1);
+        createPropertyMap(numberOfSlotsForLastOffset(m_offset, m_typeInfo.type()));
 
     for (ptrdiff_t i = structures.size() - 2; i >= 0; --i) {
         structure = structures[i];
@@ -256,21 +256,21 @@
     }
 }
 
-inline size_t nextPropertyStorageCapacity(size_t currentCapacity)
+inline size_t nextOutOfLineStorageCapacity(size_t currentCapacity)
 {
     if (!currentCapacity)
         return 4;
     return currentCapacity * 2;
 }
 
-void Structure::growPropertyStorageCapacity()
+void Structure::growOutOfLineCapacity()
 {
-    m_propertyStorageCapacity = nextPropertyStorageCapacity(m_propertyStorageCapacity);
+    m_outOfLineCapacity = nextOutOfLineStorageCapacity(m_outOfLineCapacity);
 }
 
-size_t Structure::suggestedNewPropertyStorageSize()
+size_t Structure::suggestedNewOutOfLineStorageCapacity()
 {
-    return nextPropertyStorageCapacity(m_propertyStorageCapacity);
+    return nextOutOfLineStorageCapacity(m_outOfLineCapacity);
 }
  
 void Structure::despecifyDictionaryFunction(JSGlobalData& globalData, PropertyName propertyName)
@@ -287,7 +287,7 @@
     entry->specificValue.clear();
 }
 
-Structure* Structure::addPropertyTransitionToExistingStructure(Structure* structure, PropertyName propertyName, unsigned attributes, JSCell* specificValue, size_t& offset)
+Structure* Structure::addPropertyTransitionToExistingStructure(Structure* structure, PropertyName propertyName, unsigned attributes, JSCell* specificValue, PropertyOffset& offset)
 {
     ASSERT(!structure->isDictionary());
     ASSERT(structure->isObject());
@@ -296,7 +296,7 @@
         JSCell* specificValueInPrevious = existingTransition->m_specificValueInPrevious.get();
         if (specificValueInPrevious && specificValueInPrevious != specificValue)
             return 0;
-        ASSERT(existingTransition->m_offset != noOffset);
+        validateOffset(existingTransition->m_offset, structure->m_typeInfo.type());
         offset = existingTransition->m_offset;
         return existingTransition;
     }
@@ -304,7 +304,7 @@
     return 0;
 }
 
-Structure* Structure::addPropertyTransition(JSGlobalData& globalData, Structure* structure, PropertyName propertyName, unsigned attributes, JSCell* specificValue, size_t& offset)
+Structure* Structure::addPropertyTransition(JSGlobalData& globalData, Structure* structure, PropertyName propertyName, unsigned attributes, JSCell* specificValue, PropertyOffset& offset)
 {
     // If we have a specific function, we may have got to this point if there is
     // already a transition with the correct property name and attributes, but
@@ -327,8 +327,8 @@
         Structure* transition = toCacheableDictionaryTransition(globalData, structure);
         ASSERT(structure != transition);
         offset = transition->putSpecificValue(globalData, propertyName, attributes, specificValue);
-        if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
-            transition->growPropertyStorageCapacity();
+        if (transition->outOfLineSize() > transition->outOfLineCapacity())
+            transition->growOutOfLineCapacity();
         return transition;
     }
     
@@ -353,15 +353,15 @@
     }
 
     offset = transition->putSpecificValue(globalData, propertyName, attributes, specificValue);
-    if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
-        transition->growPropertyStorageCapacity();
+    if (transition->outOfLineSize() > transition->outOfLineCapacity())
+        transition->growOutOfLineCapacity();
 
     transition->m_offset = offset;
     structure->m_transitionTable.add(globalData, transition);
     return transition;
 }
 
-Structure* Structure::removePropertyTransition(JSGlobalData& globalData, Structure* structure, PropertyName propertyName, size_t& offset)
+Structure* Structure::removePropertyTransition(JSGlobalData& globalData, Structure* structure, PropertyName propertyName, PropertyOffset& offset)
 {
     ASSERT(!structure->isUncacheableDictionary());
 
@@ -548,18 +548,19 @@
 
         size_t propertyCount = m_propertyTable->size();
         Vector<JSValue> values(propertyCount);
-
+        
         unsigned i = 0;
+        PropertyOffset firstOffset = firstPropertyOffsetFor(m_typeInfo.type());
         PropertyTable::iterator end = m_propertyTable->end();
         for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter, ++i) {
             values[i] = object->getDirectOffset(iter->offset);
             // Update property table to have the new property offsets
-            iter->offset = i;
+            iter->offset = i + firstOffset;
         }
         
         // Copy the original property values into their final locations
         for (unsigned i = 0; i < propertyCount; i++)
-            object->putDirectOffset(globalData, i, values[i]);
+            object->putDirectOffset(globalData, firstOffset + i, values[i]);
 
         m_propertyTable->clearDeletedOffsets();
     }
@@ -568,7 +569,7 @@
     return this;
 }
 
-size_t Structure::addPropertyWithoutTransition(JSGlobalData& globalData, PropertyName propertyName, unsigned attributes, JSCell* specificValue)
+PropertyOffset Structure::addPropertyWithoutTransition(JSGlobalData& globalData, PropertyName propertyName, unsigned attributes, JSCell* specificValue)
 {
     ASSERT(!m_enumerationCache);
 
@@ -579,13 +580,13 @@
     
     pin();
 
-    size_t offset = putSpecificValue(globalData, propertyName, attributes, specificValue);
-    if (propertyStorageSize() > propertyStorageCapacity())
-        growPropertyStorageCapacity();
+    PropertyOffset offset = putSpecificValue(globalData, propertyName, attributes, specificValue);
+    if (outOfLineSize() > outOfLineCapacity())
+        growOutOfLineCapacity();
     return offset;
 }
 
-size_t Structure::removePropertyWithoutTransition(JSGlobalData& globalData, PropertyName propertyName)
+PropertyOffset Structure::removePropertyWithoutTransition(JSGlobalData& globalData, PropertyName propertyName)
 {
     ASSERT(isUncacheableDictionary());
     ASSERT(!m_enumerationCache);
@@ -593,8 +594,7 @@
     materializePropertyMapIfNecessaryForPinning(globalData);
 
     pin();
-    size_t offset = remove(propertyName);
-    return offset;
+    return remove(propertyName);
 }
 
 void Structure::pin()
@@ -639,20 +639,20 @@
 
 PassOwnPtr<PropertyTable> Structure::copyPropertyTableForPinning(JSGlobalData& globalData, Structure* owner)
 {
-    return adoptPtr(m_propertyTable ? new PropertyTable(globalData, owner, *m_propertyTable) : new PropertyTable(m_offset == noOffset ? 0 : m_offset));
+    return adoptPtr(m_propertyTable ? new PropertyTable(globalData, owner, *m_propertyTable) : new PropertyTable(numberOfSlotsForLastOffset(m_offset, m_typeInfo.type())));
 }
 
-size_t Structure::get(JSGlobalData& globalData, PropertyName propertyName, unsigned& attributes, JSCell*& specificValue)
+PropertyOffset Structure::get(JSGlobalData& globalData, PropertyName propertyName, unsigned& attributes, JSCell*& specificValue)
 {
     ASSERT(structure()->classInfo() == &s_info);
 
     materializePropertyMapIfNecessary(globalData);
     if (!m_propertyTable)
-        return WTF::notFound;
+        return invalidOffset;
 
     PropertyMapEntry* entry = m_propertyTable->find(propertyName.uid()).first;
     if (!entry)
-        return WTF::notFound;
+        return invalidOffset;
 
     attributes = entry->attributes;
     specificValue = entry->specificValue.get();
@@ -685,9 +685,9 @@
         iter->specificValue.clear();
 }
 
-size_t Structure::putSpecificValue(JSGlobalData& globalData, PropertyName propertyName, unsigned attributes, JSCell* specificValue)
+PropertyOffset Structure::putSpecificValue(JSGlobalData& globalData, PropertyName propertyName, unsigned attributes, JSCell* specificValue)
 {
-    ASSERT(get(globalData, propertyName) == notFound);
+    ASSERT(!JSC::isValidOffset(get(globalData, propertyName)));
 
     checkConsistency();
     if (attributes & DontEnum)
@@ -698,12 +698,7 @@
     if (!m_propertyTable)
         createPropertyMap();
 
-    unsigned newOffset;
-
-    if (m_propertyTable->hasDeletedOffset())
-        newOffset = m_propertyTable->getDeletedOffset();
-    else
-        newOffset = m_propertyTable->size();
+    PropertyOffset newOffset = m_propertyTable->nextOffset(m_typeInfo.type());
 
     m_propertyTable->add(PropertyMapEntry(globalData, this, rep, newOffset, attributes, specificValue));
 
@@ -711,20 +706,20 @@
     return newOffset;
 }
 
-size_t Structure::remove(PropertyName propertyName)
+PropertyOffset Structure::remove(PropertyName propertyName)
 {
     checkConsistency();
 
     StringImpl* rep = propertyName.uid();
 
     if (!m_propertyTable)
-        return notFound;
+        return invalidOffset;
 
     PropertyTable::find_iterator position = m_propertyTable->find(rep);
     if (!position.first)
-        return notFound;
+        return invalidOffset;
 
-    size_t offset = position.first->offset;
+    PropertyOffset offset = position.first->offset;
 
     m_propertyTable->remove(position);
     m_propertyTable->addDeletedOffset(offset);
diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h
index bb53c42..d2d025b 100644
--- a/Source/JavaScriptCore/runtime/Structure.h
+++ b/Source/JavaScriptCore/runtime/Structure.h
@@ -87,9 +87,9 @@
     public:
         static void dumpStatistics();
 
-        JS_EXPORT_PRIVATE static Structure* addPropertyTransition(JSGlobalData&, Structure*, PropertyName, unsigned attributes, JSCell* specificValue, size_t& offset);
-        JS_EXPORT_PRIVATE static Structure* addPropertyTransitionToExistingStructure(Structure*, PropertyName, unsigned attributes, JSCell* specificValue, size_t& offset);
-        static Structure* removePropertyTransition(JSGlobalData&, Structure*, PropertyName, size_t& offset);
+        JS_EXPORT_PRIVATE static Structure* addPropertyTransition(JSGlobalData&, Structure*, PropertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&);
+        JS_EXPORT_PRIVATE static Structure* addPropertyTransitionToExistingStructure(Structure*, PropertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&);
+        static Structure* removePropertyTransition(JSGlobalData&, Structure*, PropertyName, PropertyOffset&);
         JS_EXPORT_PRIVATE static Structure* changePrototypeTransition(JSGlobalData&, Structure*, JSValue prototype);
         JS_EXPORT_PRIVATE static Structure* despecifyFunctionTransition(JSGlobalData&, Structure*, PropertyName);
         static Structure* attributeChangeTransition(JSGlobalData&, Structure*, PropertyName, unsigned attributes);
@@ -103,32 +103,32 @@
         bool isFrozen(JSGlobalData&);
         bool isExtensible() const { return !m_preventExtensions; }
         bool didTransition() const { return m_didTransition; }
-        bool putWillGrowPropertyStorage()
+        bool putWillGrowOutOfLineStorage()
         {
-            ASSERT(propertyStorageCapacity() >= propertyStorageSize());
+            ASSERT(outOfLineCapacity() >= outOfLineSize());
             
             if (!m_propertyTable) {
-                unsigned currentSize = static_cast<unsigned>(m_offset + 1);
-                ASSERT(propertyStorageCapacity() >= currentSize);
-                return currentSize == propertyStorageCapacity();
+                unsigned currentSize = numberOfOutOfLineSlotsForLastOffset(m_offset);
+                ASSERT(outOfLineCapacity() >= currentSize);
+                return currentSize == outOfLineCapacity();
             }
             
-            ASSERT(propertyStorageCapacity() >= m_propertyTable->propertyStorageSize());
+            ASSERT(totalStorageCapacity() >= m_propertyTable->propertyStorageSize());
             if (m_propertyTable->hasDeletedOffset())
                 return false;
             
-            ASSERT(propertyStorageCapacity() >= m_propertyTable->size());
-            return m_propertyTable->size() == propertyStorageCapacity();
+            ASSERT(totalStorageCapacity() >= m_propertyTable->size());
+            return m_propertyTable->size() == totalStorageCapacity();
         }
-        JS_EXPORT_PRIVATE size_t suggestedNewPropertyStorageSize(); 
+        JS_EXPORT_PRIVATE size_t suggestedNewOutOfLineStorageCapacity(); 
 
         Structure* flattenDictionaryStructure(JSGlobalData&, JSObject*);
 
         static void destroy(JSCell*);
 
         // These should be used with caution.  
-        JS_EXPORT_PRIVATE size_t addPropertyWithoutTransition(JSGlobalData&, PropertyName, unsigned attributes, JSCell* specificValue);
-        size_t removePropertyWithoutTransition(JSGlobalData&, PropertyName);
+        JS_EXPORT_PRIVATE PropertyOffset addPropertyWithoutTransition(JSGlobalData&, PropertyName, unsigned attributes, JSCell* specificValue);
+        PropertyOffset removePropertyWithoutTransition(JSGlobalData&, PropertyName);
         void setPrototypeWithoutTransition(JSGlobalData& globalData, JSValue prototype) { m_prototype.set(globalData, this, prototype); }
         
         bool isDictionary() const { return m_dictionaryKind != NoneDictionaryKind; }
@@ -149,18 +149,114 @@
         StructureChain* prototypeChain(ExecState*) const;
         static void visitChildren(JSCell*, SlotVisitor&);
 
-        Structure* previousID() const { ASSERT(structure()->classInfo() == &s_info); return m_previous.get(); }
+        Structure* previousID() const
+        {
+            ASSERT(structure()->classInfo() == &s_info);
+            return m_previous.get();
+        }
         bool transitivelyTransitionedFrom(Structure* structureToFind);
 
-        void growPropertyStorageCapacity();
-        unsigned propertyStorageCapacity() const { ASSERT(structure()->classInfo() == &s_info); return m_propertyStorageCapacity; }
-        unsigned propertyStorageSize() const { ASSERT(structure()->classInfo() == &s_info); return (m_propertyTable ? m_propertyTable->propertyStorageSize() : static_cast<unsigned>(m_offset + 1)); }
-        size_t inlineStorageCapacity() const;
-        bool isUsingInlineStorage() const;
+        void growOutOfLineCapacity();
+        unsigned outOfLineCapacity() const
+        {
+            ASSERT(structure()->classInfo() == &s_info);
+            return m_outOfLineCapacity;
+        }
+        unsigned outOfLineSizeForKnownFinalObject() const
+        {
+            ASSERT(m_typeInfo.type() == FinalObjectType);
+            if (m_propertyTable) {
+                unsigned totalSize = m_propertyTable->propertyStorageSize();
+                if (totalSize < static_cast<unsigned>(inlineStorageCapacity))
+                    return 0;
+                return totalSize - inlineStorageCapacity;
+            }
+            return numberOfOutOfLineSlotsForLastOffset(m_offset);
+        }
+        unsigned outOfLineSizeForKnownNonFinalObject() const
+        {
+            ASSERT(m_typeInfo.type() != FinalObjectType);
+            if (m_propertyTable)
+                return m_propertyTable->propertyStorageSize();
+            return numberOfOutOfLineSlotsForLastOffset(m_offset);
+        }
+        unsigned outOfLineSize() const
+        {
+            ASSERT(structure()->classInfo() == &s_info);
+            if (m_propertyTable) {
+                unsigned totalSize = m_propertyTable->propertyStorageSize();
+                unsigned inlineCapacity = this->inlineCapacity();
+                if (totalSize < inlineCapacity)
+                    return 0;
+                return totalSize - inlineCapacity;
+            }
+            return numberOfOutOfLineSlotsForLastOffset(m_offset);
+        }
+        bool hasInlineStorage() const
+        {
+            return m_typeInfo.type() == FinalObjectType;
+        }
+        unsigned inlineCapacity() const
+        {
+            if (hasInlineStorage())
+                return inlineStorageCapacity;
+            return 0;
+        }
+        unsigned inlineSizeForKnownFinalObject() const
+        {
+            ASSERT(m_typeInfo.type() == FinalObjectType);
+            unsigned result;
+            if (m_propertyTable)
+                result = m_propertyTable->propertyStorageSize();
+            else
+                result = m_offset + 1;
+            if (result > static_cast<unsigned>(inlineStorageCapacity))
+                return inlineStorageCapacity;
+            return result;
+        }
+        unsigned inlineSize() const
+        {
+            if (!hasInlineStorage())
+                return 0;
+            return inlineSizeForKnownFinalObject();
+        }
+        unsigned totalStorageSize() const
+        {
+            if (m_propertyTable)
+                return m_propertyTable->propertyStorageSize();
+            return numberOfSlotsForLastOffset(m_offset, m_typeInfo.type());
+        }
+        unsigned totalStorageCapacity() const
+        {
+            ASSERT(structure()->classInfo() == &s_info);
+            return m_outOfLineCapacity + inlineCapacity();
+        }
 
-        size_t get(JSGlobalData&, PropertyName);
-        size_t get(JSGlobalData&, const UString& name);
-        JS_EXPORT_PRIVATE size_t get(JSGlobalData&, PropertyName, unsigned& attributes, JSCell*& specificValue);
+        PropertyOffset firstValidOffset() const
+        {
+            if (hasInlineStorage())
+                return 0;
+            return inlineStorageCapacity;
+        }
+        PropertyOffset lastValidOffset() const
+        {
+            if (m_propertyTable) {
+                PropertyOffset size = m_propertyTable->propertyStorageSize();
+                if (!hasInlineStorage())
+                    size += inlineStorageCapacity;
+                return size - 1;
+            }
+            return m_offset;
+        }
+        bool isValidOffset(PropertyOffset offset) const
+        {
+            return offset >= firstValidOffset()
+                && offset <= lastValidOffset();
+        }
+
+        PropertyOffset get(JSGlobalData&, PropertyName);
+        PropertyOffset get(JSGlobalData&, const UString& name);
+        JS_EXPORT_PRIVATE PropertyOffset get(JSGlobalData&, PropertyName, unsigned& attributes, JSCell*& specificValue);
 
         bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
         bool hasReadOnlyOrGetterSetterPropertiesExcludingProto() const { return m_hasReadOnlyOrGetterSetterPropertiesExcludingProto; }
@@ -177,7 +273,12 @@
 
         bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; }
         
-        bool isEmpty() const { return m_propertyTable ? m_propertyTable->isEmpty() : m_offset == noOffset; }
+        bool isEmpty() const
+        {
+            if (m_propertyTable)
+                return m_propertyTable->isEmpty();
+            return !JSC::isValidOffset(m_offset);
+        }
 
         JS_EXPORT_PRIVATE void despecifyDictionaryFunction(JSGlobalData&, PropertyName);
         void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; }
@@ -273,8 +374,8 @@
         } DictionaryKind;
         static Structure* toDictionaryTransition(JSGlobalData&, Structure*, DictionaryKind);
 
-        size_t putSpecificValue(JSGlobalData&, PropertyName, unsigned attributes, JSCell* specificValue);
-        size_t remove(PropertyName);
+        PropertyOffset putSpecificValue(JSGlobalData&, PropertyName, unsigned attributes, JSCell* specificValue);
+        PropertyOffset remove(PropertyName);
 
         void createPropertyMap(unsigned keyCount = 0);
         void checkConsistency();
@@ -301,7 +402,7 @@
         int transitionCount() const
         {
             // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both.
-            return m_offset == noOffset ? 0 : m_offset + 1;
+            return numberOfSlotsForLastOffset(m_offset, m_typeInfo.type());
         }
 
         bool isValid(ExecState*, StructureChain* cachedPrototypeChain) const;
@@ -310,8 +411,6 @@
 
         static const int s_maxTransitionLength = 64;
 
-        static const int noOffset = -1;
-
         static const unsigned maxSpecificFunctionThrashCount = 3;
 
         TypeInfo m_typeInfo;
@@ -336,10 +435,10 @@
         
         mutable InlineWatchpointSet m_transitionWatchpointSet;
 
-        uint32_t m_propertyStorageCapacity;
+        uint32_t m_outOfLineCapacity;
 
         // m_offset does not account for anonymous slots
-        int m_offset;
+        PropertyOffset m_offset;
 
         unsigned m_dictionaryKind : 2;
         bool m_isPinnedPropertyTable : 1;
@@ -353,26 +452,26 @@
         unsigned m_staticFunctionReified;
     };
 
-    inline size_t Structure::get(JSGlobalData& globalData, PropertyName propertyName)
+    inline PropertyOffset Structure::get(JSGlobalData& globalData, PropertyName propertyName)
     {
         ASSERT(structure()->classInfo() == &s_info);
         materializePropertyMapIfNecessary(globalData);
         if (!m_propertyTable)
-            return notFound;
+            return invalidOffset;
 
         PropertyMapEntry* entry = m_propertyTable->find(propertyName.uid()).first;
-        return entry ? entry->offset : notFound;
+        return entry ? entry->offset : invalidOffset;
     }
 
-    inline size_t Structure::get(JSGlobalData& globalData, const UString& name)
+    inline PropertyOffset Structure::get(JSGlobalData& globalData, const UString& name)
     {
         ASSERT(structure()->classInfo() == &s_info);
         materializePropertyMapIfNecessary(globalData);
         if (!m_propertyTable)
-            return notFound;
+            return invalidOffset;
 
         PropertyMapEntry* entry = m_propertyTable->findWithString(name.impl()).first;
-        return entry ? entry->offset : notFound;
+        return entry ? entry->offset : invalidOffset;
     }
     
     inline JSValue JSValue::structureOrUndefined() const