ObjectAllocationProfileInlines.h [plain text]
#pragma once
#include "ObjectAllocationProfile.h"
#include "JSFunctionInlines.h"
namespace JSC {
ALWAYS_INLINE void ObjectAllocationProfile::initializeProfile(VM& vm, JSGlobalObject* globalObject, JSCell* owner, JSObject* prototype, unsigned inferredInlineCapacity, JSFunction* constructor, FunctionRareData* functionRareData)
{
ASSERT(!m_allocator);
ASSERT(!m_structure);
ASSERT(!m_prototype);
ASSERT(!m_inlineCapacity);
bool isPolyProto = false;
FunctionExecutable* executable = nullptr;
if (constructor) {
executable = constructor->jsExecutable();
if (Structure* structure = executable->cachedPolyProtoStructure()) {
RELEASE_ASSERT(structure->typeInfo().type() == FinalObjectType);
m_allocator = Allocator();
m_structure.set(vm, owner, structure);
m_prototype.set(vm, owner, prototype);
m_inlineCapacity = structure->inlineCapacity();
return;
}
isPolyProto = false;
if (Options::forcePolyProto())
isPolyProto = true;
else
isPolyProto = executable->ensurePolyProtoWatchpoint().hasBeenInvalidated() && executable->singletonFunction()->hasBeenInvalidated();
}
unsigned inlineCapacity = 0;
if (inferredInlineCapacity < JSFinalObject::defaultInlineCapacity()) {
inferredInlineCapacity += possibleDefaultPropertyCount(vm, prototype);
if (!inferredInlineCapacity) {
inferredInlineCapacity = JSFinalObject::defaultInlineCapacity();
} else if (inferredInlineCapacity > JSFinalObject::defaultInlineCapacity()) {
inferredInlineCapacity = JSFinalObject::defaultInlineCapacity();
}
inlineCapacity = inferredInlineCapacity;
ASSERT(inlineCapacity < JSFinalObject::maxInlineCapacity());
} else {
inlineCapacity = inferredInlineCapacity;
if (inlineCapacity > JSFinalObject::maxInlineCapacity())
inlineCapacity = JSFinalObject::maxInlineCapacity();
}
if (isPolyProto) {
++inlineCapacity;
inlineCapacity = std::min(inlineCapacity, JSFinalObject::maxInlineCapacity());
}
ASSERT(inlineCapacity > 0);
ASSERT(inlineCapacity <= JSFinalObject::maxInlineCapacity());
size_t allocationSize = JSFinalObject::allocationSize(inlineCapacity);
Allocator allocator = subspaceFor<JSFinalObject>(vm)->allocatorForNonVirtual(allocationSize, AllocatorForMode::EnsureAllocator);
if (allocator) {
size_t slop = (allocator.cellSize() - allocationSize) / sizeof(WriteBarrier<Unknown>);
inlineCapacity += slop;
if (inlineCapacity > JSFinalObject::maxInlineCapacity())
inlineCapacity = JSFinalObject::maxInlineCapacity();
}
Structure* structure = vm.structureCache.emptyObjectStructureForPrototype(globalObject, prototype, inlineCapacity, isPolyProto, executable);
if (isPolyProto) {
ASSERT(structure->hasPolyProto());
m_allocator = Allocator();
executable->setCachedPolyProtoStructure(vm, structure);
} else {
if (executable) {
ASSERT(constructor);
ASSERT(functionRareData);
InlineWatchpointSet& polyProtoWatchpointSet = executable->ensurePolyProtoWatchpoint();
structure->ensureRareData(vm)->setSharedPolyProtoWatchpoint(executable->sharedPolyProtoWatchpoint());
if (polyProtoWatchpointSet.isStillValid() && !functionRareData->hasAllocationProfileClearingWatchpoint()) {
Watchpoint* watchpoint = functionRareData->createAllocationProfileClearingWatchpoint();
polyProtoWatchpointSet.add(watchpoint);
}
}
m_allocator = allocator;
}
WTF::storeStoreFence();
m_structure.set(vm, owner, structure);
m_prototype.set(vm, owner, prototype);
m_inlineCapacity = inlineCapacity;
}
ALWAYS_INLINE unsigned ObjectAllocationProfile::possibleDefaultPropertyCount(VM& vm, JSObject* prototype)
{
if (prototype == prototype->globalObject(vm)->objectPrototype())
return 0;
size_t count = 0;
PropertyNameArray propertyNameArray(&vm, PropertyNameMode::StringsAndSymbols, PrivateSymbolMode::Include);
prototype->structure(vm)->getPropertyNamesFromStructure(vm, propertyNameArray, EnumerationMode());
PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArray.data()->propertyNameVector();
for (size_t i = 0; i < propertyNameVector.size(); ++i) {
JSValue value = prototype->getDirect(vm, propertyNameVector[i]);
if (jsDynamicCast<JSFunction*>(vm, value))
continue;
++count;
}
return count;
}
}