Allow FastCloneShallowObjectStub to use AllocationMementos.

(currently turned off)

BUG=
R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/26827002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17154 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mvstanton@chromium.org 2013-10-11 09:25:14 +00:00
parent 06f16a132c
commit 71af6c86a1
4 changed files with 46 additions and 18 deletions

View File

@ -436,22 +436,30 @@ template <>
HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() { HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() {
HValue* undefined = graph()->GetConstantUndefined(); HValue* undefined = graph()->GetConstantUndefined();
HInstruction* boilerplate = Add<HLoadKeyed>(GetParameter(0), HInstruction* allocation_site = Add<HLoadKeyed>(GetParameter(0),
GetParameter(1), GetParameter(1),
static_cast<HValue*>(NULL), static_cast<HValue*>(NULL),
FAST_ELEMENTS); FAST_ELEMENTS);
IfBuilder checker(this); IfBuilder checker(this);
checker.IfNot<HCompareObjectEqAndBranch, HValue*>(boilerplate, checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site,
undefined); undefined);
checker.And(); checker.And();
HObjectAccess access = HObjectAccess::ForAllocationSiteTransitionInfo();
HInstruction* boilerplate = Add<HLoadNamedField>(allocation_site, access);
int size = JSObject::kHeaderSize + casted_stub()->length() * kPointerSize; int size = JSObject::kHeaderSize + casted_stub()->length() * kPointerSize;
int object_size = size;
if (FLAG_allocation_site_pretenuring) {
size += AllocationMemento::kSize;
}
HValue* boilerplate_map = Add<HLoadNamedField>( HValue* boilerplate_map = Add<HLoadNamedField>(
boilerplate, HObjectAccess::ForMap()); boilerplate, HObjectAccess::ForMap());
HValue* boilerplate_size = Add<HLoadNamedField>( HValue* boilerplate_size = Add<HLoadNamedField>(
boilerplate_map, HObjectAccess::ForMapInstanceSize()); boilerplate_map, HObjectAccess::ForMapInstanceSize());
HValue* size_in_words = Add<HConstant>(size >> kPointerSizeLog2); HValue* size_in_words = Add<HConstant>(object_size >> kPointerSizeLog2);
checker.If<HCompareNumericAndBranch>(boilerplate_size, checker.If<HCompareNumericAndBranch>(boilerplate_size,
size_in_words, Token::EQ); size_in_words, Token::EQ);
checker.Then(); checker.Then();
@ -461,12 +469,17 @@ HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() {
HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(), HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(),
isolate()->heap()->GetPretenureMode(), JS_OBJECT_TYPE); isolate()->heap()->GetPretenureMode(), JS_OBJECT_TYPE);
for (int i = 0; i < size; i += kPointerSize) { for (int i = 0; i < object_size; i += kPointerSize) {
HObjectAccess access = HObjectAccess::ForJSObjectOffset(i); HObjectAccess access = HObjectAccess::ForJSObjectOffset(i);
Add<HStoreNamedField>(object, access, Add<HStoreNamedField>(object, access,
Add<HLoadNamedField>(boilerplate, access)); Add<HLoadNamedField>(boilerplate, access));
} }
ASSERT(FLAG_allocation_site_pretenuring || (size == object_size));
if (FLAG_allocation_site_pretenuring) {
BuildCreateAllocationMemento(object, object_size, allocation_site);
}
environment()->Push(object); environment()->Push(object);
checker.ElseDeopt("Uninitialized boilerplate in fast clone"); checker.ElseDeopt("Uninitialized boilerplate in fast clone");
checker.End(); checker.End();

View File

@ -207,6 +207,8 @@ DEFINE_bool(pretenuring, true, "allocate objects in old space")
// TODO(hpayer): We will remove this flag as soon as we have pretenuring // TODO(hpayer): We will remove this flag as soon as we have pretenuring
// support for specific allocation sites. // support for specific allocation sites.
DEFINE_bool(pretenuring_call_new, false, "pretenure call new") DEFINE_bool(pretenuring_call_new, false, "pretenure call new")
DEFINE_bool(allocation_site_pretenuring, false,
"pretenure with allocation sites")
DEFINE_bool(track_fields, true, "track fields with only smi values") DEFINE_bool(track_fields, true, "track fields with only smi values")
DEFINE_bool(track_double_fields, true, "track fields with double values") DEFINE_bool(track_double_fields, true, "track fields with double values")
DEFINE_bool(track_heap_object_fields, true, "track fields with heap values") DEFINE_bool(track_heap_object_fields, true, "track fields with heap values")

View File

@ -4335,15 +4335,20 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
// Check whether to use fast or slow deep-copying for boilerplate. // Check whether to use fast or slow deep-copying for boilerplate.
int max_properties = kMaxFastLiteralProperties; int max_properties = kMaxFastLiteralProperties;
Handle<Object> boilerplate(closure->literals()->get( Handle<Object> literals_cell(closure->literals()->get(expr->literal_index()),
expr->literal_index()), isolate()); isolate());
if (boilerplate->IsJSObject() && Handle<AllocationSite> site;
IsFastLiteral(Handle<JSObject>::cast(boilerplate), Handle<JSObject> boilerplate;
kMaxFastLiteralDepth, if (!literals_cell->IsUndefined()) {
&max_properties)) { // Retrieve the boilerplate
Handle<JSObject> boilerplate_object = Handle<JSObject>::cast(boilerplate); site = Handle<AllocationSite>::cast(literals_cell);
boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()),
isolate());
}
literal = BuildFastLiteral(boilerplate_object); if (!boilerplate.is_null() &&
IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) {
literal = BuildFastLiteral(boilerplate);
} else { } else {
NoObservableSideEffectsScope no_effects(this); NoObservableSideEffectsScope no_effects(this);
Handle<FixedArray> closure_literals(closure->literals(), isolate()); Handle<FixedArray> closure_literals(closure->literals(), isolate());

View File

@ -486,16 +486,24 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteral) {
bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0; bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
// Check if boilerplate exists. If not, create it first. // Check if boilerplate exists. If not, create it first.
Handle<Object> boilerplate(literals->get(literals_index), isolate); Handle<Object> literal_site(literals->get(literals_index), isolate);
if (*boilerplate == isolate->heap()->undefined_value()) { Handle<AllocationSite> site;
Handle<Object> boilerplate;
if (*literal_site == isolate->heap()->undefined_value()) {
boilerplate = CreateObjectLiteralBoilerplate(isolate, boilerplate = CreateObjectLiteralBoilerplate(isolate,
literals, literals,
constant_properties, constant_properties,
should_have_fast_elements, should_have_fast_elements,
has_function_literal); has_function_literal);
RETURN_IF_EMPTY_HANDLE(isolate, boilerplate); RETURN_IF_EMPTY_HANDLE(isolate, boilerplate);
site = isolate->factory()->NewAllocationSite();
site->set_transition_info(*boilerplate);
// Update the functions literal and return the boilerplate. // Update the functions literal and return the boilerplate.
literals->set(literals_index, *boilerplate); literals->set(literals_index, *site);
} else {
site = Handle<AllocationSite>::cast(literal_site);
boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()));
} }
Handle<Object> copy = JSObject::DeepCopy(Handle<JSObject>::cast(boilerplate)); Handle<Object> copy = JSObject::DeepCopy(Handle<JSObject>::cast(boilerplate));