Commit c2c4de29 authored by Camillo Bruni's avatar Camillo Bruni Committed by Commit Bot

[runtime] Handle deprecated boilerplate maps correctly

With the introduction of the fast-cloning double fields in the CSA stub for
literals we forgot to check for deprecated maps. As a result every subsequent
IC-miss would have to migrate the objects from such boilerplates.

This CL makes sure we don't use the deprecated map when copying boilerplates,
thus restoring the original behavior.

Bug: v8:6211 chromium:728682
Change-Id: If9ea1e0c5c6fb4236cb7a82ea33306a600925ac3
Reviewed-on: https://chromium-review.googlesource.com/538677Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45981}
parent 2850bdd7
...@@ -556,9 +556,12 @@ Node* ConstructorBuiltinsAssembler::EmitFastCloneShallowObject( ...@@ -556,9 +556,12 @@ Node* ConstructorBuiltinsAssembler::EmitFastCloneShallowObject(
VARIABLE(var_properties, MachineRepresentation::kTagged); VARIABLE(var_properties, MachineRepresentation::kTagged);
{ {
Node* bit_field_3 = LoadMapBitField3(boilerplate_map);
GotoIf(IsSetWord32<Map::Deprecated>(bit_field_3), call_runtime);
// Directly copy over the property store for dict-mode boilerplates. // Directly copy over the property store for dict-mode boilerplates.
Label if_dictionary(this), if_fast(this), done(this); Label if_dictionary(this), if_fast(this), done(this);
Branch(IsDictionaryMap(boilerplate_map), &if_dictionary, &if_fast); Branch(IsSetWord32<Map::DictionaryMap>(bit_field_3), &if_dictionary,
&if_fast);
BIND(&if_dictionary); BIND(&if_dictionary);
{ {
Comment("Copy dictionary properties"); Comment("Copy dictionary properties");
......
...@@ -199,14 +199,18 @@ MaybeHandle<JSObject> CreateLiteral(Isolate* isolate, ...@@ -199,14 +199,18 @@ MaybeHandle<JSObject> CreateLiteral(Isolate* isolate,
Handle<AllocationSite> site; Handle<AllocationSite> site;
Handle<JSObject> boilerplate; Handle<JSObject> boilerplate;
if (!HasBoilerplate(isolate, literal_site)) { if (HasBoilerplate(isolate, literal_site)) {
site = Handle<AllocationSite>::cast(literal_site);
boilerplate =
Handle<JSObject>(JSObject::cast(site->transition_info()), isolate);
} else {
// Instantiate a JSArray or JSObject literal from the given {description}. // Instantiate a JSArray or JSObject literal from the given {description}.
boilerplate = Boilerplate::Create(isolate, vector, description, flags); boilerplate = Boilerplate::Create(isolate, vector, description, flags);
if (IsUninitializedLiteralSite(literal_site)) { if (IsUninitializedLiteralSite(literal_site)) {
PreInitializeLiteralSite(vector, literals_slot); PreInitializeLiteralSite(vector, literals_slot);
return boilerplate; return boilerplate;
} }
// Install AllocationSite objects.
AllocationSiteCreationContext creation_context(isolate); AllocationSiteCreationContext creation_context(isolate);
site = creation_context.EnterNewScope(); site = creation_context.EnterNewScope();
RETURN_ON_EXCEPTION( RETURN_ON_EXCEPTION(
...@@ -214,10 +218,6 @@ MaybeHandle<JSObject> CreateLiteral(Isolate* isolate, ...@@ -214,10 +218,6 @@ MaybeHandle<JSObject> CreateLiteral(Isolate* isolate,
creation_context.ExitScope(site, boilerplate); creation_context.ExitScope(site, boilerplate);
vector->Set(literals_slot, *site); vector->Set(literals_slot, *site);
} else {
site = Handle<AllocationSite>::cast(literal_site);
boilerplate =
Handle<JSObject>(JSObject::cast(site->transition_info()), isolate);
} }
STATIC_ASSERT(static_cast<int>(ObjectLiteral::kDisableMementos) == STATIC_ASSERT(static_cast<int>(ObjectLiteral::kDisableMementos) ==
......
...@@ -614,3 +614,26 @@ gc(); ...@@ -614,3 +614,26 @@ gc();
var b = make(); var b = make();
assertKind(elements_kind.fast_double, b); assertKind(elements_kind.fast_double, b);
})(); })();
(function TestBoilerplateMapDeprecation() {
function literal() {
return { a: 1, b: 2 };
}
literal();
literal();
let instance = literal();
assertKind(elements_kind.fast_smi_only, [instance.a, instance.b]);
// Create literal instances with double insteand of smi values.
for (let i = 0; i < 1000; i++) {
instance = literal();
instance.a = 1.2;
assertKind(elements_kind.fast_double, [instance.a, instance.b]);
}
// After deprecating the original boilerplate map we should get heap numbers
// back for the original unmodified literal as well.
for (let i =0; i < 100; i++) {
instance = literal();
assertKind(elements_kind.fast_double, [instance.a, instance.b]);
}
})();
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