Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(852)

Unified Diff: src/objects.cc

Issue 167303005: Track field types. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index aaa03203ae444987ec954edb1d4e19012e0791c5..dae7d51b6a1195117f87dcc108944324a1701cc7 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -73,6 +73,23 @@ MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor,
}
+Handle<HeapType> Object::OptimalType(Isolate* isolate,
+ Representation representation) {
+ if (!FLAG_track_field_types) return HeapType::Any(isolate);
+ if (representation.IsNone()) return HeapType::None(isolate);
+ if (representation.IsHeapObject() && IsHeapObject()) {
+ // We can track only JavaScript objects with stable maps.
+ Handle<Map> map(HeapObject::cast(this)->map(), isolate);
+ if (map->is_stable() &&
+ map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE &&
+ map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE) {
+ return HeapType::Class(map, isolate);
+ }
+ }
+ return HeapType::Any(isolate);
+}
+
+
MaybeObject* Object::ToObject(Context* native_context) {
if (IsNumber()) {
return CreateJSValue(native_context->number_function(), this);
@@ -1447,7 +1464,9 @@ void Map::PrintGeneralization(FILE* file,
int descriptors,
bool constant_to_field,
Representation old_representation,
- Representation new_representation) {
+ Representation new_representation,
+ HeapType* old_field_type,
+ HeapType* new_field_type) {
PrintF(file, "[generalizing ");
constructor_name()->PrintOn(file);
PrintF(file, "] ");
@@ -1457,13 +1476,19 @@ void Map::PrintGeneralization(FILE* file,
} else {
PrintF(file, "{symbol %p}", static_cast<void*>(name));
}
+ PrintF(file, ":");
if (constant_to_field) {
- PrintF(file, ":c->f");
+ PrintF(file, "c");
} else {
- PrintF(file, ":%s->%s",
- old_representation.Mnemonic(),
- new_representation.Mnemonic());
- }
+ PrintF(file, "%s", old_representation.Mnemonic());
+ PrintF(file, "{");
+ old_field_type->TypePrint(file, HeapType::SEMANTIC_DIM);
+ PrintF(file, "}");
+ }
+ PrintF(file, "->%s", new_representation.Mnemonic());
+ PrintF(file, "{");
+ new_field_type->TypePrint(file, HeapType::SEMANTIC_DIM);
+ PrintF(file, "}");
PrintF(file, " (");
if (strlen(reason) > 0) {
PrintF(file, "%s", reason);
@@ -1855,10 +1880,12 @@ static Handle<Object> NewStorageFor(Isolate* isolate,
static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map,
Handle<Name> name,
int index,
+ Handle<HeapType> field_type,
PropertyAttributes attributes,
Representation representation,
TransitionFlag flag) {
- FieldDescriptor new_field_desc(name, index, attributes, representation);
+ FieldDescriptor new_field_desc(name, index, field_type,
+ attributes, representation);
Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag);
int unused_property_fields = map->unused_property_fields() - 1;
if (unused_property_fields < 0) {
@@ -1895,11 +1922,14 @@ void JSObject::AddFastProperty(Handle<JSObject> object,
// Compute the new index for new field.
int index = object->map()->NextFreePropertyIndex();
- // Allocate new instance descriptors with (name, index) added
+ // Compute the optimal representation for the new field.
if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED;
Representation representation = value->OptimalRepresentation(value_type);
+
Handle<Map> new_map = CopyAddFieldDescriptor(
- handle(object->map()), name, index, attributes, representation, flag);
+ handle(object->map()), name, index,
+ value->OptimalType(isolate, representation),
+ attributes, representation, flag);
JSObject::MigrateToMap(object, new_map);
@@ -2345,9 +2375,11 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object,
int modify_index,
Representation new_representation,
+ Handle<HeapType> new_field_type,
StoreMode store_mode) {
Handle<Map> new_map = Map::GeneralizeRepresentation(
- handle(object->map()), modify_index, new_representation, store_mode);
+ handle(object->map()), modify_index, new_representation,
+ new_field_type, store_mode);
if (object->map() == *new_map) return;
return MigrateToMap(object, new_map);
}
@@ -2368,16 +2400,22 @@ Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map,
StoreMode store_mode,
PropertyAttributes attributes,
const char* reason) {
+ Isolate* isolate = map->GetIsolate();
Handle<Map> new_map = Copy(map);
DescriptorArray* descriptors = new_map->instance_descriptors();
- descriptors->InitializeRepresentations(Representation::Tagged());
+ int length = descriptors->number_of_descriptors();
+ for (int i = 0; i < length; i++) {
+ descriptors->SetRepresentation(i, Representation::Tagged());
+ if (descriptors->GetDetails(i).type() == FIELD) {
+ descriptors->SetValue(i, HeapType::Any());
+ }
+ }
// Unless the instance is being migrated, ensure that modify_index is a field.
PropertyDetails details = descriptors->GetDetails(modify_index);
if (store_mode == FORCE_FIELD && details.type() != FIELD) {
- FieldDescriptor d(handle(descriptors->GetKey(modify_index),
- map->GetIsolate()),
+ FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate),
new_map->NumberOfFields(),
attributes,
Representation::Tagged());
@@ -2390,11 +2428,15 @@ Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map,
}
if (FLAG_trace_generalization) {
+ HeapType* field_type = (details.type() == FIELD)
+ ? map->instance_descriptors()->GetFieldType(modify_index)
+ : NULL;
map->PrintGeneralization(stdout, reason, modify_index,
new_map->NumberOfOwnDescriptors(),
new_map->NumberOfOwnDescriptors(),
details.type() == CONSTANT && store_mode == FORCE_FIELD,
- Representation::Tagged(), Representation::Tagged());
+ details.representation(), Representation::Tagged(),
+ field_type, HeapType::Any());
}
return new_map;
}
@@ -2459,6 +2501,8 @@ Map* Map::FindRootMap() {
Map* Map::FindUpdatedMap(int verbatim,
int length,
DescriptorArray* descriptors) {
+ DisallowHeapAllocation no_allocation;
+
// This can only be called on roots of transition trees.
ASSERT(GetBackPointer()->IsUndefined());
@@ -2493,6 +2537,8 @@ Map* Map::FindUpdatedMap(int verbatim,
Map* Map::FindLastMatchMap(int verbatim,
int length,
DescriptorArray* descriptors) {
+ DisallowHeapAllocation no_allocation;
+
// This can only be called on roots of transition trees.
ASSERT(GetBackPointer()->IsUndefined());
@@ -2508,13 +2554,17 @@ Map* Map::FindLastMatchMap(int verbatim,
Map* next = transitions->GetTarget(transition);
DescriptorArray* next_descriptors = next->instance_descriptors();
- if (next_descriptors->GetValue(i) != descriptors->GetValue(i)) break;
-
PropertyDetails details = descriptors->GetDetails(i);
PropertyDetails next_details = next_descriptors->GetDetails(i);
if (details.type() != next_details.type()) break;
if (details.attributes() != next_details.attributes()) break;
if (!details.representation().Equals(next_details.representation())) break;
+ if (next_details.type() == FIELD) {
+ if (!descriptors->GetFieldType(i)->NowIs(
+ next_descriptors->GetFieldType(i))) break;
+ } else {
+ if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break;
+ }
current = next;
}
@@ -2522,6 +2572,87 @@ Map* Map::FindLastMatchMap(int verbatim,
}
+Map* Map::FindFieldOwner(int descriptor) {
+ DisallowHeapAllocation no_allocation;
+ ASSERT_EQ(FIELD, instance_descriptors()->GetDetails(descriptor).type());
+ Map* result = this;
+ while (true) {
+ Object* back = result->GetBackPointer();
+ if (back->IsUndefined()) break;
+ Map* parent = Map::cast(back);
+ if (parent->NumberOfOwnDescriptors() <= descriptor) break;
+ result = parent;
+ }
+ return result;
+}
+
+
+void Map::UpdateDescriptor(int descriptor_number, Descriptor* desc) {
+ DisallowHeapAllocation no_allocation;
+ if (HasTransitionArray()) {
+ TransitionArray* transitions = this->transitions();
+ for (int i = 0; i < transitions->number_of_transitions(); ++i) {
+ transitions->GetTarget(i)->UpdateDescriptor(descriptor_number, desc);
+ }
+ }
+ instance_descriptors()->Replace(descriptor_number, desc);;
+}
+
+
+// static
+Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> old_field_type,
+ Handle<HeapType> new_field_type,
+ Isolate* isolate) {
+ if (new_field_type->NowIs(old_field_type)) return old_field_type;
+ if (old_field_type->NowIs(new_field_type)) return new_field_type;
+ return HeapType::Any(isolate);
+}
+
+
+// static
+void Map::GeneralizeFieldType(Handle<Map> map,
+ int modify_index,
+ Handle<HeapType> new_field_type) {
+ Isolate* isolate = map->GetIsolate();
+ Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate);
+ Handle<DescriptorArray> descriptors(
+ field_owner->instance_descriptors(), isolate);
+
+ // Check if we actually need to generalize the field type at all.
+ Handle<HeapType> old_field_type(
+ descriptors->GetFieldType(modify_index), isolate);
+ if (new_field_type->NowIs(old_field_type)) {
+ ASSERT(Map::GeneralizeFieldType(old_field_type,
+ new_field_type,
+ isolate)->NowIs(old_field_type));
+ return;
+ }
+
+ // Determine the generalized new field type.
+ new_field_type = Map::GeneralizeFieldType(
+ old_field_type, new_field_type, isolate);
+
+ PropertyDetails details = descriptors->GetDetails(modify_index);
+ FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate),
+ descriptors->GetFieldIndex(modify_index),
+ new_field_type,
+ details.attributes(),
+ details.representation());
+ field_owner->UpdateDescriptor(modify_index, &d);
+ field_owner->dependent_code()->DeoptimizeDependentCodeGroup(
+ isolate, DependentCode::kFieldTypeGroup);
+
+ if (FLAG_trace_generalization) {
+ map->PrintGeneralization(
+ stdout, "field type generalization",
+ modify_index, map->NumberOfOwnDescriptors(),
+ map->NumberOfOwnDescriptors(), false,
+ details.representation(), details.representation(),
+ *old_field_type, *new_field_type);
+ }
+}
+
+
// Generalize the representation of the descriptor at |modify_index|.
// This method rewrites the transition tree to reflect the new change. To avoid
// high degrees over polymorphism, and to stabilize quickly, on every rewrite
@@ -2543,6 +2674,7 @@ Map* Map::FindLastMatchMap(int verbatim,
Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
int modify_index,
Representation new_representation,
+ Handle<HeapType> new_field_type,
StoreMode store_mode) {
Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
@@ -2555,11 +2687,28 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
if (old_representation.IsNone() &&
!new_representation.IsNone() &&
!new_representation.IsDouble()) {
+ ASSERT(old_details.type() == FIELD);
+ ASSERT(old_descriptors->GetFieldType(modify_index)->NowIs(
+ HeapType::None()));
+ if (FLAG_trace_generalization) {
+ old_map->PrintGeneralization(
+ stdout, "uninitialized field",
+ modify_index, old_map->NumberOfOwnDescriptors(),
+ old_map->NumberOfOwnDescriptors(), false,
+ old_representation, new_representation,
+ old_descriptors->GetFieldType(modify_index), *new_field_type);
+ }
old_descriptors->SetRepresentation(modify_index, new_representation);
+ old_descriptors->SetValue(modify_index, *new_field_type);
+ return old_map;
+ }
+
+ if (new_representation.Equals(old_representation) &&
+ old_details.type() == FIELD) {
+ Map::GeneralizeFieldType(old_map, modify_index, new_field_type);
return old_map;
}
- int descriptors = old_map->NumberOfOwnDescriptors();
Handle<Map> root_map(old_map->FindRootMap());
// Check the state of the root map.
@@ -2575,6 +2724,7 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
old_details.attributes(), "root modification");
}
+ int descriptors = old_map->NumberOfOwnDescriptors();
Map* raw_updated = root_map->FindUpdatedMap(
verbatim, descriptors, *old_descriptors);
if (raw_updated == NULL) {
@@ -2604,6 +2754,7 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
ASSERT(store_mode == ALLOW_AS_CONSTANT ||
new_descriptors->GetDetails(modify_index).type() == FIELD);
+ Isolate* isolate = new_descriptors->GetIsolate();
old_representation =
new_descriptors->GetDetails(modify_index).representation();
Representation updated_representation =
@@ -2611,6 +2762,13 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
if (!updated_representation.Equals(old_representation)) {
new_descriptors->SetRepresentation(modify_index, updated_representation);
}
+ if (new_descriptors->GetDetails(modify_index).type() == FIELD) {
+ Handle<HeapType> field_type(
+ new_descriptors->GetFieldType(modify_index), isolate);
+ new_field_type = Map::GeneralizeFieldType(
+ field_type, new_field_type, isolate);
+ new_descriptors->SetValue(modify_index, *new_field_type);
+ }
Handle<Map> split_map(root_map->FindLastMatchMap(
verbatim, descriptors, *new_descriptors));
@@ -2625,11 +2783,21 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
old_descriptors->GetKey(descriptor), *new_descriptors);
if (FLAG_trace_generalization) {
+ PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
+ PropertyDetails new_details = new_descriptors->GetDetails(modify_index);
+ Handle<HeapType> old_field_type = (old_details.type() == FIELD)
+ ? handle(old_descriptors->GetFieldType(modify_index), isolate)
+ : HeapType::Constant(handle(old_descriptors->GetValue(modify_index),
+ isolate), isolate);
+ Handle<HeapType> new_field_type = (new_details.type() == FIELD)
+ ? handle(new_descriptors->GetFieldType(modify_index), isolate)
+ : HeapType::Constant(handle(new_descriptors->GetValue(modify_index),
+ isolate), isolate);
old_map->PrintGeneralization(
stdout, "", modify_index, descriptor, descriptors,
- old_descriptors->GetDetails(modify_index).type() == CONSTANT &&
- store_mode == FORCE_FIELD,
- old_representation, updated_representation);
+ old_details.type() == CONSTANT && store_mode == FORCE_FIELD,
+ old_details.representation(), new_details.representation(),
+ *old_field_type, *new_field_type);
}
// Add missing transitions.
@@ -2645,13 +2813,13 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
// Generalize the representation of all FIELD descriptors.
Handle<Map> Map::GeneralizeAllFieldRepresentations(
- Handle<Map> map,
- Representation new_representation) {
+ Handle<Map> map) {
Handle<DescriptorArray> descriptors(map->instance_descriptors());
- for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
- PropertyDetails details = descriptors->GetDetails(i);
- if (details.type() == FIELD) {
- map = GeneralizeRepresentation(map, i, new_representation, FORCE_FIELD);
+ for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) {
+ if (descriptors->GetDetails(i).type() == FIELD) {
+ map = GeneralizeRepresentation(map, i, Representation::Tagged(),
+ HeapType::Any(map->GetIsolate()),
+ FORCE_FIELD);
}
}
return map;
@@ -3790,7 +3958,9 @@ void JSObject::MigrateInstance(Handle<JSObject> object) {
// transition that matches the object. This achieves what is needed.
Handle<Map> original_map(object->map());
GeneralizeFieldRepresentation(
- object, 0, Representation::None(), ALLOW_AS_CONSTANT);
+ object, 0, Representation::None(),
+ HeapType::None(object->GetIsolate()),
+ ALLOW_AS_CONSTANT);
object->map()->set_migration_target(true);
if (FLAG_trace_migration) {
object->PrintInstanceMigration(stdout, *original_map, object->map());
@@ -3819,7 +3989,7 @@ MaybeHandle<Object> JSObject::SetPropertyUsingTransition(
Handle<Map> transition_map(lookup->GetTransitionTarget());
int descriptor = transition_map->LastAdded();
- DescriptorArray* descriptors = transition_map->instance_descriptors();
+ Handle<DescriptorArray> descriptors(transition_map->instance_descriptors());
PropertyDetails details = descriptors->GetDetails(descriptor);
if (details.type() == CALLBACKS || attributes != details.attributes()) {
@@ -3836,17 +4006,19 @@ MaybeHandle<Object> JSObject::SetPropertyUsingTransition(
// Keep the target CONSTANT if the same value is stored.
// TODO(verwaest): Also support keeping the placeholder
// (value->IsUninitialized) as constant.
- if (!lookup->CanHoldValue(value) ||
- (details.type() == CONSTANT &&
- descriptors->GetValue(descriptor) != *value)) {
- transition_map = Map::GeneralizeRepresentation(transition_map,
- descriptor, value->OptimalRepresentation(), FORCE_FIELD);
+ if (!lookup->CanHoldValue(value)) {
+ Representation field_representation = value->OptimalRepresentation();
+ Handle<HeapType> field_type = value->OptimalType(
+ lookup->isolate(), field_representation);
+ transition_map = Map::GeneralizeRepresentation(
+ transition_map, descriptor,
+ field_representation, field_type, FORCE_FIELD);
}
JSObject::MigrateToMap(object, transition_map);
// Reload.
- descriptors = transition_map->instance_descriptors();
+ descriptors = handle(transition_map->instance_descriptors());
details = descriptors->GetDetails(descriptor);
if (details.type() != FIELD) return value;
@@ -3868,11 +4040,13 @@ MaybeHandle<Object> JSObject::SetPropertyUsingTransition(
static void SetPropertyToField(LookupResult* lookup,
Handle<Object> value) {
Representation representation = lookup->representation();
- if (!lookup->CanHoldValue(value) ||
- lookup->type() == CONSTANT) {
+ if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) {
+ Representation field_representation = value->OptimalRepresentation();
+ Handle<HeapType> field_type = value->OptimalType(
+ lookup->isolate(), field_representation);
JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()),
lookup->GetDescriptorIndex(),
- value->OptimalRepresentation(),
+ field_representation, field_type,
FORCE_FIELD);
DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
int descriptor = lookup->GetDescriptorIndex();
@@ -3908,7 +4082,8 @@ static void ConvertAndSetLocalProperty(LookupResult* lookup,
int descriptor_index = lookup->GetDescriptorIndex();
if (lookup->GetAttributes() == attributes) {
JSObject::GeneralizeFieldRepresentation(
- object, descriptor_index, Representation::Tagged(), FORCE_FIELD);
+ object, descriptor_index, Representation::Tagged(),
+ HeapType::Any(lookup->isolate()), FORCE_FIELD);
} else {
Handle<Map> old_map(object->map());
Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map,
@@ -6896,7 +7071,13 @@ Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map,
map->set_transitions(*transitions);
result->SetBackPointer(*map);
} else {
- descriptors->InitializeRepresentations(Representation::Tagged());
+ int length = descriptors->number_of_descriptors();
+ for (int i = 0; i < length; i++) {
+ descriptors->SetRepresentation(i, Representation::Tagged());
+ if (descriptors->GetDetails(i).type() == FIELD) {
+ descriptors->SetValue(i, HeapType::Any());
+ }
+ }
}
return result;
@@ -8085,16 +8266,27 @@ Handle<DescriptorArray> DescriptorArray::Merge(Handle<Map> left_map,
(left_details.type() == CONSTANT &&
right_details.type() == CONSTANT &&
left->GetValue(descriptor) != right->GetValue(descriptor))) {
+ ASSERT(left_details.type() == CONSTANT || left_details.type() == FIELD);
+ ASSERT(right_details.type() == CONSTANT || right_details.type() == FIELD);
Representation representation = left_details.representation().generalize(
right_details.representation());
- FieldDescriptor d(handle(left->GetKey(descriptor)),
+ Handle<HeapType> left_type = (left_details.type() == FIELD)
+ ? handle(left->GetFieldType(descriptor), isolate)
+ : left->GetValue(descriptor)->OptimalType(isolate, representation);
+ Handle<HeapType> right_type = (right_details.type() == FIELD)
+ ? handle(right->GetFieldType(descriptor), isolate)
+ : right->GetValue(descriptor)->OptimalType(isolate, representation);
+ Handle<HeapType> field_type = Map::GeneralizeFieldType(
+ left_type, right_type, isolate);
+ FieldDescriptor d(handle(left->GetKey(descriptor), isolate),
current_offset++,
+ field_type,
right_details.attributes(),
representation);
result->Set(descriptor, &d);
} else {
- Descriptor d(handle(right->GetKey(descriptor)),
- handle(right->GetValue(descriptor), right->GetIsolate()),
+ Descriptor d(handle(right->GetKey(descriptor), isolate),
+ handle(right->GetValue(descriptor), isolate),
right_details);
result->Set(descriptor, &d);
}
@@ -8103,16 +8295,27 @@ Handle<DescriptorArray> DescriptorArray::Merge(Handle<Map> left_map,
// |valid| -> |new_size|
for (; descriptor < new_size; descriptor++) {
PropertyDetails right_details = right->GetDetails(descriptor);
- if (right_details.type() == FIELD ||
- (store_mode == FORCE_FIELD && descriptor == modify_index)) {
- FieldDescriptor d(handle(right->GetKey(descriptor)),
+ if (right_details.type() == FIELD) {
+ FieldDescriptor d(handle(right->GetKey(descriptor), isolate),
current_offset++,
+ handle(right->GetFieldType(descriptor), isolate),
right_details.attributes(),
right_details.representation());
result->Set(descriptor, &d);
+ } else if (store_mode == FORCE_FIELD && descriptor == modify_index) {
+ ASSERT_EQ(CONSTANT, right_details.type());
+ Representation field_representation = right_details.representation();
+ Handle<HeapType> field_type = right->GetValue(descriptor)->OptimalType(
+ isolate, field_representation);
+ FieldDescriptor d(handle(right->GetKey(descriptor), isolate),
+ current_offset++,
+ field_type,
+ right_details.attributes(),
+ field_representation);
+ result->Set(descriptor, &d);
} else {
- Descriptor d(handle(right->GetKey(descriptor)),
- handle(right->GetValue(descriptor), right->GetIsolate()),
+ Descriptor d(handle(right->GetKey(descriptor), isolate),
+ handle(right->GetValue(descriptor), isolate),
right_details);
result->Set(descriptor, &d);
}
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698