Commit ba6907b7 authored by oliver@apple.com's avatar oliver@apple.com
Browse files

Use bump allocator for initial property storage

https://bugs.webkit.org/show_bug.cgi?id=67494

Reviewed by Geoffrey Garen.

../../../../Volumes/Data/git/WebKit/OpenSource/Source/JavaScriptCore:

Use a bump allocator for initial allocation of property storage,
and promote to fastMalloc memory only if it survives a GC pass.

Comes out as a 1% win on v8, and is a useful step on the way to
GC allocation of all property storage.

* JavaScriptCore.exp:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
* JavaScriptCore.xcodeproj/project.pbxproj:
* heap/Heap.cpp:
(JSC::Heap::collect):
* heap/Heap.h:
(JSC::Heap::allocatePropertyStorage):
(JSC::Heap::inPropertyStorageNursery):
* heap/MarkedBlock.h:
* heap/NewSpace.cpp:
(JSC::NewSpace::NewSpace):
* heap/NewSpace.h:
(JSC::NewSpace::resetPropertyStorageNursery):
(JSC::NewSpace::allocatePropertyStorage):
(JSC::NewSpace::inPropertyStorageNursery):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* runtime/JSObject.cpp:
(JSC::JSObject::allocatePropertyStorage):
* runtime/JSObject.h:
(JSC::JSObject::isUsingInlineStorage):
(JSC::JSObject::JSObject):
(JSC::JSObject::propertyStorage):
(JSC::JSObject::~JSObject):
(JSC::JSObject::putDirectInternal):
(JSC::JSObject::putDirectWithoutTransition):
(JSC::JSObject::putDirectFunctionWithoutTransition):
(JSC::JSObject::transitionTo):
(JSC::JSObject::visitChildrenDirect):
* runtime/StorageBarrier.h: Added.
(JSC::StorageBarrier::StorageBarrier):
(JSC::StorageBarrier::set):
(JSC::StorageBarrier::operator->):
(JSC::StorageBarrier::operator*):
(JSC::StorageBarrier::operator[]):
(JSC::StorageBarrier::get):

../../../../Volumes/Data/git/WebKit/OpenSource/Source/WebCore:

Add a forwarding header.

* ForwardingHeaders/runtime/StorageBarrier.h: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@94814 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 55b28ab6
2011-09-08 Oliver Hunt <oliver@apple.com>
Use bump allocator for initial property storage
https://bugs.webkit.org/show_bug.cgi?id=67494
Reviewed by Geoffrey Garen.
Use a bump allocator for initial allocation of property storage,
and promote to fastMalloc memory only if it survives a GC pass.
Comes out as a 1% win on v8, and is a useful step on the way to
GC allocation of all property storage.
* JavaScriptCore.exp:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
* JavaScriptCore.xcodeproj/project.pbxproj:
* heap/Heap.cpp:
(JSC::Heap::collect):
* heap/Heap.h:
(JSC::Heap::allocatePropertyStorage):
(JSC::Heap::inPropertyStorageNursery):
* heap/MarkedBlock.h:
* heap/NewSpace.cpp:
(JSC::NewSpace::NewSpace):
* heap/NewSpace.h:
(JSC::NewSpace::resetPropertyStorageNursery):
(JSC::NewSpace::allocatePropertyStorage):
(JSC::NewSpace::inPropertyStorageNursery):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* runtime/JSObject.cpp:
(JSC::JSObject::allocatePropertyStorage):
* runtime/JSObject.h:
(JSC::JSObject::isUsingInlineStorage):
(JSC::JSObject::JSObject):
(JSC::JSObject::propertyStorage):
(JSC::JSObject::~JSObject):
(JSC::JSObject::putDirectInternal):
(JSC::JSObject::putDirectWithoutTransition):
(JSC::JSObject::putDirectFunctionWithoutTransition):
(JSC::JSObject::transitionTo):
(JSC::JSObject::visitChildrenDirect):
* runtime/StorageBarrier.h: Added.
(JSC::StorageBarrier::StorageBarrier):
(JSC::StorageBarrier::set):
(JSC::StorageBarrier::operator->):
(JSC::StorageBarrier::operator*):
(JSC::StorageBarrier::operator[]):
(JSC::StorageBarrier::get):
2011-09-08 Sam Weinig <sam@webkit.org>
 
