[literals] Migrate deprecated sub-literals on the first run

It might happen that we deprecate the map of previous sub-literals if we create
literals with the same map several times. This is usually the case for
configuration arrays.

Bug: chromium:734051
Change-Id: I82284e5aae632286135b2092816d776d229c65af
Reviewed-on: https://chromium-review.googlesource.com/538665
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46003}
This commit is contained in:
Camillo Bruni 2017-06-19 11:48:29 +02:00 committed by Commit Bot
parent 642ce1f8ae
commit ee188afe69
5 changed files with 80 additions and 0 deletions

View File

@ -11,6 +11,24 @@
namespace v8 {
namespace internal {
class DeprecationUpdateContext {
public:
explicit DeprecationUpdateContext(Isolate* isolate) { isolate_ = isolate; }
Isolate* isolate() { return isolate_; }
bool ShouldCreateMemento(Handle<JSObject> object) { return false; }
inline void ExitScope(Handle<AllocationSite> scope_site,
Handle<JSObject> object) {}
Handle<AllocationSite> EnterNewScope() { return Handle<AllocationSite>(); }
Handle<AllocationSite> current() {
UNREACHABLE();
return Handle<AllocationSite>();
}
static const bool kCopying = false;
private:
Isolate* isolate_;
};
// AllocationSiteContext is the base class for walking and copying a nested
// boilerplate with AllocationSite and AllocationMemento support.

View File

@ -8050,6 +8050,14 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
return copy;
}
MaybeHandle<JSObject> JSObject::DeepWalk(
Handle<JSObject> object, DeprecationUpdateContext* site_context) {
JSObjectWalkVisitor<DeprecationUpdateContext> v(site_context, kNoHints);
MaybeHandle<JSObject> result = v.StructureWalk(object);
Handle<JSObject> for_assert;
DCHECK(!result.ToHandle(&for_assert) || for_assert.is_identical_to(object));
return result;
}
MaybeHandle<JSObject> JSObject::DeepWalk(
Handle<JSObject> object,

View File

@ -930,6 +930,7 @@ class AllocationSiteCreationContext;
class AllocationSiteUsageContext;
class Cell;
class ConsString;
class DeprecationUpdateContext;
class ElementsAccessor;
class FindAndReplacePattern;
class FixedArrayBase;
@ -2502,6 +2503,8 @@ class JSObject: public JSReceiver {
MUST_USE_RESULT static MaybeHandle<JSObject> DeepWalk(
Handle<JSObject> object,
AllocationSiteCreationContext* site_context);
MUST_USE_RESULT static MaybeHandle<JSObject> DeepWalk(
Handle<JSObject> object, DeprecationUpdateContext* site_context);
DECLARE_CAST(JSObject)

View File

@ -208,6 +208,12 @@ MaybeHandle<JSObject> CreateLiteral(Isolate* isolate,
boilerplate = Boilerplate::Create(isolate, vector, description, flags);
if (IsUninitializedLiteralSite(literal_site)) {
PreInitializeLiteralSite(vector, literals_slot);
if (copy_hints == JSObject::kNoHints) {
DeprecationUpdateContext update_context(isolate);
RETURN_ON_EXCEPTION(isolate,
JSObject::DeepWalk(boilerplate, &update_context),
JSObject);
}
return boilerplate;
}
// Install AllocationSite objects.

View File

@ -637,3 +637,48 @@ gc();
assertKind(elements_kind.fast_double, [instance.a, instance.b]);
}
})();
(function TestInnerBoilerplateMapDeprecation() {
// Create a literal where the inner literals cause a map deprecation of the
// previous inner literal.
function literal() {
return [
{xA2A:false, a: 1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1}
];
};
let instance = literal();
// Make sure all sub-literals are migrated properly.
for (let i = 0; i < instance.length; i++) {
let sub_literal = instance[i];
assertKind(elements_kind.fast_double, [sub_literal.a]);
assertKind(elements_kind.fast_smi_only, [sub_literal.b]);
assertKind(elements_kind.fast_smi_only, [sub_literal.c]);
assertKind(elements_kind.fast_double, [sub_literal.d]);
}
instance = literal();
instance = literal();
instance = literal();
for (let i = 0; i < instance.length; i++) {
let sub_literal = instance[i];
assertKind(elements_kind.fast_double, [sub_literal.a]);
assertKind(elements_kind.fast_smi_only, [sub_literal.b]);
assertKind(elements_kind.fast_smi_only, [sub_literal.c]);
assertKind(elements_kind.fast_double, [sub_literal.d]);
}
})();