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

Side by Side Diff: src/objects.cc

Issue 22911018: Remove special case code for generalizing constants to fields. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1432 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 PrintF(file, " from "); 1443 PrintF(file, " from ");
1444 from_elements->ShortPrint(file); 1444 from_elements->ShortPrint(file);
1445 PrintF(file, " to "); 1445 PrintF(file, " to ");
1446 to_elements->ShortPrint(file); 1446 to_elements->ShortPrint(file);
1447 PrintF(file, "\n"); 1447 PrintF(file, "\n");
1448 } 1448 }
1449 } 1449 }
1450 1450
1451 1451
1452 void Map::PrintGeneralization(FILE* file, 1452 void Map::PrintGeneralization(FILE* file,
1453 const char* reason,
1453 int modify_index, 1454 int modify_index,
1454 int split, 1455 int split,
1455 int descriptors, 1456 int descriptors,
1457 bool constant_to_field,
1456 Representation old_representation, 1458 Representation old_representation,
1457 Representation new_representation) { 1459 Representation new_representation) {
1458 PrintF(file, "[generalizing "); 1460 PrintF(file, "[generalizing ");
1459 constructor_name()->PrintOn(file); 1461 constructor_name()->PrintOn(file);
1460 PrintF(file, "] "); 1462 PrintF(file, "] ");
1461 String::cast(instance_descriptors()->GetKey(modify_index))->PrintOn(file); 1463 String::cast(instance_descriptors()->GetKey(modify_index))->PrintOn(file);
1462 PrintF(file, ":%s->%s (+%i maps) [", 1464 if (constant_to_field) {
1463 old_representation.Mnemonic(), 1465 PrintF(file, ":c->f");
1464 new_representation.Mnemonic(), 1466 } else {
1465 descriptors - split); 1467 PrintF(file, ":%s->%s",
1468 old_representation.Mnemonic(),
1469 new_representation.Mnemonic());
1470 }
1471 PrintF(file, " (");
1472 if (strlen(reason) > 0) {
1473 PrintF(file, "%s", reason);
1474 } else {
1475 PrintF(file, "+%i maps", descriptors - split);
1476 }
1477 PrintF(file, ") [");
1466 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); 1478 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true);
1467 PrintF(file, "]\n"); 1479 PrintF(file, "]\n");
1468 } 1480 }
1469 1481
1470 1482
1471 void JSObject::PrintInstanceMigration(FILE* file, 1483 void JSObject::PrintInstanceMigration(FILE* file,
1472 Map* original_map, 1484 Map* original_map,
1473 Map* new_map) { 1485 Map* new_map) {
1474 PrintF(file, "[migrating "); 1486 PrintF(file, "[migrating ");
1475 map()->constructor_name()->PrintOn(file); 1487 map()->constructor_name()->PrintOn(file);
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
1981 1993
1982 1994
1983 MaybeObject* JSObject::AddConstantProperty( 1995 MaybeObject* JSObject::AddConstantProperty(
1984 Name* name, 1996 Name* name,
1985 Object* constant, 1997 Object* constant,
1986 PropertyAttributes attributes) { 1998 PropertyAttributes attributes) {
1987 // Allocate new instance descriptors with (name, constant) added 1999 // Allocate new instance descriptors with (name, constant) added
1988 ConstantDescriptor d(name, constant, attributes); 2000 ConstantDescriptor d(name, constant, attributes);
1989 2001
1990 TransitionFlag flag = 2002 TransitionFlag flag =
1991 // Do not add transitions to global objects. 2003 // Do not add transitions to global objects.
1992 (IsGlobalObject() || 2004 (IsGlobalObject() ||
1993 // Don't add transitions to special properties with non-trivial 2005 // Don't add transitions to special properties with non-trivial
1994 // attributes. 2006 // attributes.
1995 attributes != NONE) 2007 attributes != NONE)
1996 ? OMIT_TRANSITION 2008 ? OMIT_TRANSITION
1997 : INSERT_TRANSITION; 2009 : INSERT_TRANSITION;
1998 2010
1999 Map* new_map; 2011 Map* new_map;
2000 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag); 2012 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag);
2001 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 2013 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
2183 if (old_index != -1) { 2195 if (old_index != -1) {
2184 // All calls to ReplaceSlowProperty have had all transitions removed. 2196 // All calls to ReplaceSlowProperty have had all transitions removed.
2185 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index(); 2197 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index();
2186 } 2198 }
2187 2199
2188 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); 2200 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
2189 return SetNormalizedProperty(name, value, new_details); 2201 return SetNormalizedProperty(name, value, new_details);
2190 } 2202 }
2191 2203
2192 2204
2193 MaybeObject* JSObject::ConvertTransitionToMapTransition(
2194 int transition_index,
2195 Name* name,
2196 Object* new_value,
2197 PropertyAttributes attributes) {
2198 Map* old_map = map();
2199 Map* old_target = old_map->GetTransition(transition_index);
2200 Object* result;
2201
2202 MaybeObject* maybe_result = ConvertDescriptorToField(
2203 name, new_value, attributes, OMIT_TRANSITION_KEEP_REPRESENTATIONS);
2204 if (!maybe_result->To(&result)) return maybe_result;
2205
2206 if (!HasFastProperties()) return result;
2207
2208 // This method should only be used to convert existing transitions.
2209 Map* new_map = map();
2210
2211 // TODO(verwaest): From here on we lose existing map transitions, causing
2212 // invalid back pointers. This will change once we can store multiple
2213 // transitions with the same key.
2214 bool owned_descriptors = old_map->owns_descriptors();
2215 if (owned_descriptors ||
2216 old_target->instance_descriptors() == old_map->instance_descriptors()) {
2217 // Since the conversion above generated a new fast map with an additional
2218 // property which can be shared as well, install this descriptor pointer
2219 // along the entire chain of smaller maps.
2220 Map* map;
2221 DescriptorArray* new_descriptors = new_map->instance_descriptors();
2222 DescriptorArray* old_descriptors = old_map->instance_descriptors();
2223 for (Object* current = old_map;
2224 !current->IsUndefined();
2225 current = map->GetBackPointer()) {
2226 map = Map::cast(current);
2227 if (map->instance_descriptors() != old_descriptors) break;
2228 map->SetEnumLength(Map::kInvalidEnumCache);
2229 map->set_instance_descriptors(new_descriptors);
2230 }
2231 old_map->set_owns_descriptors(false);
2232 }
2233
2234 old_target->DeprecateTransitionTree();
2235
2236 old_map->SetTransition(transition_index, new_map);
2237 new_map->SetBackPointer(old_map);
2238 return result;
2239 }
2240
2241
2242 MaybeObject* JSObject::ConvertDescriptorToField(Name* name, 2205 MaybeObject* JSObject::ConvertDescriptorToField(Name* name,
2243 Object* new_value, 2206 Object* new_value,
2244 PropertyAttributes attributes, 2207 PropertyAttributes attributes,
2245 TransitionFlag flag) { 2208 TransitionFlag flag) {
2246 if (map()->unused_property_fields() == 0 && 2209 if (map()->unused_property_fields() == 0 &&
2247 TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) { 2210 TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) {
2248 Object* obj; 2211 Object* obj;
2249 MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 2212 MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2250 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 2213 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2251 return ReplaceSlowProperty(name, new_value, attributes); 2214 return ReplaceSlowProperty(name, new_value, attributes);
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
2484 } 2447 }
2485 2448
2486 set_map(new_map); 2449 set_map(new_map);
2487 2450
2488 return this; 2451 return this;
2489 } 2452 }
2490 2453
2491 2454
2492 MaybeObject* JSObject::GeneralizeFieldRepresentation( 2455 MaybeObject* JSObject::GeneralizeFieldRepresentation(
2493 int modify_index, 2456 int modify_index,
2494 Representation new_representation) { 2457 Representation new_representation,
2458 StoreMode store_mode) {
2495 Map* new_map; 2459 Map* new_map;
2496 MaybeObject* maybe_new_map = 2460 MaybeObject* maybe_new_map = map()->GeneralizeRepresentation(
2497 map()->GeneralizeRepresentation(modify_index, new_representation); 2461 modify_index, new_representation, store_mode);
2498 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 2462 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
2499 if (map() == new_map) return this; 2463 if (map() == new_map) return this;
2500 2464
2501 return MigrateToMap(new_map); 2465 return MigrateToMap(new_map);
2502 } 2466 }
2503 2467
2504 2468
2505 int Map::NumberOfFields() { 2469 int Map::NumberOfFields() {
2506 DescriptorArray* descriptors = instance_descriptors(); 2470 DescriptorArray* descriptors = instance_descriptors();
2507 int result = 0; 2471 int result = 0;
2508 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { 2472 for (int i = 0; i < NumberOfOwnDescriptors(); i++) {
2509 if (descriptors->GetDetails(i).type() == FIELD) result++; 2473 if (descriptors->GetDetails(i).type() == FIELD) result++;
2510 } 2474 }
2511 return result; 2475 return result;
2512 } 2476 }
2513 2477
2514 2478
2515 MaybeObject* Map::CopyGeneralizeAllRepresentations() { 2479 MaybeObject* Map::CopyGeneralizeAllRepresentations(
2480 int modify_index,
2481 StoreMode store_mode,
2482 const char* reason) {
2516 Map* new_map; 2483 Map* new_map;
2517 MaybeObject* maybe_map = this->Copy(); 2484 MaybeObject* maybe_map = this->Copy();
2518 if (!maybe_map->To(&new_map)) return maybe_map; 2485 if (!maybe_map->To(&new_map)) return maybe_map;
2519 2486
2520 new_map->instance_descriptors()->InitializeRepresentations( 2487 DescriptorArray* descriptors = new_map->instance_descriptors();
2521 Representation::Tagged()); 2488 descriptors->InitializeRepresentations(Representation::Tagged());
2489
2490 // Unless the instance is being migrated, ensure that modify_index is a field.
2491 PropertyDetails details = descriptors->GetDetails(modify_index);
2492 if (store_mode == FORCE_FIELD && details.type() != FIELD) {
2493 FieldDescriptor d(descriptors->GetKey(modify_index),
2494 new_map->NumberOfFields(),
2495 details.attributes(),
2496 Representation::Tagged());
2497 d.SetSortedKeyIndex(details.pointer());
2498 descriptors->Set(modify_index, &d);
2499 int unused_property_fields = new_map->unused_property_fields() - 1;
2500 if (unused_property_fields < 0) {
2501 unused_property_fields += JSObject::kFieldsAdded;
2502 }
2503 new_map->set_unused_property_fields(unused_property_fields);
2504 }
2505
2522 if (FLAG_trace_generalization) { 2506 if (FLAG_trace_generalization) {
2523 PrintF("failed generalization %p -> %p\n", 2507 PrintGeneralization(stdout, reason, modify_index,
2524 static_cast<void*>(this), static_cast<void*>(new_map)); 2508 new_map->NumberOfOwnDescriptors(),
2509 new_map->NumberOfOwnDescriptors(),
2510 details.type() == CONSTANT && store_mode == FORCE_FIELD,
2511 Representation::Tagged(), Representation::Tagged());
2525 } 2512 }
2526 return new_map; 2513 return new_map;
2527 } 2514 }
2528 2515
2529 2516
2530 void Map::DeprecateTransitionTree() { 2517 void Map::DeprecateTransitionTree() {
2531 if (!FLAG_track_fields) return; 2518 if (!FLAG_track_fields) return;
2532 if (is_deprecated()) return; 2519 if (is_deprecated()) return;
2533 if (HasTransitionArray()) { 2520 if (HasTransitionArray()) {
2534 TransitionArray* transitions = this->transitions(); 2521 TransitionArray* transitions = this->transitions();
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
2659 // walk the transition tree. 2646 // walk the transition tree.
2660 // - Merge/generalize the descriptor array of the current map and |updated|. 2647 // - Merge/generalize the descriptor array of the current map and |updated|.
2661 // - Generalize the |modify_index| descriptor using |new_representation|. 2648 // - Generalize the |modify_index| descriptor using |new_representation|.
2662 // - Walk the tree again starting from the root towards |updated|. Stop at 2649 // - Walk the tree again starting from the root towards |updated|. Stop at
2663 // |split_map|, the first map who's descriptor array does not match the merged 2650 // |split_map|, the first map who's descriptor array does not match the merged
2664 // descriptor array. 2651 // descriptor array.
2665 // - If |updated| == |split_map|, |updated| is in the expected state. Return it. 2652 // - If |updated| == |split_map|, |updated| is in the expected state. Return it.
2666 // - Otherwise, invalidate the outdated transition target from |updated|, and 2653 // - Otherwise, invalidate the outdated transition target from |updated|, and
2667 // replace its transition tree with a new branch for the updated descriptors. 2654 // replace its transition tree with a new branch for the updated descriptors.
2668 MaybeObject* Map::GeneralizeRepresentation(int modify_index, 2655 MaybeObject* Map::GeneralizeRepresentation(int modify_index,
2669 Representation new_representation) { 2656 Representation new_representation,
2657 StoreMode store_mode) {
2670 Map* old_map = this; 2658 Map* old_map = this;
2671 DescriptorArray* old_descriptors = old_map->instance_descriptors(); 2659 DescriptorArray* old_descriptors = old_map->instance_descriptors();
2672 Representation old_representation = 2660 Representation old_representation =
2673 old_descriptors->GetDetails(modify_index).representation(); 2661 old_descriptors->GetDetails(modify_index).representation();
2674 2662
2675 // It's fine to transition from None to anything but double without any 2663 // It's fine to transition from None to anything but double without any
2676 // modification to the object, because the default uninitialized value for 2664 // modification to the object, because the default uninitialized value for
2677 // representation None can be overwritten by both smi and tagged values. 2665 // representation None can be overwritten by both smi and tagged values.
2678 // Doubles, however, would require a box allocation. 2666 // Doubles, however, would require a box allocation.
2679 if (old_representation.IsNone() && 2667 if (old_representation.IsNone() &&
2680 !new_representation.IsNone() && 2668 !new_representation.IsNone() &&
2681 !new_representation.IsDouble()) { 2669 !new_representation.IsDouble()) {
2682 old_descriptors->SetRepresentation(modify_index, new_representation); 2670 old_descriptors->SetRepresentation(modify_index, new_representation);
2683 return old_map; 2671 return old_map;
2684 } 2672 }
2685 2673
2686 int descriptors = old_map->NumberOfOwnDescriptors(); 2674 int descriptors = old_map->NumberOfOwnDescriptors();
2687 Map* root_map = old_map->FindRootMap(); 2675 Map* root_map = old_map->FindRootMap();
2688 2676
2689 // Check the state of the root map. 2677 // Check the state of the root map.
2690 if (!old_map->EquivalentToForTransition(root_map)) { 2678 if (!old_map->EquivalentToForTransition(root_map)) {
2691 return CopyGeneralizeAllRepresentations(); 2679 return CopyGeneralizeAllRepresentations(
2680 modify_index, store_mode, "not equivalent");
2692 } 2681 }
2693 2682
2694 int verbatim = root_map->NumberOfOwnDescriptors(); 2683 int verbatim = root_map->NumberOfOwnDescriptors();
2695 2684
2685 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) {
2686 return CopyGeneralizeAllRepresentations(
2687 modify_index, store_mode, "root modification");
2688 }
2689
2696 Map* updated = root_map->FindUpdatedMap( 2690 Map* updated = root_map->FindUpdatedMap(
2697 verbatim, descriptors, old_descriptors); 2691 verbatim, descriptors, old_descriptors);
2698 if (updated == NULL) return CopyGeneralizeAllRepresentations(); 2692 if (updated == NULL) {
2693 return CopyGeneralizeAllRepresentations(
2694 modify_index, store_mode, "incompatible");
2695 }
2699 2696
2700 DescriptorArray* updated_descriptors = updated->instance_descriptors(); 2697 DescriptorArray* updated_descriptors = updated->instance_descriptors();
2701 2698
2702 int valid = updated->NumberOfOwnDescriptors(); 2699 int valid = updated->NumberOfOwnDescriptors();
2700
2701 // Directly change the map if the target map is more general. Ensure that the
2702 // target type of the modify_index is a FIELD, unless we are migrating.
2703 if (updated_descriptors->IsMoreGeneralThan( 2703 if (updated_descriptors->IsMoreGeneralThan(
2704 verbatim, valid, descriptors, old_descriptors)) { 2704 verbatim, valid, descriptors, old_descriptors) &&
2705 (store_mode == ALLOW_AS_CONSTANT ||
2706 updated_descriptors->GetDetails(modify_index).type() == FIELD)) {
2705 Representation updated_representation = 2707 Representation updated_representation =
2706 updated_descriptors->GetDetails(modify_index).representation(); 2708 updated_descriptors->GetDetails(modify_index).representation();
2707 if (new_representation.fits_into(updated_representation)) { 2709 if (new_representation.fits_into(updated_representation)) return updated;
2708 if (FLAG_trace_generalization &&
2709 !(modify_index == 0 && new_representation.IsNone())) {
2710 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2711 PrintGeneralization(stdout, modify_index, descriptors, descriptors,
2712 old_details.representation(),
2713 updated_representation);
2714 }
2715 return updated;
2716 }
2717 } 2710 }
2718 2711
2719 DescriptorArray* new_descriptors; 2712 DescriptorArray* new_descriptors;
2720 MaybeObject* maybe_descriptors = updated_descriptors->Merge( 2713 MaybeObject* maybe_descriptors = updated_descriptors->Merge(
2721 verbatim, valid, descriptors, old_descriptors); 2714 verbatim, valid, descriptors, modify_index, store_mode, old_descriptors);
2722 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; 2715 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
2716 ASSERT(store_mode == ALLOW_AS_CONSTANT ||
2717 new_descriptors->GetDetails(modify_index).type() == FIELD);
2723 2718
2724 old_representation = 2719 old_representation =
2725 new_descriptors->GetDetails(modify_index).representation(); 2720 new_descriptors->GetDetails(modify_index).representation();
2726 Representation updated_representation = 2721 Representation updated_representation =
2727 new_representation.generalize(old_representation); 2722 new_representation.generalize(old_representation);
2728 if (!updated_representation.Equals(old_representation)) { 2723 if (!updated_representation.Equals(old_representation)) {
2729 new_descriptors->SetRepresentation(modify_index, updated_representation); 2724 new_descriptors->SetRepresentation(modify_index, updated_representation);
2730 } 2725 }
2731 2726
2732 Map* split_map = root_map->FindLastMatchMap( 2727 Map* split_map = root_map->FindLastMatchMap(
2733 verbatim, descriptors, new_descriptors); 2728 verbatim, descriptors, new_descriptors);
2734 2729
2735 int split_descriptors = split_map->NumberOfOwnDescriptors(); 2730 int split_descriptors = split_map->NumberOfOwnDescriptors();
2736 // This is shadowed by |updated_descriptors| being more general than 2731 // This is shadowed by |updated_descriptors| being more general than
2737 // |old_descriptors|. 2732 // |old_descriptors|.
2738 ASSERT(descriptors != split_descriptors); 2733 ASSERT(descriptors != split_descriptors);
2739 2734
2740 int descriptor = split_descriptors; 2735 int descriptor = split_descriptors;
2741 split_map->DeprecateTarget( 2736 split_map->DeprecateTarget(
2742 old_descriptors->GetKey(descriptor), new_descriptors); 2737 old_descriptors->GetKey(descriptor), new_descriptors);
2743 2738
2744 if (FLAG_trace_generalization && 2739 if (FLAG_trace_generalization && store_mode != ALLOW_AS_CONSTANT) {
2745 !(modify_index == 0 && new_representation.IsNone())) { 2740 PrintGeneralization(
2746 PrintGeneralization(stdout, modify_index, descriptor, descriptors, 2741 stdout, "", modify_index, descriptor, descriptors,
2747 old_representation, updated_representation); 2742 old_descriptors->GetDetails(modify_index).type() == CONSTANT,
2743 old_representation, updated_representation);
2748 } 2744 }
2749 2745
2750 Map* new_map = split_map; 2746 Map* new_map = split_map;
2751 // Add missing transitions. 2747 // Add missing transitions.
2752 for (; descriptor < descriptors; descriptor++) { 2748 for (; descriptor < descriptors; descriptor++) {
2753 MaybeObject* maybe_map = new_map->CopyInstallDescriptors( 2749 MaybeObject* maybe_map = new_map->CopyInstallDescriptors(
2754 descriptor, new_descriptors); 2750 descriptor, new_descriptors);
2755 if (!maybe_map->To(&new_map)) { 2751 if (!maybe_map->To(&new_map)) {
2756 // Create a handle for the last created map to ensure it stays alive 2752 // Create a handle for the last created map to ensure it stays alive
2757 // during GC. Its descriptor array is too large, but it will be 2753 // during GC. Its descriptor array is too large, but it will be
(...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after
3775 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { 3771 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) {
3776 CALL_HEAP_FUNCTION( 3772 CALL_HEAP_FUNCTION(
3777 object->GetIsolate(), 3773 object->GetIsolate(),
3778 object->MigrateInstance(), 3774 object->MigrateInstance(),
3779 Object); 3775 Object);
3780 } 3776 }
3781 3777
3782 3778
3783 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map, 3779 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map,
3784 int modify_index, 3780 int modify_index,
3785 Representation representation) { 3781 Representation representation,
3782 StoreMode store_mode) {
3786 CALL_HEAP_FUNCTION( 3783 CALL_HEAP_FUNCTION(
3787 map->GetIsolate(), 3784 map->GetIsolate(),
3788 map->GeneralizeRepresentation(modify_index, representation), 3785 map->GeneralizeRepresentation(modify_index, representation, store_mode),
3789 Map); 3786 Map);
3790 } 3787 }
3791 3788
3792 3789
3790 static MaybeObject* SetPropertyUsingTransition(LookupResult* lookup,
3791 Handle<Name> name,
3792 Handle<Object> value,
3793 PropertyAttributes attributes) {
3794 Map* transition_map = lookup->GetTransitionTarget();
3795 int descriptor = transition_map->LastAdded();
3796
3797 DescriptorArray* descriptors = transition_map->instance_descriptors();
3798 PropertyDetails details = descriptors->GetDetails(descriptor);
3799
3800 if (details.type() == CALLBACKS || attributes != details.attributes()) {
3801 return lookup->holder()->ConvertDescriptorToField(
3802 *name, *value, attributes);
3803 }
3804
3805 // Keep the target CONSTANT if the same value is stored.
3806 // TODO(verwaest): Also support keeping the placeholder
3807 // (value->IsUninitialized) as constant.
3808 if (details.type() == CONSTANT &&
3809 descriptors->GetValue(descriptor) == *value) {
3810 lookup->holder()->set_map(transition_map);
3811 return *value;
3812 }
3813
3814 Representation representation = details.representation();
3815
3816 if (!value->FitsRepresentation(representation) ||
3817 details.type() == CONSTANT) {
3818 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation(
3819 descriptor, value->OptimalRepresentation(), FORCE_FIELD);
3820 if (!maybe_map->To(&transition_map)) return maybe_map;
3821 Object* back = transition_map->GetBackPointer();
3822 if (back->IsMap()) {
3823 MaybeObject* maybe_failure =
3824 lookup->holder()->MigrateToMap(Map::cast(back));
3825 if (maybe_failure->IsFailure()) return maybe_failure;
3826 }
3827 descriptors = transition_map->instance_descriptors();
3828 representation = descriptors->GetDetails(descriptor).representation();
3829 }
3830
3831 int field_index = descriptors->GetFieldIndex(descriptor);
3832 return lookup->holder()->AddFastPropertyUsingMap(
3833 transition_map, *name, *value, field_index, representation);
3834 }
3835
3836
3837 static MaybeObject* SetPropertyToField(LookupResult* lookup,
3838 Handle<Name> name,
3839 Handle<Object> value) {
3840 Representation representation = lookup->representation();
3841 if (!value->FitsRepresentation(representation) ||
3842 lookup->type() == CONSTANT) {
3843 MaybeObject* maybe_failure =
3844 lookup->holder()->GeneralizeFieldRepresentation(
3845 lookup->GetDescriptorIndex(),
3846 value->OptimalRepresentation(),
3847 FORCE_FIELD);
3848 if (maybe_failure->IsFailure()) return maybe_failure;
3849 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
3850 int descriptor = lookup->GetDescriptorIndex();
3851 representation = desc->GetDetails(descriptor).representation();
3852 }
3853
3854 if (FLAG_track_double_fields && representation.IsDouble()) {
3855 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
3856 lookup->GetFieldIndex().field_index()));
3857 storage->set_value(value->Number());
3858 return *value;
3859 }
3860
3861 lookup->holder()->FastPropertyAtPut(
3862 lookup->GetFieldIndex().field_index(), *value);
3863 return *value;
3864 }
3865
3866
3793 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, 3867 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
3794 Name* name_raw, 3868 Name* name_raw,
3795 Object* value_raw, 3869 Object* value_raw,
3796 PropertyAttributes attributes, 3870 PropertyAttributes attributes,
3797 StrictModeFlag strict_mode, 3871 StrictModeFlag strict_mode,
3798 StoreFromKeyed store_mode) { 3872 StoreFromKeyed store_mode) {
3799 Heap* heap = GetHeap(); 3873 Heap* heap = GetHeap();
3800 Isolate* isolate = heap->isolate(); 3874 Isolate* isolate = heap->isolate();
3801 // Make sure that the top context does not change when doing callbacks or 3875 // Make sure that the top context does not change when doing callbacks or
3802 // interceptor calls. 3876 // interceptor calls.
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
3871 old_value = Object::GetProperty(self, name); 3945 old_value = Object::GetProperty(self, name);
3872 } 3946 }
3873 3947
3874 // This is a real property that is not read-only, or it is a 3948 // This is a real property that is not read-only, or it is a
3875 // transition or null descriptor and there are no setters in the prototypes. 3949 // transition or null descriptor and there are no setters in the prototypes.
3876 MaybeObject* result = *value; 3950 MaybeObject* result = *value;
3877 switch (lookup->type()) { 3951 switch (lookup->type()) {
3878 case NORMAL: 3952 case NORMAL:
3879 result = lookup->holder()->SetNormalizedProperty(lookup, *value); 3953 result = lookup->holder()->SetNormalizedProperty(lookup, *value);
3880 break; 3954 break;
3881 case FIELD: { 3955 case FIELD:
3882 Representation representation = lookup->representation(); 3956 result = SetPropertyToField(lookup, name, value);
3883 if (!value->FitsRepresentation(representation)) {
3884 MaybeObject* maybe_failure =
3885 lookup->holder()->GeneralizeFieldRepresentation(
3886 lookup->GetDescriptorIndex(), value->OptimalRepresentation());
3887 if (maybe_failure->IsFailure()) return maybe_failure;
3888 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
3889 int descriptor = lookup->GetDescriptorIndex();
3890 representation = desc->GetDetails(descriptor).representation();
3891 }
3892 if (FLAG_track_double_fields && representation.IsDouble()) {
3893 HeapNumber* storage =
3894 HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
3895 lookup->GetFieldIndex().field_index()));
3896 storage->set_value(value->Number());
3897 result = *value;
3898 break;
3899 }
3900 lookup->holder()->FastPropertyAtPut(
3901 lookup->GetFieldIndex().field_index(), *value);
3902 result = *value;
3903 break; 3957 break;
3904 }
3905 case CONSTANT: 3958 case CONSTANT:
3906 // Only replace the constant if necessary. 3959 // Only replace the constant if necessary.
3907 if (*value == lookup->GetConstant()) return *value; 3960 if (*value == lookup->GetConstant()) return *value;
3908 // Preserve the attributes of this existing property. 3961 result = SetPropertyToField(lookup, name, value);
3909 attributes = lookup->GetAttributes();
3910 result = lookup->holder()->ConvertDescriptorToField(
3911 *name, *value, attributes);
3912 break; 3962 break;
3913 case CALLBACKS: { 3963 case CALLBACKS: {
3914 Object* callback_object = lookup->GetCallbackObject(); 3964 Object* callback_object = lookup->GetCallbackObject();
3915 return self->SetPropertyWithCallback( 3965 return self->SetPropertyWithCallback(
3916 callback_object, *name, *value, lookup->holder(), strict_mode); 3966 callback_object, *name, *value, lookup->holder(), strict_mode);
3917 } 3967 }
3918 case INTERCEPTOR: 3968 case INTERCEPTOR:
3919 result = lookup->holder()->SetPropertyWithInterceptor( 3969 result = lookup->holder()->SetPropertyWithInterceptor(
3920 *name, *value, attributes, strict_mode); 3970 *name, *value, attributes, strict_mode);
3921 break; 3971 break;
3922 case TRANSITION: { 3972 case TRANSITION: {
3923 Map* transition_map = lookup->GetTransitionTarget(); 3973 result = SetPropertyUsingTransition(lookup, name, value, attributes);
3924 int descriptor = transition_map->LastAdded();
3925
3926 DescriptorArray* descriptors = transition_map->instance_descriptors();
3927 PropertyDetails details = descriptors->GetDetails(descriptor);
3928
3929 if (details.type() == FIELD) {
3930 if (attributes == details.attributes()) {
3931 Representation representation = details.representation();
3932 if (!value->FitsRepresentation(representation)) {
3933 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation(
3934 descriptor, value->OptimalRepresentation());
3935 if (!maybe_map->To(&transition_map)) return maybe_map;
3936 Object* back = transition_map->GetBackPointer();
3937 if (back->IsMap()) {
3938 MaybeObject* maybe_failure =
3939 lookup->holder()->MigrateToMap(Map::cast(back));
3940 if (maybe_failure->IsFailure()) return maybe_failure;
3941 }
3942 DescriptorArray* desc = transition_map->instance_descriptors();
3943 int descriptor = transition_map->LastAdded();
3944 representation = desc->GetDetails(descriptor).representation();
3945 }
3946 int field_index = descriptors->GetFieldIndex(descriptor);
3947 result = lookup->holder()->AddFastPropertyUsingMap(
3948 transition_map, *name, *value, field_index, representation);
3949 } else {
3950 result = lookup->holder()->ConvertDescriptorToField(
3951 *name, *value, attributes);
3952 }
3953 } else if (details.type() == CALLBACKS) {
3954 result = lookup->holder()->ConvertDescriptorToField(
3955 *name, *value, attributes);
3956 } else {
3957 ASSERT(details.type() == CONSTANT);
3958
3959 Object* constant = descriptors->GetValue(descriptor);
3960 if (constant == *value) {
3961 // If the same constant function is being added we can simply
3962 // transition to the target map.
3963 lookup->holder()->set_map(transition_map);
3964 result = constant;
3965 } else {
3966 // Otherwise, replace with a map transition to a new map with a FIELD,
3967 // even if the value is a constant function.
3968 result = lookup->holder()->ConvertTransitionToMapTransition(
3969 lookup->GetTransitionIndex(), *name, *value, attributes);
3970 }
3971 }
3972 break; 3974 break;
3973 } 3975 }
3974 case HANDLER: 3976 case HANDLER:
3975 case NONEXISTENT: 3977 case NONEXISTENT:
3976 UNREACHABLE(); 3978 UNREACHABLE();
3977 } 3979 }
3978 3980
3979 Handle<Object> hresult; 3981 Handle<Object> hresult;
3980 if (!result->ToHandle(&hresult, isolate)) return result; 3982 if (!result->ToHandle(&hresult, isolate)) return result;
3981 3983
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
4081 } 4083 }
4082 4084
4083 // Check of IsReadOnly removed from here in clone. 4085 // Check of IsReadOnly removed from here in clone.
4084 MaybeObject* result = *value; 4086 MaybeObject* result = *value;
4085 switch (lookup.type()) { 4087 switch (lookup.type()) {
4086 case NORMAL: { 4088 case NORMAL: {
4087 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); 4089 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0);
4088 result = self->SetNormalizedProperty(*name, *value, details); 4090 result = self->SetNormalizedProperty(*name, *value, details);
4089 break; 4091 break;
4090 } 4092 }
4091 case FIELD: { 4093 case FIELD:
4092 Representation representation = lookup.representation(); 4094 if (value->IsUninitialized()) break;
4093 Representation value_representation = 4095 result = SetPropertyToField(&lookup, name, value);
4094 value->OptimalRepresentation(value_type);
4095 if (value_representation.IsNone()) break;
4096 if (!value_representation.fits_into(representation)) {
4097 MaybeObject* maybe_failure = self->GeneralizeFieldRepresentation(
4098 lookup.GetDescriptorIndex(), value_representation);
4099 if (maybe_failure->IsFailure()) return maybe_failure;
4100 DescriptorArray* desc = self->map()->instance_descriptors();
4101 int descriptor = lookup.GetDescriptorIndex();
4102 representation = desc->GetDetails(descriptor).representation();
4103 }
4104 if (FLAG_track_double_fields && representation.IsDouble()) {
4105 HeapNumber* storage =
4106 HeapNumber::cast(self->RawFastPropertyAt(
4107 lookup.GetFieldIndex().field_index()));
4108 storage->set_value(value->Number());
4109 result = *value;
4110 break;
4111 }
4112 self->FastPropertyAtPut(lookup.GetFieldIndex().field_index(), *value);
4113 result = *value;
4114 break; 4096 break;
4115 }
4116 case CONSTANT: 4097 case CONSTANT:
4117 // Only replace the function if necessary. 4098 // Only replace the constant if necessary.
4118 if (*value != lookup.GetConstant()) { 4099 if (*value == lookup.GetConstant()) return *value;
4119 // Preserve the attributes of this existing property. 4100 if (value->IsUninitialized()) break;
4120 attributes = lookup.GetAttributes(); 4101 result = SetPropertyToField(&lookup, name, value);
4121 result = self->ConvertDescriptorToField(*name, *value, attributes);
4122 }
4123 break; 4102 break;
4124 case CALLBACKS: 4103 case CALLBACKS:
4125 case INTERCEPTOR: 4104 case INTERCEPTOR:
4126 // Override callback in clone 4105 // Override callback in clone
4127 result = self->ConvertDescriptorToField(*name, *value, attributes); 4106 result = self->ConvertDescriptorToField(*name, *value, attributes);
4128 break; 4107 break;
4129 case TRANSITION: { 4108 case TRANSITION:
4130 Map* transition_map = lookup.GetTransitionTarget(); 4109 result = SetPropertyUsingTransition(&lookup, name, value, attributes);
4131 int descriptor = transition_map->LastAdded();
4132
4133 DescriptorArray* descriptors = transition_map->instance_descriptors();
4134 PropertyDetails details = descriptors->GetDetails(descriptor);
4135
4136 if (details.type() == FIELD) {
4137 if (attributes == details.attributes()) {
4138 Representation representation = details.representation();
4139 Representation value_representation =
4140 value->OptimalRepresentation(value_type);
4141 if (!value_representation.fits_into(representation)) {
4142 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation(
4143 descriptor, value_representation);
4144 if (!maybe_map->To(&transition_map)) return maybe_map;
4145 Object* back = transition_map->GetBackPointer();
4146 if (back->IsMap()) {
4147 MaybeObject* maybe_failure = self->MigrateToMap(Map::cast(back));
4148 if (maybe_failure->IsFailure()) return maybe_failure;
4149 }
4150 DescriptorArray* desc = transition_map->instance_descriptors();
4151 int descriptor = transition_map->LastAdded();
4152 representation = desc->GetDetails(descriptor).representation();
4153 }
4154 int field_index = descriptors->GetFieldIndex(descriptor);
4155 result = self->AddFastPropertyUsingMap(
4156 transition_map, *name, *value, field_index, representation);
4157 } else {
4158 result = self->ConvertDescriptorToField(*name, *value, attributes);
4159 }
4160 } else if (details.type() == CALLBACKS) {
4161 result = self->ConvertDescriptorToField(*name, *value, attributes);
4162 } else {
4163 ASSERT(details.type() == CONSTANT);
4164
4165 // Replace transition to CONSTANT FUNCTION with a map transition to a
4166 // new map with a FIELD, even if the value is a function.
4167 result = self->ConvertTransitionToMapTransition(
4168 lookup.GetTransitionIndex(), *name, *value, attributes);
4169 }
4170 break; 4110 break;
4171 }
4172 case HANDLER: 4111 case HANDLER:
4173 case NONEXISTENT: 4112 case NONEXISTENT:
4174 UNREACHABLE(); 4113 UNREACHABLE();
4175 } 4114 }
4176 4115
4177 Handle<Object> hresult; 4116 Handle<Object> hresult;
4178 if (!result->ToHandle(&hresult, isolate)) return result; 4117 if (!result->ToHandle(&hresult, isolate)) return result;
4179 4118
4180 if (is_observed) { 4119 if (is_observed) {
4181 if (lookup.IsTransition()) { 4120 if (lookup.IsTransition()) {
(...skipping 2486 matching lines...) Expand 10 before | Expand all | Expand 10 after
6668 if (!maybe_result->To(&result)) return maybe_result; 6607 if (!maybe_result->To(&result)) return maybe_result;
6669 6608
6670 result->InitializeDescriptors(descriptors); 6609 result->InitializeDescriptors(descriptors);
6671 6610
6672 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) { 6611 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) {
6673 TransitionArray* transitions; 6612 TransitionArray* transitions;
6674 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag); 6613 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag);
6675 if (!maybe_transitions->To(&transitions)) return maybe_transitions; 6614 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
6676 set_transitions(transitions); 6615 set_transitions(transitions);
6677 result->SetBackPointer(this); 6616 result->SetBackPointer(this);
6678 } else if (flag != OMIT_TRANSITION_KEEP_REPRESENTATIONS) { 6617 } else {
6679 descriptors->InitializeRepresentations(Representation::Tagged()); 6618 descriptors->InitializeRepresentations(Representation::Tagged());
6680 } 6619 }
6681 6620
6682 return result; 6621 return result;
6683 } 6622 }
6684 6623
6685 6624
6686 // Since this method is used to rewrite an existing transition tree, it can 6625 // Since this method is used to rewrite an existing transition tree, it can
6687 // always insert transitions without checking. 6626 // always insert transitions without checking.
6688 MaybeObject* Map::CopyInstallDescriptors(int new_descriptor, 6627 MaybeObject* Map::CopyInstallDescriptors(int new_descriptor,
(...skipping 1107 matching lines...) Expand 10 before | Expand all | Expand 10 after
7796 // The method merges two descriptor array in three parts. Both descriptor arrays 7735 // The method merges two descriptor array in three parts. Both descriptor arrays
7797 // are identical up to |verbatim|. They also overlap in keys up to |valid|. 7736 // are identical up to |verbatim|. They also overlap in keys up to |valid|.
7798 // Between |verbatim| and |valid|, the resulting descriptor type as well as the 7737 // Between |verbatim| and |valid|, the resulting descriptor type as well as the
7799 // representation are generalized from both |this| and |other|. Beyond |valid|, 7738 // representation are generalized from both |this| and |other|. Beyond |valid|,
7800 // the descriptors are copied verbatim from |other| up to |new_size|. 7739 // the descriptors are copied verbatim from |other| up to |new_size|.
7801 // In case of incompatible types, the type and representation of |other| is 7740 // In case of incompatible types, the type and representation of |other| is
7802 // used. 7741 // used.
7803 MaybeObject* DescriptorArray::Merge(int verbatim, 7742 MaybeObject* DescriptorArray::Merge(int verbatim,
7804 int valid, 7743 int valid,
7805 int new_size, 7744 int new_size,
7745 int modify_index,
7746 StoreMode store_mode,
7806 DescriptorArray* other) { 7747 DescriptorArray* other) {
7807 ASSERT(verbatim <= valid); 7748 ASSERT(verbatim <= valid);
7808 ASSERT(valid <= new_size); 7749 ASSERT(valid <= new_size);
7809 7750
7810 DescriptorArray* result; 7751 DescriptorArray* result;
7811 // Allocate a new descriptor array large enough to hold the required 7752 // Allocate a new descriptor array large enough to hold the required
7812 // descriptors, with minimally the exact same size as this descriptor array. 7753 // descriptors, with minimally the exact same size as this descriptor array.
7813 MaybeObject* maybe_descriptors = DescriptorArray::Allocate( 7754 MaybeObject* maybe_descriptors = DescriptorArray::Allocate(
7814 new_size, Max(new_size, other->number_of_descriptors()) - new_size); 7755 new_size, Max(new_size, other->number_of_descriptors()) - new_size);
7815 if (!maybe_descriptors->To(&result)) return maybe_descriptors; 7756 if (!maybe_descriptors->To(&result)) return maybe_descriptors;
(...skipping 13 matching lines...) Expand all
7829 result->CopyFrom(descriptor, this, descriptor, witness); 7770 result->CopyFrom(descriptor, this, descriptor, witness);
7830 } 7771 }
7831 7772
7832 // |verbatim| -> |valid| 7773 // |verbatim| -> |valid|
7833 for (; descriptor < valid; descriptor++) { 7774 for (; descriptor < valid; descriptor++) {
7834 Name* key = GetKey(descriptor); 7775 Name* key = GetKey(descriptor);
7835 PropertyDetails details = GetDetails(descriptor); 7776 PropertyDetails details = GetDetails(descriptor);
7836 PropertyDetails other_details = other->GetDetails(descriptor); 7777 PropertyDetails other_details = other->GetDetails(descriptor);
7837 7778
7838 if (details.type() == FIELD || other_details.type() == FIELD || 7779 if (details.type() == FIELD || other_details.type() == FIELD ||
7780 (store_mode == FORCE_FIELD && descriptor == modify_index) ||
7839 (details.type() == CONSTANT && 7781 (details.type() == CONSTANT &&
7840 other_details.type() == CONSTANT && 7782 other_details.type() == CONSTANT &&
7841 GetValue(descriptor) != other->GetValue(descriptor))) { 7783 GetValue(descriptor) != other->GetValue(descriptor))) {
7842 Representation representation = 7784 Representation representation =
7843 details.representation().generalize(other_details.representation()); 7785 details.representation().generalize(other_details.representation());
7844 FieldDescriptor d(key, 7786 FieldDescriptor d(key,
7845 current_offset++, 7787 current_offset++,
7846 other_details.attributes(), 7788 other_details.attributes(),
7847 representation); 7789 representation);
7848 result->Set(descriptor, &d, witness); 7790 result->Set(descriptor, &d, witness);
7849 } else { 7791 } else {
7850 result->CopyFrom(descriptor, other, descriptor, witness); 7792 result->CopyFrom(descriptor, other, descriptor, witness);
7851 } 7793 }
7852 } 7794 }
7853 7795
7854 // |valid| -> |new_size| 7796 // |valid| -> |new_size|
7855 for (; descriptor < new_size; descriptor++) { 7797 for (; descriptor < new_size; descriptor++) {
7856 PropertyDetails details = other->GetDetails(descriptor); 7798 PropertyDetails details = other->GetDetails(descriptor);
7857 if (details.type() == FIELD) { 7799 if (details.type() == FIELD ||
7800 (store_mode == FORCE_FIELD && descriptor == modify_index)) {
7858 Name* key = other->GetKey(descriptor); 7801 Name* key = other->GetKey(descriptor);
7859 FieldDescriptor d(key, 7802 FieldDescriptor d(key,
7860 current_offset++, 7803 current_offset++,
7861 details.attributes(), 7804 details.attributes(),
7862 details.representation()); 7805 details.representation());
7863 result->Set(descriptor, &d, witness); 7806 result->Set(descriptor, &d, witness);
7864 } else { 7807 } else {
7865 result->CopyFrom(descriptor, other, descriptor, witness); 7808 result->CopyFrom(descriptor, other, descriptor, witness);
7866 } 7809 }
7867 } 7810 }
(...skipping 8139 matching lines...) Expand 10 before | Expand all | Expand 10 after
16007 #define ERROR_MESSAGES_TEXTS(C, T) T, 15950 #define ERROR_MESSAGES_TEXTS(C, T) T,
16008 static const char* error_messages_[] = { 15951 static const char* error_messages_[] = {
16009 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 15952 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16010 }; 15953 };
16011 #undef ERROR_MESSAGES_TEXTS 15954 #undef ERROR_MESSAGES_TEXTS
16012 return error_messages_[reason]; 15955 return error_messages_[reason];
16013 } 15956 }
16014 15957
16015 15958
16016 } } // namespace v8::internal 15959 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698