From 8db3014974182e311d9c4a0cdafb46f9492ee284 Mon Sep 17 00:00:00 2001 From: "verwaest@chromium.org" Date: Wed, 22 May 2013 10:46:33 +0000 Subject: [PATCH] Keep representations while overwriting transitions. BUG=chromium:241477 R=jkummerow@chromium.org Review URL: https://chromiumcodereview.appspot.com/15718002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14745 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/objects.cc | 32 +++++++++++++++----------------- src/objects.h | 4 +++- test/mjsunit/track-fields.js | 19 +++++++++++++++++++ 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/objects.cc b/src/objects.cc index 6513482..31bbbdb 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -2056,8 +2056,8 @@ MaybeObject* JSObject::ConvertTransitionToMapTransition( Map* old_target = old_map->GetTransition(transition_index); Object* result; - MaybeObject* maybe_result = - ConvertDescriptorToField(name, new_value, attributes); + MaybeObject* maybe_result = ConvertDescriptorToField( + name, new_value, attributes, OMIT_TRANSITION_KEEP_REPRESENTATIONS); if (!maybe_result->To(&result)) return maybe_result; if (!HasFastProperties()) return result; @@ -2098,7 +2098,8 @@ MaybeObject* JSObject::ConvertTransitionToMapTransition( MaybeObject* JSObject::ConvertDescriptorToField(Name* name, Object* new_value, - PropertyAttributes attributes) { + PropertyAttributes attributes, + TransitionFlag flag) { if (map()->unused_property_fields() == 0 && TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) { Object* obj; @@ -2114,8 +2115,7 @@ MaybeObject* JSObject::ConvertDescriptorToField(Name* name, // Make a new map for the object. Map* new_map; - MaybeObject* maybe_new_map = map()->CopyInsertDescriptor(&new_field, - OMIT_TRANSITION); + MaybeObject* maybe_new_map = map()->CopyInsertDescriptor(&new_field, flag); if (!maybe_new_map->To(&new_map)) return maybe_new_map; // Make new properties array if necessary. @@ -6389,7 +6389,7 @@ MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, set_transitions(transitions); result->SetBackPointer(this); - } else { + } else if (flag != OMIT_TRANSITION_KEEP_REPRESENTATIONS) { descriptors->InitializeRepresentations(Representation::Tagged()); } @@ -6397,6 +6397,8 @@ MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, } +// Since this method is used to rewrite an existing transition tree, it can +// always insert transitions without checking. MaybeObject* Map::CopyInstallDescriptors(int new_descriptor, DescriptorArray* descriptors) { ASSERT(descriptors->IsSortedNoDuplicates()); @@ -6419,18 +6421,14 @@ MaybeObject* Map::CopyInstallDescriptors(int new_descriptor, result->set_unused_property_fields(unused_property_fields); result->set_owns_descriptors(false); - if (CanHaveMoreTransitions()) { - Name* name = descriptors->GetKey(new_descriptor); - TransitionArray* transitions; - MaybeObject* maybe_transitions = - AddTransition(name, result, SIMPLE_TRANSITION); - if (!maybe_transitions->To(&transitions)) return maybe_transitions; + Name* name = descriptors->GetKey(new_descriptor); + TransitionArray* transitions; + MaybeObject* maybe_transitions = + AddTransition(name, result, SIMPLE_TRANSITION); + if (!maybe_transitions->To(&transitions)) return maybe_transitions; - set_transitions(transitions); - result->SetBackPointer(this); - } else { - descriptors->InitializeRepresentations(Representation::Tagged()); - } + set_transitions(transitions); + result->SetBackPointer(this); return result; } diff --git a/src/objects.h b/src/objects.h index 2c31f30..ac74162 100644 --- a/src/objects.h +++ b/src/objects.h @@ -254,6 +254,7 @@ enum CreationFlag { // Indicates whether transitions can be added to a source map or not. enum TransitionFlag { INSERT_TRANSITION, + OMIT_TRANSITION_KEEP_REPRESENTATIONS, OMIT_TRANSITION }; @@ -2200,7 +2201,8 @@ class JSObject: public JSReceiver { MUST_USE_RESULT MaybeObject* ConvertDescriptorToField( Name* name, Object* new_value, - PropertyAttributes attributes); + PropertyAttributes attributes, + TransitionFlag flag = OMIT_TRANSITION); MUST_USE_RESULT MaybeObject* MigrateToMap(Map* new_map); MUST_USE_RESULT MaybeObject* GeneralizeFieldRepresentation( diff --git a/test/mjsunit/track-fields.js b/test/mjsunit/track-fields.js index 74389d9..ced006c 100644 --- a/test/mjsunit/track-fields.js +++ b/test/mjsunit/track-fields.js @@ -306,3 +306,22 @@ test_fic(ftest3); test_fic(ftest4); assertTrue(%HaveSameMap(ftest1, ftest3)); assertTrue(%HaveSameMap(ftest3, ftest4)); + +// Test representations and transition conversions. +function read_first_double(o) { + return o.first_double; +} +var df1 = {}; +df1.first_double=1.6; +read_first_double(df1); +read_first_double(df1); +function some_function1() { return 10; } +var df2 = {}; +df2.first_double = 1.7; +df2.second_function = some_function1; +function some_function2() { return 20; } +var df3 = {}; +df3.first_double = 1.7; +df3.second_function = some_function2; +df1.first_double = 10; +read_first_double(df1); -- 2.7.4