Remove the Completion object from JSC, I have never liked it
......
......@@ -417,6 +417,7 @@ javascriptcore_sources += \
Source/JavaScriptCore/runtime/ScopeChainMark.h \
Source/JavaScriptCore/runtime/SmallStrings.cpp \
Source/JavaScriptCore/runtime/SmallStrings.h \
Source/JavaScriptCore/runtime/StorageBarrier.h \
Source/JavaScriptCore/runtime/StrictEvalActivation.cpp \
Source/JavaScriptCore/runtime/StrictEvalActivation.h \
Source/JavaScriptCore/runtime/StringConstructor.cpp \
......
......@@ -215,6 +215,7 @@ __ZN3JSC20createReferenceErrorEPNS_9ExecStateERKNS_7UStringE
__ZN3JSC22globalMemoryStatisticsEv
__ZN3JSC22objectConstructorTableE
__ZN3JSC23AbstractSamplingCounter4dumpEv
__ZN3JSC23AbstractSamplingCounter30s_abstractSamplingCounterChainE
__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateE
__ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
__ZN3JSC24DynamicGlobalObjectScopeC1ERNS_12JSGlobalDataEPNS_14JSGlobalObjectE
......@@ -320,7 +321,7 @@ __ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE
__ZN3JSC8JSObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
__ZN3JSC8JSObject21getPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
__ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_16WriteBarrierBaseINS_7UnknownEEE
__ZN3JSC8JSObject23allocatePropertyStorageEmm
__ZN3JSC8JSObject23allocatePropertyStorageERNS_12JSGlobalDataEmm
__ZN3JSC8JSObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
__ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_7JSValueE
......
......@@ -114,6 +114,7 @@
'runtime/RopeImpl.h',
'runtime/ScopeChain.h',
'runtime/SmallStrings.h',
'runtime/StorageBarrier.h',
'runtime/StringObject.h',
'runtime/StringObjectThatMasqueradesAsUndefined.h',
'runtime/StringPrototype.h',
......
......@@ -59,7 +59,7 @@ EXPORTS
?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVExecState@2@PAVStringImpl@4@@Z
?addStaticGlobals@JSGlobalObject@JSC@@IAEXPAUGlobalPropertyInfo@12@H@Z
?allocate@Heap@JSC@@QAEPAXAAUSizeClass@NewSpace@2@@Z
?allocatePropertyStorage@JSObject@JSC@@QAEXII@Z
?allocatePropertyStorage@JSObject@JSC@@QAEXAAVJSGlobalData@2@II@Z
?allocateSlowCase@Heap@JSC@@AAEPAXAAUSizeClass@NewSpace@2@@Z
?append@StringBuilder@WTF@@QAEXPBDI@Z
?append@StringBuilder@WTF@@QAEXPB_WI@Z
......
......@@ -416,6 +416,7 @@
A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
A76C51761182748D00715B05 /* JSInterfaceJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = A76C51741182748D00715B05 /* JSInterfaceJIT.h */; };
A76F54A313B28AAB00EF2BCE /* JITWriteBarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */; };
A781E359141970C700094D90 /* StorageBarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = A781E358141970C700094D90 /* StorageBarrier.h */; settings = {ATTRIBUTES = (Private, ); }; };
A784A26111D16622005776AC /* ASTBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A7EE7411B98B8D0065A14F /* ASTBuilder.h */; };
A784A26211D16622005776AC /* JSParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7A7EE7511B98B8D0065A14F /* JSParser.cpp */; };
A784A26311D16622005776AC /* JSParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A7EE7611B98B8D0065A14F /* JSParser.h */; };
......@@ -1182,6 +1183,7 @@
A75706DD118A2BCF0057F88F /* JITArithmetic32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic32_64.cpp; sourceTree = "<group>"; };
A76C51741182748D00715B05 /* JSInterfaceJIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInterfaceJIT.h; sourceTree = "<group>"; };
A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITWriteBarrier.h; sourceTree = "<group>"; };
A781E358141970C700094D90 /* StorageBarrier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageBarrier.h; sourceTree = "<group>"; };
A791EF260F11E07900AE1F68 /* JSByteArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSByteArray.h; sourceTree = "<group>"; };
A791EF270F11E07900AE1F68 /* JSByteArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSByteArray.cpp; sourceTree = "<group>"; };
A79EDB0811531CD60019E912 /* JSObjectRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSObjectRefPrivate.h; sourceTree = "<group>"; };
......@@ -2104,6 +2106,7 @@
7E2C6C980D31C6B6002D44E2 /* ScopeChainMark.h */,
93303FE80E6A72B500786E6A /* SmallStrings.cpp */,
93303FEA0E6A72C000786E6A /* SmallStrings.h */,
A781E358141970C700094D90 /* StorageBarrier.h */,
A730B6111250068F009D25B1 /* StrictEvalActivation.cpp */,
A730B6101250068F009D25B1 /* StrictEvalActivation.h */,
BC18C3C00E16EE3300B34460 /* StringConstructor.cpp */,
......@@ -2748,6 +2751,7 @@
866739D313BFDE710023D87C /* Uint16WithFraction.h in Headers */,
BC66BAE413F492CC00C23FAE /* Compiler.h in Headers */,
A7BC0C82140608B000B1BB71 /* CheckedArithmetic.h in Headers */,
A781E359141970C700094D90 /* StorageBarrier.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -690,7 +690,7 @@ void Heap::collect(SweepToggle sweepToggle)
// new bytes allocated) proportion, and seems to work well in benchmarks.
size_t proportionalBytes = 2 * size();
m_newSpace.setHighWaterMark(max(proportionalBytes, m_minBytesPerCycle));
m_newSpace.resetPropertyStorageNursery();
JAVASCRIPTCORE_GC_END();
(*m_activityCallback)();
......
......@@ -91,6 +91,9 @@ namespace JSC {
void notifyIsSafeToCollect() { m_isSafeToCollect = true; }
void collectAllGarbage();
inline void* allocatePropertyStorage(size_t);
inline bool inPropertyStorageNursery(void*);
void reportExtraMemoryCost(size_t cost);
void protect(JSValue);
......@@ -163,7 +166,7 @@ namespace JSC {
RegisterFile& registerFile();
static void writeBarrierSlowCase(const JSCell*, JSCell*);
#if ENABLE(LAZY_BLOCK_FREEING)
void waitForRelativeTimeWhileHoldingLock(double relative);
void waitForRelativeTime(double relative);
......@@ -359,6 +362,22 @@ namespace JSC {
return allocate(sizeClass);
}
inline void* Heap::allocatePropertyStorage(size_t bytes)
{
ASSERT(!(bytes % sizeof(JSValue)));
if (bytes >= NewSpace::PropertyStorageNurserySize)
return 0;
if (void* result = m_newSpace.allocatePropertyStorage(bytes))
return result;
collect(DoNotSweep);
return m_newSpace.allocatePropertyStorage(bytes);
}
inline bool Heap::inPropertyStorageNursery(void* ptr)
{
return m_newSpace.inPropertyStorageNursery(ptr);
}
} // namespace JSC
#endif // Heap_h
......@@ -48,6 +48,7 @@ namespace JSC {
typedef uintptr_t Bits;
static const size_t KB = 1024;
static const size_t MB = 1024 * 1024;
// A marked block is a page-aligned container for heap-allocated objects.
// Objects are allocated within cells of the marked block. For a given
......
......@@ -32,7 +32,9 @@ namespace JSC {
class Structure;
NewSpace::NewSpace(Heap* heap)
: m_waterMark(0)
: m_propertyStorageNursery(static_cast<char*>(fastMalloc(PropertyStorageNurserySize)))
, m_propertyStorageAllocationPoint(m_propertyStorageNursery)
, m_waterMark(0)
, m_highWaterMark(0)
, m_heap(heap)
{
......
......@@ -46,6 +46,7 @@ namespace JSC {
WTF_MAKE_NONCOPYABLE(NewSpace);
public:
static const size_t maxCellSize = 1024;
static const size_t PropertyStorageNurserySize = 4 * MB;
struct SizeClass {
SizeClass();
......@@ -63,6 +64,10 @@ namespace JSC {
SizeClass& sizeClassFor(size_t);
void* allocate(SizeClass&);
inline void* allocatePropertyStorage(size_t);
inline bool inPropertyStorageNursery(void* ptr);
inline void resetPropertyStorageNursery();
void resetAllocator();
void addBlock(SizeClass&, MarkedBlock*);
......@@ -91,6 +96,8 @@ namespace JSC {
SizeClass m_preciseSizeClasses[preciseCount];
SizeClass m_impreciseSizeClasses[impreciseCount];
char* m_propertyStorageNursery;
char* m_propertyStorageAllocationPoint;
size_t m_waterMark;
size_t m_highWaterMark;
Heap* m_heap;
......@@ -160,6 +167,30 @@ namespace JSC {
return firstFreeCell;
}
inline void NewSpace::resetPropertyStorageNursery()
{
m_propertyStorageAllocationPoint = m_propertyStorageNursery;
}
inline void* NewSpace::allocatePropertyStorage(size_t size)
{
char* result = m_propertyStorageAllocationPoint;
if (size > PropertyStorageNurserySize)
CRASH();
m_propertyStorageAllocationPoint += size;
if (static_cast<size_t>(m_propertyStorageAllocationPoint - m_propertyStorageNursery) > PropertyStorageNurserySize) {
m_propertyStorageAllocationPoint = result;
return 0;
}
return result;
}
inline bool NewSpace::inPropertyStorageNursery(void* ptr)
{
char* addr = static_cast<char*>(ptr);
return static_cast<size_t>(addr - m_propertyStorageNursery) < PropertyStorageNurserySize;
}
template <typename Functor> inline typename Functor::ReturnType NewSpace::forEachBlock(Functor& functor)
{
for (size_t i = 0; i < preciseCount; ++i) {
......
......@@ -1481,7 +1481,7 @@ DEFINE_STUB_FUNCTION(JSObject*, op_put_by_id_transition_realloc)
ASSERT(baseValue.isObject());
JSObject* base = asObject(baseValue);
base->allocatePropertyStorage(oldSize, newSize);
base->allocatePropertyStorage(*stackFrame.globalData, oldSize, newSize);
return base;
}
......
......@@ -594,24 +594,34 @@ Structure* JSObject::createInheritorID(JSGlobalData& globalData)
return m_inheritorID.get();
}
void JSObject::allocatePropertyStorage(size_t oldSize, size_t newSize)
void JSObject::allocatePropertyStorage(JSGlobalData& globalData, size_t oldSize, size_t newSize)
{
ASSERT(newSize > oldSize);
// It's important that this function not rely on m_structure, since
// we might be in the middle of a transition.
bool wasInline = (oldSize < JSObject::baseExternalStorageCapacity);
PropertyStorage newPropertyStorage = 0;
if (globalData.heap.inPropertyStorageNursery(m_propertyStorage.get())) {
newPropertyStorage = static_cast<PropertyStorage>(globalData.heap.allocatePropertyStorage(newSize * sizeof(WriteBarrierBase<Unknown>)));
if (!newPropertyStorage || !globalData.heap.inPropertyStorageNursery(m_propertyStorage.get())) {
// If allocation failed because it's too big, or it triggered a GC
// that promoted us to old space, we need to allocate our property
// storage in old space.
newPropertyStorage = new WriteBarrierBase<Unknown>[newSize];
}
} else
newPropertyStorage = new WriteBarrierBase<Unknown>[newSize];
PropertyStorage oldPropertyStorage = m_propertyStorage;
PropertyStorage newPropertyStorage = new WriteBarrierBase<Unknown>[newSize];
PropertyStorage oldPropertyStorage = m_propertyStorage.get();
ASSERT(newPropertyStorage);
for (unsigned i = 0; i < oldSize; ++i)
newPropertyStorage[i] = oldPropertyStorage[i];
if (!wasInline)
if (!isUsingInlineStorage() && !globalData.heap.inPropertyStorageNursery(m_propertyStorage.get()))
delete [] oldPropertyStorage;
m_propertyStorage = newPropertyStorage;
m_propertyStorage.set(globalData, this, newPropertyStorage);
}
bool JSObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
......
......@@ -31,6 +31,7 @@
#include "PropertySlot.h"
#include "PutPropertySlot.h"
#include "ScopeChain.h"
#include "StorageBarrier.h"
#include "Structure.h"
#include "JSGlobalData.h"
#include "JSString.h"
......@@ -68,9 +69,6 @@ namespace JSC {
Setter = 1 << 6 // property is a setter
};
typedef WriteBarrierBase<Unknown>* PropertyStorage;
typedef const WriteBarrierBase<Unknown>* ConstPropertyStorage;
class JSObject : public JSCell {
friend class BatchedTransitionOptimizer;
friend class JIT;
......@@ -218,8 +216,8 @@ namespace JSC {
bool isFrozen(JSGlobalData& globalData) { return m_structure->isFrozen(globalData); }
bool isExtensible() { return m_structure->isExtensible(); }
void allocatePropertyStorage(size_t oldSize, size_t newSize);
bool isUsingInlineStorage() const { return static_cast<const void*>(m_propertyStorage) == static_cast<const void*>(this + 1); }
void allocatePropertyStorage(JSGlobalData&, size_t oldSize, size_t newSize);
bool isUsingInlineStorage() const { return static_cast<const void*>(m_propertyStorage.get()) == static_cast<const void*>(this + 1); }
void* addressOfPropertyAtOffset(size_t offset)
{
......@@ -291,7 +289,7 @@ namespace JSC {
JSObject(JSGlobalData&, Structure*, PropertyStorage inlineStorage);
JSObject(VPtrStealingHackType, PropertyStorage inlineStorage)
: JSCell(VPtrStealingHack)
, m_propertyStorage(inlineStorage)
, m_propertyStorage(inlineStorage, StorageBarrier::Unchecked)
{
}
......@@ -305,8 +303,8 @@ namespace JSC {
void isObject();
void isString();
ConstPropertyStorage propertyStorage() const { return m_propertyStorage; }
PropertyStorage propertyStorage() { return m_propertyStorage; }
ConstPropertyStorage propertyStorage() const { return m_propertyStorage.get(); }
PropertyStorage propertyStorage() { return m_propertyStorage.get(); }
const WriteBarrierBase<Unknown>* locationForOffset(size_t offset) const
{
......@@ -327,7 +325,7 @@ namespace JSC {
const HashEntry* findPropertyHashEntry(ExecState*, const Identifier& propertyName) const;
Structure* createInheritorID(JSGlobalData&);
PropertyStorage m_propertyStorage;
StorageBarrier m_propertyStorage;
WriteBarrier<Structure> m_inheritorID;
};
......@@ -461,14 +459,14 @@ inline JSObject* asObject(JSValue value)
inline JSObject::JSObject(JSGlobalData& globalData, Structure* structure, PropertyStorage inlineStorage)
: JSCell(globalData, structure)
, m_propertyStorage(inlineStorage)
, m_propertyStorage(globalData, this, inlineStorage)
{
}
inline JSObject::~JSObject()
{
if (!isUsingInlineStorage())
delete [] m_propertyStorage;
if (!isUsingInlineStorage() && !Heap::heap(this)->inPropertyStorageNursery(m_propertyStorage.get()))
delete [] m_propertyStorage.get();
}
inline JSValue JSObject::prototype() const
......@@ -661,7 +659,7 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
size_t currentCapacity = m_structure->propertyStorageCapacity();
offset = m_structure->addPropertyWithoutTransition(globalData, propertyName, attributes, specificFunction);
if (currentCapacity != m_structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
allocatePropertyStorage(globalData, currentCapacity, m_structure->propertyStorageCapacity());
ASSERT(offset < m_structure->propertyStorageCapacity());
putDirectOffset(globalData, offset, value);
......@@ -675,7 +673,7 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
size_t currentCapacity = m_structure->propertyStorageCapacity();
if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(m_structure.get(), propertyName, attributes, specificFunction, offset)) {
if (currentCapacity != structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
allocatePropertyStorage(globalData, currentCapacity, structure->propertyStorageCapacity());
ASSERT(offset < structure->propertyStorageCapacity());
setStructure(globalData, structure);
......@@ -725,7 +723,7 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
Structure* structure = Structure::addPropertyTransition(globalData, m_structure.get(), propertyName, attributes, specificFunction, offset);
if (currentCapacity != structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
allocatePropertyStorage(globalData, currentCapacity, structure->propertyStorageCapacity());
ASSERT(offset < structure->propertyStorageCapacity());
setStructure(globalData, structure);
......@@ -786,7 +784,7 @@ inline void JSObject::putDirectWithoutTransition(JSGlobalData& globalData, const
size_t currentCapacity = m_structure->propertyStorageCapacity();
size_t offset = m_structure->addPropertyWithoutTransition(globalData, propertyName, attributes, 0);
if (currentCapacity != m_structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
allocatePropertyStorage(globalData, currentCapacity, m_structure->propertyStorageCapacity());
putDirectOffset(globalData, offset, value);
}
......@@ -795,14 +793,14 @@ inline void JSObject::putDirectFunctionWithoutTransition(JSGlobalData& globalDat
size_t currentCapacity = m_structure->propertyStorageCapacity();
size_t offset = m_structure->addPropertyWithoutTransition(globalData, propertyName, attributes, value);
if (currentCapacity != m_structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
allocatePropertyStorage(globalData, currentCapacity, m_structure->propertyStorageCapacity());
putDirectOffset(globalData, offset, value);
}
inline void JSObject::transitionTo(JSGlobalData& globalData, Structure* newStructure)
{
if (m_structure->propertyStorageCapacity() != newStructure->propertyStorageCapacity())
allocatePropertyStorage(m_structure->propertyStorageCapacity(), newStructure->propertyStorageCapacity());
allocatePropertyStorage(globalData, m_structure->propertyStorageCapacity(), newStructure->propertyStorageCapacity());
setStructure(globalData, newStructure);
}
......@@ -893,6 +891,12 @@ ALWAYS_INLINE void JSObject::visitChildrenDirect(SlotVisitor& visitor)
JSCell::visitChildren(visitor);
PropertyStorage storage = propertyStorage();
if (Heap::heap(this)->inPropertyStorageNursery(storage)) {
m_propertyStorage.set(new WriteBarrierBase<Unknown>[structure()->propertyStorageCapacity()], StorageBarrier::Unchecked);
if (structure()->propertyStorageCapacity() > m_structure->propertyStorageSize())
ASSERT(!storage[m_structure->propertyStorageSize()]);
memcpy(m_propertyStorage.get(), storage, m_structure->propertyStorageSize() * sizeof(WriteBarrierBase<Unknown>));
}
size_t storageSize = m_structure->propertyStorageSize();
visitor.appendValues(storage, storageSize);
if (m_inheritorID)
......
/*
* Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 StorageBarrier_h
#define StorageBarrier_h
#include "JSGlobalData.h"
#include "WriteBarrier.h"
namespace JSC {
typedef WriteBarrierBase<Unknown>* PropertyStorage;
typedef const WriteBarrierBase<Unknown>* ConstPropertyStorage;
class StorageBarrier {
public:
enum UncheckedTag { Unchecked };
StorageBarrier(JSGlobalData& globalData, JSCell* owner, PropertyStorage storage)
{
set(globalData, owner, storage);
}
StorageBarrier(PropertyStorage storage, UncheckedTag)
{
set(storage, Unchecked);
}
void set(JSGlobalData& globalData, JSCell* owner, PropertyStorage newStorage)
{
if (!globalData.heap.inPropertyStorageNursery(m_storage))
globalData.heap.writeBarrier(owner, JSValue());
m_storage = newStorage;
}
void set(PropertyStorage newStorage, UncheckedTag)
{
m_storage = newStorage;
}
WriteBarrierBase<Unknown>* operator->() const { return m_storage; }
WriteBarrierBase<Unknown>* operator->() { return m_storage; }
WriteBarrierBase<Unknown> operator*() const { return *m_storage; }
WriteBarrierBase<Unknown> operator*() { return *m_storage; }
const WriteBarrierBase<Unknown>& operator[](size_t i) const { return m_storage[i]; }
WriteBarrierBase<Unknown>& operator[](size_t i) { return m_storage[i]; }
ConstPropertyStorage get() const { return m_storage; }
PropertyStorage get() { return m_storage; }
private:
PropertyStorage m_storage;
};
}
#endif
2011-09-08 Oliver Hunt <oliver@apple.com>
Use bump allocator for initial property storage
https://bugs.webkit.org/show_bug.cgi?id=67494
Reviewed by Geoffrey Garen.
Add a forwarding header.
* ForwardingHeaders/runtime/StorageBarrier.h: Added.
2011-09-08 Roland Steiner <rolandsteiner@chromium.org>
 
Unreviewed, rolling out r94809.
#ifndef WebCore_FWD_StorageBarrier_h
#define WebCore_FWD_StorageBarrier_h
#include <JavaScriptCore/StorageBarrier.h>
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment