OLD | NEW |
---|---|
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 1941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1952 Representation representation) { | 1952 Representation representation) { |
1953 Heap* heap = isolate->heap(); | 1953 Heap* heap = isolate->heap(); |
1954 CALL_HEAP_FUNCTION(isolate, | 1954 CALL_HEAP_FUNCTION(isolate, |
1955 object->AllocateNewStorageFor(heap, representation), | 1955 object->AllocateNewStorageFor(heap, representation), |
1956 Object); | 1956 Object); |
1957 } | 1957 } |
1958 | 1958 |
1959 | 1959 |
1960 static MaybeObject* CopyAddFieldDescriptor(Map* map, | 1960 static MaybeObject* CopyAddFieldDescriptor(Map* map, |
1961 Name* name, | 1961 Name* name, |
1962 int index, | 1962 int field_index, |
1963 HeapType* field_type, | |
1963 PropertyAttributes attributes, | 1964 PropertyAttributes attributes, |
1964 Representation representation, | 1965 Representation representation, |
1965 TransitionFlag flag) { | 1966 TransitionFlag flag) { |
1966 Map* new_map; | 1967 Map* new_map; |
1967 FieldDescriptor new_field_desc(name, index, attributes, representation); | 1968 FieldDescriptor new_field_desc(name, field_index, field_type, |
1969 attributes, representation); | |
1968 MaybeObject* maybe_map = map->CopyAddDescriptor(&new_field_desc, flag); | 1970 MaybeObject* maybe_map = map->CopyAddDescriptor(&new_field_desc, flag); |
1969 if (!maybe_map->To(&new_map)) return maybe_map; | 1971 if (!maybe_map->To(&new_map)) return maybe_map; |
1970 int unused_property_fields = map->unused_property_fields() - 1; | 1972 int unused_property_fields = map->unused_property_fields() - 1; |
1971 if (unused_property_fields < 0) { | 1973 if (unused_property_fields < 0) { |
1972 unused_property_fields += JSObject::kFieldsAdded; | 1974 unused_property_fields += JSObject::kFieldsAdded; |
1973 } | 1975 } |
1974 new_map->set_unused_property_fields(unused_property_fields); | 1976 new_map->set_unused_property_fields(unused_property_fields); |
1975 return new_map; | 1977 return new_map; |
1976 } | 1978 } |
1977 | 1979 |
1978 | 1980 |
1979 static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map, | 1981 static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map, |
1980 Handle<Name> name, | 1982 Handle<Name> name, |
1981 int index, | 1983 int field_index, |
1984 Handle<HeapType> field_type, | |
1982 PropertyAttributes attributes, | 1985 PropertyAttributes attributes, |
1983 Representation representation, | 1986 Representation representation, |
1984 TransitionFlag flag) { | 1987 TransitionFlag flag) { |
1985 CALL_HEAP_FUNCTION(map->GetIsolate(), | 1988 CALL_HEAP_FUNCTION(map->GetIsolate(), |
1986 CopyAddFieldDescriptor( | 1989 CopyAddFieldDescriptor( |
1987 *map, *name, index, attributes, representation, flag), | 1990 *map, *name, field_index, *field_type, |
1991 attributes, representation, flag), | |
1988 Map); | 1992 Map); |
1989 } | 1993 } |
1990 | 1994 |
1991 | 1995 |
1992 void JSObject::AddFastProperty(Handle<JSObject> object, | 1996 void JSObject::AddFastProperty(Handle<JSObject> object, |
1993 Handle<Name> name, | 1997 Handle<Name> name, |
1994 Handle<Object> value, | 1998 Handle<Object> value, |
1995 PropertyAttributes attributes, | 1999 PropertyAttributes attributes, |
1996 StoreFromKeyed store_mode, | 2000 StoreFromKeyed store_mode, |
1997 ValueType value_type, | 2001 ValueType value_type, |
1998 TransitionFlag flag) { | 2002 TransitionFlag flag) { |
1999 ASSERT(!object->IsJSGlobalProxy()); | 2003 ASSERT(!object->IsJSGlobalProxy()); |
2000 ASSERT(DescriptorArray::kNotFound == | 2004 ASSERT(DescriptorArray::kNotFound == |
2001 object->map()->instance_descriptors()->Search( | 2005 object->map()->instance_descriptors()->Search( |
2002 *name, object->map()->NumberOfOwnDescriptors())); | 2006 *name, object->map()->NumberOfOwnDescriptors())); |
2003 | 2007 |
2004 // Normalize the object if the name is an actual name (not the | 2008 // Normalize the object if the name is an actual name (not the |
2005 // hidden strings) and is not a real identifier. | 2009 // hidden strings) and is not a real identifier. |
2006 // Normalize the object if it will have too many fast properties. | 2010 // Normalize the object if it will have too many fast properties. |
2007 Isolate* isolate = object->GetIsolate(); | 2011 Isolate* isolate = object->GetIsolate(); |
2008 if (!name->IsCacheable(isolate) || | 2012 if (!name->IsCacheable(isolate) || |
2009 object->TooManyFastProperties(store_mode)) { | 2013 object->TooManyFastProperties(store_mode)) { |
2010 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 2014 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
2011 AddSlowProperty(object, name, value, attributes); | 2015 AddSlowProperty(object, name, value, attributes); |
2012 return; | 2016 return; |
2013 } | 2017 } |
2014 | 2018 |
2015 // Compute the new index for new field. | 2019 // Compute the new index for new field. |
2016 int index = object->map()->NextFreePropertyIndex(); | 2020 int field_index = object->map()->NextFreePropertyIndex(); |
2021 | |
2022 // Compute the optimal representation for the new field. | |
2023 if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED; | |
2024 Representation representation = value->OptimalRepresentation(value_type); | |
2025 | |
2026 // Compute the type of the new field. | |
2027 Handle<HeapType> field_type = FLAG_track_field_types | |
2028 ? HeapType::OfCurrently(value, isolate) | |
Toon Verwaest
2014/03/21 14:33:37
If it's FORCE_TAGGED we also shouldn't be tracking
Benedikt Meurer
2014/04/11 11:12:00
Done.
| |
2029 : HeapType::Any(isolate); | |
2030 if (FLAG_trace_track_field_types) { | |
2031 #ifdef OBJECT_PRINT | |
2032 PrintF("[Adding fast property "); | |
2033 name->Print(); | |
2034 PrintF(" to object "); | |
2035 object->ShortPrint(); | |
2036 PrintF(" with value "); | |
2037 value->ShortPrint(); | |
2038 PrintF(" and field type "); | |
2039 field_type->TypePrint(stdout); | |
2040 PrintF("]\n"); | |
2041 #endif | |
2042 } | |
2017 | 2043 |
2018 // Allocate new instance descriptors with (name, index) added | 2044 // Allocate new instance descriptors with (name, index) added |
2019 if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED; | |
2020 Representation representation = value->OptimalRepresentation(value_type); | |
2021 Handle<Map> new_map = CopyAddFieldDescriptor( | 2045 Handle<Map> new_map = CopyAddFieldDescriptor( |
2022 handle(object->map()), name, index, attributes, representation, flag); | 2046 handle(object->map()), name, field_index, |
2047 field_type, attributes, representation, flag); | |
2023 | 2048 |
2024 JSObject::MigrateToMap(object, new_map); | 2049 JSObject::MigrateToMap(object, new_map); |
2025 | 2050 |
2026 if (representation.IsDouble()) { | 2051 if (representation.IsDouble()) { |
2027 // Nothing more to be done. | 2052 // Nothing more to be done. |
2028 if (value->IsUninitialized()) return; | 2053 if (value->IsUninitialized()) return; |
2029 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index)); | 2054 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index)); |
2030 box->set_value(value->Number()); | 2055 box->set_value(value->Number()); |
2031 } else { | 2056 } else { |
2032 object->FastPropertyAtPut(index, *value); | 2057 object->FastPropertyAtPut(field_index, *value); |
2033 } | 2058 } |
2034 } | 2059 } |
2035 | 2060 |
2036 | 2061 |
2037 static MaybeObject* CopyAddConstantDescriptor(Map* map, | 2062 static MaybeObject* CopyAddConstantDescriptor(Map* map, |
2038 Name* name, | 2063 Name* name, |
2039 Object* value, | 2064 Object* value, |
2040 PropertyAttributes attributes, | 2065 PropertyAttributes attributes, |
2041 TransitionFlag flag) { | 2066 TransitionFlag flag) { |
2042 ConstantDescriptor new_constant_desc(name, value, attributes); | 2067 ConstantDescriptor new_constant_desc(name, value, attributes); |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2453 SimpleTransitionFlag flag) { | 2478 SimpleTransitionFlag flag) { |
2454 CALL_HEAP_FUNCTION(map->GetIsolate(), | 2479 CALL_HEAP_FUNCTION(map->GetIsolate(), |
2455 map->AddTransition(*key, *target, flag), | 2480 map->AddTransition(*key, *target, flag), |
2456 TransitionArray); | 2481 TransitionArray); |
2457 } | 2482 } |
2458 | 2483 |
2459 | 2484 |
2460 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, | 2485 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, |
2461 int modify_index, | 2486 int modify_index, |
2462 Representation new_representation, | 2487 Representation new_representation, |
2488 Handle<HeapType> new_field_type, | |
2463 StoreMode store_mode) { | 2489 StoreMode store_mode) { |
2464 Handle<Map> new_map = Map::GeneralizeRepresentation( | 2490 Handle<Map> new_map = Map::GeneralizeRepresentation( |
2465 handle(object->map()), modify_index, new_representation, store_mode); | 2491 handle(object->map()), modify_index, new_representation, |
2492 new_field_type, store_mode); | |
2466 if (object->map() == *new_map) return; | 2493 if (object->map() == *new_map) return; |
2467 return MigrateToMap(object, new_map); | 2494 return MigrateToMap(object, new_map); |
2468 } | 2495 } |
2469 | 2496 |
2470 | 2497 |
2471 int Map::NumberOfFields() { | 2498 int Map::NumberOfFields() { |
2472 DescriptorArray* descriptors = instance_descriptors(); | 2499 DescriptorArray* descriptors = instance_descriptors(); |
2473 int result = 0; | 2500 int result = 0; |
2474 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { | 2501 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { |
2475 if (descriptors->GetDetails(i).type() == FIELD) result++; | 2502 if (descriptors->GetDetails(i).type() == FIELD) result++; |
2476 } | 2503 } |
2477 return result; | 2504 return result; |
2478 } | 2505 } |
2479 | 2506 |
2480 | 2507 |
2481 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, | 2508 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, |
2482 int modify_index, | 2509 int modify_index, |
2483 StoreMode store_mode, | 2510 StoreMode store_mode, |
2484 PropertyAttributes attributes, | 2511 PropertyAttributes attributes, |
2485 const char* reason) { | 2512 const char* reason) { |
2486 Handle<Map> new_map = Copy(map); | 2513 Handle<Map> new_map = Copy(map); |
2487 | 2514 |
2488 DescriptorArray* descriptors = new_map->instance_descriptors(); | 2515 DescriptorArray* descriptors = new_map->instance_descriptors(); |
2489 descriptors->InitializeRepresentations(Representation::Tagged()); | 2516 int length = descriptors->number_of_descriptors(); |
2517 for (int i = 0; i < length; i++) { | |
2518 descriptors->SetRepresentation(i, Representation::Tagged()); | |
2519 if (descriptors->GetDetails(i).type() == FIELD) { | |
2520 descriptors->SetValue(i, HeapType::Any()); | |
2521 } | |
2522 } | |
2490 | 2523 |
2491 // Unless the instance is being migrated, ensure that modify_index is a field. | 2524 // Unless the instance is being migrated, ensure that modify_index is a field. |
2492 PropertyDetails details = descriptors->GetDetails(modify_index); | 2525 PropertyDetails details = descriptors->GetDetails(modify_index); |
2493 if (store_mode == FORCE_FIELD && details.type() != FIELD) { | 2526 if (store_mode == FORCE_FIELD && details.type() != FIELD) { |
2494 FieldDescriptor d(descriptors->GetKey(modify_index), | 2527 FieldDescriptor d(descriptors->GetKey(modify_index), |
2495 new_map->NumberOfFields(), | 2528 new_map->NumberOfFields(), |
2529 HeapType::Any(), | |
2496 attributes, | 2530 attributes, |
2497 Representation::Tagged()); | 2531 Representation::Tagged()); |
2498 d.SetSortedKeyIndex(details.pointer()); | 2532 d.SetSortedKeyIndex(details.pointer()); |
2499 descriptors->Set(modify_index, &d); | 2533 descriptors->Set(modify_index, &d); |
2500 int unused_property_fields = new_map->unused_property_fields() - 1; | 2534 int unused_property_fields = new_map->unused_property_fields() - 1; |
2501 if (unused_property_fields < 0) { | 2535 if (unused_property_fields < 0) { |
2502 unused_property_fields += JSObject::kFieldsAdded; | 2536 unused_property_fields += JSObject::kFieldsAdded; |
2503 } | 2537 } |
2504 new_map->set_unused_property_fields(unused_property_fields); | 2538 new_map->set_unused_property_fields(unused_property_fields); |
2505 } | 2539 } |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2616 for (int i = verbatim; i < length; i++) { | 2650 for (int i = verbatim; i < length; i++) { |
2617 if (!current->HasTransitionArray()) break; | 2651 if (!current->HasTransitionArray()) break; |
2618 Name* name = descriptors->GetKey(i); | 2652 Name* name = descriptors->GetKey(i); |
2619 TransitionArray* transitions = current->transitions(); | 2653 TransitionArray* transitions = current->transitions(); |
2620 int transition = transitions->Search(name); | 2654 int transition = transitions->Search(name); |
2621 if (transition == TransitionArray::kNotFound) break; | 2655 if (transition == TransitionArray::kNotFound) break; |
2622 | 2656 |
2623 Map* next = transitions->GetTarget(transition); | 2657 Map* next = transitions->GetTarget(transition); |
2624 DescriptorArray* next_descriptors = next->instance_descriptors(); | 2658 DescriptorArray* next_descriptors = next->instance_descriptors(); |
2625 | 2659 |
2626 if (next_descriptors->GetValue(i) != descriptors->GetValue(i)) break; | |
2627 | |
2628 PropertyDetails details = descriptors->GetDetails(i); | 2660 PropertyDetails details = descriptors->GetDetails(i); |
2629 PropertyDetails next_details = next_descriptors->GetDetails(i); | 2661 PropertyDetails next_details = next_descriptors->GetDetails(i); |
2630 if (details.type() != next_details.type()) break; | 2662 if (details.type() != next_details.type()) break; |
2631 if (details.attributes() != next_details.attributes()) break; | 2663 if (details.attributes() != next_details.attributes()) break; |
2632 if (!details.representation().Equals(next_details.representation())) break; | 2664 if (!details.representation().Equals(next_details.representation())) break; |
2633 | 2665 |
2666 // TODO(bmeurer): Check descriptors is subtype of next_descriptors. | |
2667 if (next_details.type() != FIELD && | |
2668 next_descriptors->GetValue(i) != descriptors->GetValue(i)) break; | |
2669 | |
2634 current = next; | 2670 current = next; |
2635 } | 2671 } |
2636 return current; | 2672 return current; |
2637 } | 2673 } |
2638 | 2674 |
2639 | 2675 |
2676 Map* Map::FindFieldOwner(int descriptor) { | |
2677 ASSERT(instance_descriptors()->GetDetails(descriptor).type() == FIELD); | |
2678 Map* result = this; | |
2679 while (true) { | |
2680 Object* back = result->GetBackPointer(); | |
2681 if (back->IsUndefined()) break; | |
2682 Map* parent = Map::cast(back); | |
2683 if (parent->NumberOfOwnDescriptors() <= descriptor) break; | |
2684 result = parent; | |
2685 } | |
2686 return result; | |
2687 } | |
2688 | |
2689 | |
2690 void Map::UpdateDescriptor(int descriptor_number, Descriptor* desc) { | |
2691 if (HasTransitionArray()) { | |
2692 TransitionArray* transitions = this->transitions(); | |
2693 for (int i = 0; i < transitions->number_of_transitions(); ++i) { | |
2694 transitions->GetTarget(i)->UpdateDescriptor(descriptor_number, desc); | |
2695 } | |
2696 } | |
2697 DescriptorArray* descriptors = instance_descriptors(); | |
2698 desc->SetSortedKeyIndex(descriptors->GetDetails(descriptor_number).pointer()); | |
2699 descriptors->Set(descriptor_number, desc); | |
2700 } | |
2701 | |
2702 | |
2703 void Map::UpdateFieldType(int descriptor, HeapType* field_type) { | |
2704 ASSERT(this == FindFieldOwner(descriptor)); | |
2705 DescriptorArray* descriptors = instance_descriptors(); | |
2706 PropertyDetails details = descriptors->GetDetails(descriptor); | |
2707 FieldDescriptor d(descriptors->GetKey(descriptor), | |
2708 descriptors->GetFieldIndex(descriptor), | |
2709 field_type, | |
2710 details.attributes(), | |
2711 details.representation()); | |
2712 UpdateDescriptor(descriptor, &d); | |
2713 dependent_code()->DeoptimizeDependentCodeGroup( | |
2714 GetIsolate(), DependentCode::kFieldTypeGroup); | |
2715 } | |
2716 | |
2717 | |
2640 // Generalize the representation of the descriptor at |modify_index|. | 2718 // Generalize the representation of the descriptor at |modify_index|. |
2641 // This method rewrites the transition tree to reflect the new change. To avoid | 2719 // This method rewrites the transition tree to reflect the new change. To avoid |
2642 // high degrees over polymorphism, and to stabilize quickly, on every rewrite | 2720 // high degrees over polymorphism, and to stabilize quickly, on every rewrite |
2643 // the new type is deduced by merging the current type with any potential new | 2721 // the new type is deduced by merging the current type with any potential new |
2644 // (partial) version of the type in the transition tree. | 2722 // (partial) version of the type in the transition tree. |
2645 // To do this, on each rewrite: | 2723 // To do this, on each rewrite: |
2646 // - Search the root of the transition tree using FindRootMap. | 2724 // - Search the root of the transition tree using FindRootMap. |
2647 // - Find |updated|, the newest matching version of this map using | 2725 // - Find |updated|, the newest matching version of this map using |
2648 // FindUpdatedMap. This uses the keys in the own map's descriptor array to | 2726 // FindUpdatedMap. This uses the keys in the own map's descriptor array to |
2649 // walk the transition tree. | 2727 // walk the transition tree. |
2650 // - Merge/generalize the descriptor array of the current map and |updated|. | 2728 // - Merge/generalize the descriptor array of the current map and |updated|. |
2651 // - Generalize the |modify_index| descriptor using |new_representation|. | 2729 // - Generalize the |modify_index| descriptor using |new_representation|. |
2652 // - Walk the tree again starting from the root towards |updated|. Stop at | 2730 // - Walk the tree again starting from the root towards |updated|. Stop at |
2653 // |split_map|, the first map who's descriptor array does not match the merged | 2731 // |split_map|, the first map who's descriptor array does not match the merged |
2654 // descriptor array. | 2732 // descriptor array. |
2655 // - If |updated| == |split_map|, |updated| is in the expected state. Return it. | 2733 // - If |updated| == |split_map|, |updated| is in the expected state. Return it. |
2656 // - Otherwise, invalidate the outdated transition target from |updated|, and | 2734 // - Otherwise, invalidate the outdated transition target from |updated|, and |
2657 // replace its transition tree with a new branch for the updated descriptors. | 2735 // replace its transition tree with a new branch for the updated descriptors. |
2658 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, | 2736 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, |
2659 int modify_index, | 2737 int modify_index, |
2660 Representation new_representation, | 2738 Representation new_representation, |
2739 Handle<HeapType> new_field_type, | |
2661 StoreMode store_mode) { | 2740 StoreMode store_mode) { |
2662 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); | 2741 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); |
2663 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2742 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
2664 Representation old_representation = old_details.representation(); | 2743 Representation old_representation = old_details.representation(); |
2665 | 2744 |
2666 // It's fine to transition from None to anything but double without any | 2745 // It's fine to transition from None to anything but double without any |
2667 // modification to the object, because the default uninitialized value for | 2746 // modification to the object, because the default uninitialized value for |
2668 // representation None can be overwritten by both smi and tagged values. | 2747 // representation None can be overwritten by both smi and tagged values. |
2669 // Doubles, however, would require a box allocation. | 2748 // Doubles, however, would require a box allocation. |
2670 if (old_representation.IsNone() && | 2749 if (old_representation.IsNone() && |
2671 !new_representation.IsNone() && | 2750 !new_representation.IsNone() && |
2672 !new_representation.IsDouble()) { | 2751 !new_representation.IsDouble()) { |
2673 old_descriptors->SetRepresentation(modify_index, new_representation); | 2752 old_descriptors->SetRepresentation(modify_index, new_representation); |
2753 if (old_details.type() == FIELD) { | |
Toon Verwaest
2014/03/21 14:33:37
Only if new_representation is heap_object right?
| |
2754 old_descriptors->SetValue(modify_index, *new_field_type); | |
2755 } | |
2674 return old_map; | 2756 return old_map; |
2675 } | 2757 } |
2676 | 2758 |
2677 int descriptors = old_map->NumberOfOwnDescriptors(); | 2759 int descriptors = old_map->NumberOfOwnDescriptors(); |
2678 Handle<Map> root_map(old_map->FindRootMap()); | 2760 Handle<Map> root_map(old_map->FindRootMap()); |
2679 | 2761 |
2680 // Check the state of the root map. | 2762 // Check the state of the root map. |
2681 if (!old_map->EquivalentToForTransition(*root_map)) { | 2763 if (!old_map->EquivalentToForTransition(*root_map)) { |
2682 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2764 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2683 old_details.attributes(), "not equivalent"); | 2765 old_details.attributes(), "not equivalent"); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2719 ASSERT(store_mode == ALLOW_AS_CONSTANT || | 2801 ASSERT(store_mode == ALLOW_AS_CONSTANT || |
2720 new_descriptors->GetDetails(modify_index).type() == FIELD); | 2802 new_descriptors->GetDetails(modify_index).type() == FIELD); |
2721 | 2803 |
2722 old_representation = | 2804 old_representation = |
2723 new_descriptors->GetDetails(modify_index).representation(); | 2805 new_descriptors->GetDetails(modify_index).representation(); |
2724 Representation updated_representation = | 2806 Representation updated_representation = |
2725 new_representation.generalize(old_representation); | 2807 new_representation.generalize(old_representation); |
2726 if (!updated_representation.Equals(old_representation)) { | 2808 if (!updated_representation.Equals(old_representation)) { |
2727 new_descriptors->SetRepresentation(modify_index, updated_representation); | 2809 new_descriptors->SetRepresentation(modify_index, updated_representation); |
2728 } | 2810 } |
2811 if (new_descriptors->GetDetails(modify_index).type() == FIELD) { | |
2812 Handle<HeapType> field_type(new_descriptors->GetFieldType(modify_index), | |
2813 new_descriptors->GetIsolate()); | |
2814 if (!new_field_type->IsCurrently(field_type)) { | |
2815 if (!field_type->IsCurrently(new_field_type)) { | |
2816 new_field_type = HeapType::Any(updated->GetIsolate()); | |
2817 } | |
2818 new_descriptors->SetValue(modify_index, *new_field_type); | |
Toon Verwaest
2014/03/21 14:33:37
Only if new_representation.IsHeapObject()
Benedikt Meurer
2014/04/11 11:12:00
No, we track types independent of the representati
| |
2819 } | |
2820 } | |
2729 | 2821 |
2730 Handle<Map> split_map(root_map->FindLastMatchMap( | 2822 Handle<Map> split_map(root_map->FindLastMatchMap( |
2731 verbatim, descriptors, *new_descriptors)); | 2823 verbatim, descriptors, *new_descriptors)); |
2732 | 2824 |
2733 int split_descriptors = split_map->NumberOfOwnDescriptors(); | 2825 int split_descriptors = split_map->NumberOfOwnDescriptors(); |
2734 // This is shadowed by |updated_descriptors| being more general than | 2826 // This is shadowed by |updated_descriptors| being more general than |
2735 // |old_descriptors|. | 2827 // |old_descriptors|. |
2736 ASSERT(descriptors != split_descriptors); | 2828 ASSERT(descriptors != split_descriptors); |
2737 | 2829 |
2738 int descriptor = split_descriptors; | 2830 int descriptor = split_descriptors; |
(...skipping 14 matching lines...) Expand all Loading... | |
2753 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors); | 2845 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors); |
2754 } | 2846 } |
2755 | 2847 |
2756 new_map->set_owns_descriptors(true); | 2848 new_map->set_owns_descriptors(true); |
2757 return new_map; | 2849 return new_map; |
2758 } | 2850 } |
2759 | 2851 |
2760 | 2852 |
2761 // Generalize the representation of all FIELD descriptors. | 2853 // Generalize the representation of all FIELD descriptors. |
2762 Handle<Map> Map::GeneralizeAllFieldRepresentations( | 2854 Handle<Map> Map::GeneralizeAllFieldRepresentations( |
2763 Handle<Map> map, | 2855 Handle<Map> map) { |
2764 Representation new_representation) { | |
2765 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 2856 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
2766 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { | 2857 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { |
2767 PropertyDetails details = descriptors->GetDetails(i); | 2858 if (descriptors->GetDetails(i).type() == FIELD) { |
2768 if (details.type() == FIELD) { | 2859 map = GeneralizeRepresentation(map, i, Representation::Tagged(), |
2769 map = GeneralizeRepresentation(map, i, new_representation, FORCE_FIELD); | 2860 HeapType::Any(map->GetIsolate()), |
2861 FORCE_FIELD); | |
2770 } | 2862 } |
2771 } | 2863 } |
2772 return map; | 2864 return map; |
2773 } | 2865 } |
2774 | 2866 |
2775 | 2867 |
2776 Handle<Map> Map::CurrentMapForDeprecated(Handle<Map> map) { | 2868 Handle<Map> Map::CurrentMapForDeprecated(Handle<Map> map) { |
2777 Handle<Map> proto_map(map); | 2869 Handle<Map> proto_map(map); |
2778 while (proto_map->prototype()->IsJSObject()) { | 2870 while (proto_map->prototype()->IsJSObject()) { |
2779 Handle<JSObject> holder(JSObject::cast(proto_map->prototype())); | 2871 Handle<JSObject> holder(JSObject::cast(proto_map->prototype())); |
(...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3838 JSObject::MigrateToMap(object, map); | 3930 JSObject::MigrateToMap(object, map); |
3839 } | 3931 } |
3840 | 3932 |
3841 | 3933 |
3842 void JSObject::MigrateInstance(Handle<JSObject> object) { | 3934 void JSObject::MigrateInstance(Handle<JSObject> object) { |
3843 // Converting any field to the most specific type will cause the | 3935 // Converting any field to the most specific type will cause the |
3844 // GeneralizeFieldRepresentation algorithm to create the most general existing | 3936 // GeneralizeFieldRepresentation algorithm to create the most general existing |
3845 // transition that matches the object. This achieves what is needed. | 3937 // transition that matches the object. This achieves what is needed. |
3846 Handle<Map> original_map(object->map()); | 3938 Handle<Map> original_map(object->map()); |
3847 GeneralizeFieldRepresentation( | 3939 GeneralizeFieldRepresentation( |
3848 object, 0, Representation::None(), ALLOW_AS_CONSTANT); | 3940 object, 0, Representation::None(), |
3941 HeapType::None(object->GetIsolate()), | |
3942 ALLOW_AS_CONSTANT); | |
3849 object->map()->set_migration_target(true); | 3943 object->map()->set_migration_target(true); |
3850 if (FLAG_trace_migration) { | 3944 if (FLAG_trace_migration) { |
3851 object->PrintInstanceMigration(stdout, *original_map, object->map()); | 3945 object->PrintInstanceMigration(stdout, *original_map, object->map()); |
3852 } | 3946 } |
3853 } | 3947 } |
3854 | 3948 |
3855 | 3949 |
3856 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { | 3950 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { |
3857 Handle<Map> original_map(object->map()); | 3951 Handle<Map> original_map(object->map()); |
3858 Handle<Map> new_map = Map::CurrentMapForDeprecatedInternal(original_map); | 3952 Handle<Map> new_map = Map::CurrentMapForDeprecatedInternal(original_map); |
(...skipping 25 matching lines...) Expand all Loading... | |
3884 return JSObject::AddProperty( | 3978 return JSObject::AddProperty( |
3885 object, name, value, attributes, SLOPPY, | 3979 object, name, value, attributes, SLOPPY, |
3886 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, | 3980 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, |
3887 JSReceiver::OMIT_EXTENSIBILITY_CHECK, | 3981 JSReceiver::OMIT_EXTENSIBILITY_CHECK, |
3888 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); | 3982 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); |
3889 } | 3983 } |
3890 | 3984 |
3891 // Keep the target CONSTANT if the same value is stored. | 3985 // Keep the target CONSTANT if the same value is stored. |
3892 // TODO(verwaest): Also support keeping the placeholder | 3986 // TODO(verwaest): Also support keeping the placeholder |
3893 // (value->IsUninitialized) as constant. | 3987 // (value->IsUninitialized) as constant. |
3988 Handle<HeapType> value_type = FLAG_track_field_types | |
3989 ? HeapType::OfCurrently(value, lookup->isolate()) | |
3990 : HeapType::Any(lookup->isolate()); | |
3894 if (!value->FitsRepresentation(details.representation()) || | 3991 if (!value->FitsRepresentation(details.representation()) || |
3895 (details.type() == CONSTANT && | 3992 (details.type() == CONSTANT && |
3896 descriptors->GetValue(descriptor) != *value)) { | 3993 descriptors->GetValue(descriptor) != *value)) { |
3897 transition_map = Map::GeneralizeRepresentation(transition_map, | 3994 transition_map = Map::GeneralizeRepresentation( |
3898 descriptor, value->OptimalRepresentation(), FORCE_FIELD); | 3995 transition_map, descriptor, |
3996 value->OptimalRepresentation(), | |
3997 value_type, FORCE_FIELD); | |
3998 } else if (details.type() == FIELD && | |
3999 details.representation().IsHeapObject()) { | |
4000 Handle<HeapType> field_type(descriptors->GetFieldType(descriptor), | |
4001 lookup->isolate()); | |
4002 if (!value_type->IsCurrently(field_type)) { | |
4003 if (!field_type->IsCurrently(value_type)) { | |
4004 value_type = HeapType::Any(lookup->isolate()); | |
4005 } | |
4006 if (FLAG_trace_track_field_types) { | |
4007 #ifdef OBJECT_PRINT | |
4008 PrintF("[Updating type of field "); | |
4009 name->Print(); | |
4010 PrintF(" in transition map "); | |
4011 transition_map->ShortPrint(); | |
4012 PrintF(": "); | |
4013 field_type->TypePrint(stdout); | |
4014 PrintF(" -> "); | |
4015 value_type->TypePrint(stdout); | |
4016 PrintF("]\n"); | |
4017 #endif | |
4018 } | |
4019 transition_map->UpdateFieldType(descriptor, *value_type); | |
4020 } | |
3899 } | 4021 } |
3900 | 4022 |
3901 JSObject::MigrateToMap(object, transition_map); | 4023 JSObject::MigrateToMap(object, transition_map); |
3902 | 4024 |
3903 // Reload. | 4025 // Reload. |
3904 descriptors = transition_map->instance_descriptors(); | 4026 descriptors = transition_map->instance_descriptors(); |
3905 details = descriptors->GetDetails(descriptor); | 4027 details = descriptors->GetDetails(descriptor); |
3906 | 4028 |
3907 if (details.type() != FIELD) return value; | 4029 if (details.type() != FIELD) return value; |
3908 | 4030 |
3909 int field_index = descriptors->GetFieldIndex(descriptor); | 4031 int field_index = descriptors->GetFieldIndex(descriptor); |
3910 if (details.representation().IsDouble()) { | 4032 if (details.representation().IsDouble()) { |
3911 // Nothing more to be done. | 4033 // Nothing more to be done. |
3912 if (value->IsUninitialized()) return value; | 4034 if (value->IsUninitialized()) return value; |
3913 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index)); | 4035 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index)); |
3914 box->set_value(value->Number()); | 4036 box->set_value(value->Number()); |
3915 } else { | 4037 } else { |
3916 object->FastPropertyAtPut(field_index, *value); | 4038 object->FastPropertyAtPut(field_index, *value); |
3917 } | 4039 } |
3918 | 4040 |
3919 return value; | 4041 return value; |
3920 } | 4042 } |
3921 | 4043 |
3922 | 4044 |
3923 static void SetPropertyToField(LookupResult* lookup, | 4045 static void SetPropertyToField(LookupResult* lookup, |
3924 Handle<Name> name, | 4046 Handle<Name> name, |
3925 Handle<Object> value) { | 4047 Handle<Object> value) { |
3926 Representation representation = lookup->representation(); | 4048 Representation representation = lookup->representation(); |
4049 Handle<HeapType> value_type = FLAG_track_field_types | |
4050 ? HeapType::OfCurrently(value, lookup->isolate()) | |
4051 : HeapType::Any(lookup->isolate()); | |
3927 if (!value->FitsRepresentation(representation) || | 4052 if (!value->FitsRepresentation(representation) || |
3928 lookup->type() == CONSTANT) { | 4053 lookup->type() == CONSTANT) { |
3929 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), | 4054 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), |
3930 lookup->GetDescriptorIndex(), | 4055 lookup->GetDescriptorIndex(), |
3931 value->OptimalRepresentation(), | 4056 value->OptimalRepresentation(), |
3932 FORCE_FIELD); | 4057 value_type, FORCE_FIELD); |
3933 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); | 4058 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); |
3934 int descriptor = lookup->GetDescriptorIndex(); | 4059 int descriptor = lookup->GetDescriptorIndex(); |
3935 representation = desc->GetDetails(descriptor).representation(); | 4060 representation = desc->GetDetails(descriptor).representation(); |
4061 } else if (representation.IsHeapObject()) { | |
4062 Handle<HeapType> field_type(lookup->GetFieldType(), lookup->isolate()); | |
4063 if (!value_type->IsCurrently(field_type)) { | |
4064 if (!field_type->IsCurrently(value_type)) { | |
4065 value_type = HeapType::Any(lookup->isolate()); | |
4066 } | |
4067 if (FLAG_trace_track_field_types) { | |
4068 #ifdef OBJECT_PRINT | |
4069 PrintF("[Updating type of field "); | |
4070 name->Print(); | |
4071 PrintF(" in map "); | |
4072 lookup->GetFieldOwner()->ShortPrint(); | |
4073 PrintF(": "); | |
4074 field_type->TypePrint(stdout); | |
4075 PrintF(" -> "); | |
4076 value_type->TypePrint(stdout); | |
4077 PrintF("]\n"); | |
4078 #endif | |
4079 } | |
4080 lookup->GetFieldOwner()->UpdateFieldType( | |
4081 lookup->GetDescriptorIndex(), *value_type); | |
4082 } | |
3936 } | 4083 } |
3937 | 4084 |
3938 if (representation.IsDouble()) { | 4085 if (representation.IsDouble()) { |
3939 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( | 4086 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( |
3940 lookup->GetFieldIndex().field_index())); | 4087 lookup->GetFieldIndex().field_index())); |
3941 storage->set_value(value->Number()); | 4088 storage->set_value(value->Number()); |
3942 return; | 4089 return; |
3943 } | 4090 } |
3944 | 4091 |
3945 lookup->holder()->FastPropertyAtPut( | 4092 lookup->holder()->FastPropertyAtPut( |
(...skipping 11 matching lines...) Expand all Loading... | |
3957 } | 4104 } |
3958 | 4105 |
3959 if (!object->HasFastProperties()) { | 4106 if (!object->HasFastProperties()) { |
3960 ReplaceSlowProperty(object, name, value, attributes); | 4107 ReplaceSlowProperty(object, name, value, attributes); |
3961 return; | 4108 return; |
3962 } | 4109 } |
3963 | 4110 |
3964 int descriptor_index = lookup->GetDescriptorIndex(); | 4111 int descriptor_index = lookup->GetDescriptorIndex(); |
3965 if (lookup->GetAttributes() == attributes) { | 4112 if (lookup->GetAttributes() == attributes) { |
3966 JSObject::GeneralizeFieldRepresentation( | 4113 JSObject::GeneralizeFieldRepresentation( |
3967 object, descriptor_index, Representation::Tagged(), FORCE_FIELD); | 4114 object, descriptor_index, Representation::Tagged(), |
4115 HeapType::Any(lookup->isolate()), FORCE_FIELD); | |
3968 } else { | 4116 } else { |
3969 Handle<Map> old_map(object->map()); | 4117 Handle<Map> old_map(object->map()); |
3970 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, | 4118 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, |
3971 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); | 4119 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); |
3972 JSObject::MigrateToMap(object, new_map); | 4120 JSObject::MigrateToMap(object, new_map); |
3973 } | 4121 } |
3974 | 4122 |
3975 DescriptorArray* descriptors = object->map()->instance_descriptors(); | 4123 DescriptorArray* descriptors = object->map()->instance_descriptors(); |
3976 int index = descriptors->GetDetails(descriptor_index).field_index(); | 4124 int index = descriptors->GetDetails(descriptor_index).field_index(); |
3977 object->FastPropertyAtPut(index, *value); | 4125 object->FastPropertyAtPut(index, *value); |
(...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4953 // If the object has fast properties, check whether the first slot | 5101 // If the object has fast properties, check whether the first slot |
4954 // in the descriptor array matches the hidden string. Since the | 5102 // in the descriptor array matches the hidden string. Since the |
4955 // hidden strings hash code is zero (and no other name has hash | 5103 // hidden strings hash code is zero (and no other name has hash |
4956 // code zero) it will always occupy the first entry if present. | 5104 // code zero) it will always occupy the first entry if present. |
4957 DescriptorArray* descriptors = this->map()->instance_descriptors(); | 5105 DescriptorArray* descriptors = this->map()->instance_descriptors(); |
4958 if (descriptors->number_of_descriptors() > 0) { | 5106 if (descriptors->number_of_descriptors() > 0) { |
4959 int sorted_index = descriptors->GetSortedKeyIndex(0); | 5107 int sorted_index = descriptors->GetSortedKeyIndex(0); |
4960 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && | 5108 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && |
4961 sorted_index < map()->NumberOfOwnDescriptors()) { | 5109 sorted_index < map()->NumberOfOwnDescriptors()) { |
4962 ASSERT(descriptors->GetType(sorted_index) == FIELD); | 5110 ASSERT(descriptors->GetType(sorted_index) == FIELD); |
4963 ASSERT(descriptors->GetDetails(sorted_index).representation(). | |
4964 IsCompatibleForLoad(Representation::Tagged())); | |
4965 return this->RawFastPropertyAt( | 5111 return this->RawFastPropertyAt( |
4966 descriptors->GetFieldIndex(sorted_index)); | 5112 descriptors->GetFieldIndex(sorted_index)); |
4967 } else { | 5113 } else { |
4968 return GetHeap()->undefined_value(); | 5114 return GetHeap()->undefined_value(); |
4969 } | 5115 } |
4970 } else { | 5116 } else { |
4971 return GetHeap()->undefined_value(); | 5117 return GetHeap()->undefined_value(); |
4972 } | 5118 } |
4973 } else { | 5119 } else { |
4974 PropertyAttributes attributes; | 5120 PropertyAttributes attributes; |
(...skipping 1884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6859 | 7005 |
6860 result->InitializeDescriptors(descriptors); | 7006 result->InitializeDescriptors(descriptors); |
6861 | 7007 |
6862 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) { | 7008 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) { |
6863 TransitionArray* transitions; | 7009 TransitionArray* transitions; |
6864 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag); | 7010 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag); |
6865 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | 7011 if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
6866 set_transitions(transitions); | 7012 set_transitions(transitions); |
6867 result->SetBackPointer(this); | 7013 result->SetBackPointer(this); |
6868 } else { | 7014 } else { |
6869 descriptors->InitializeRepresentations(Representation::Tagged()); | 7015 int length = descriptors->number_of_descriptors(); |
7016 for (int i = 0; i < length; i++) { | |
7017 descriptors->SetRepresentation(i, Representation::Tagged()); | |
7018 if (descriptors->GetDetails(i).type() == FIELD) { | |
7019 descriptors->SetValue(i, HeapType::Any()); | |
7020 } | |
7021 } | |
6870 } | 7022 } |
6871 | 7023 |
6872 return result; | 7024 return result; |
6873 } | 7025 } |
6874 | 7026 |
6875 | 7027 |
6876 // Since this method is used to rewrite an existing transition tree, it can | 7028 // Since this method is used to rewrite an existing transition tree, it can |
6877 // always insert transitions without checking. | 7029 // always insert transitions without checking. |
6878 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, | 7030 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, |
6879 int new_descriptor, | 7031 int new_descriptor, |
(...skipping 1099 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7979 ASSERT(!IsEmpty()); | 8131 ASSERT(!IsEmpty()); |
7980 ASSERT(!HasEnumCache() || new_cache->length() > GetEnumCache()->length()); | 8132 ASSERT(!HasEnumCache() || new_cache->length() > GetEnumCache()->length()); |
7981 FixedArray::cast(bridge_storage)-> | 8133 FixedArray::cast(bridge_storage)-> |
7982 set(kEnumCacheBridgeCacheIndex, new_cache); | 8134 set(kEnumCacheBridgeCacheIndex, new_cache); |
7983 FixedArray::cast(bridge_storage)-> | 8135 FixedArray::cast(bridge_storage)-> |
7984 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); | 8136 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); |
7985 set(kEnumCacheIndex, bridge_storage); | 8137 set(kEnumCacheIndex, bridge_storage); |
7986 } | 8138 } |
7987 | 8139 |
7988 | 8140 |
8141 HeapType* DescriptorArray::GetFieldType(int descriptor_number) { | |
8142 ASSERT(GetDetails(descriptor_number).type() == FIELD); | |
8143 return HeapType::cast(GetValue(descriptor_number)); | |
8144 } | |
8145 | |
8146 | |
7989 void DescriptorArray::CopyFrom(int dst_index, | 8147 void DescriptorArray::CopyFrom(int dst_index, |
7990 DescriptorArray* src, | 8148 DescriptorArray* src, |
7991 int src_index, | 8149 int src_index, |
7992 const WhitenessWitness& witness) { | 8150 const WhitenessWitness& witness) { |
7993 Object* value = src->GetValue(src_index); | 8151 Object* value = src->GetValue(src_index); |
7994 PropertyDetails details = src->GetDetails(src_index); | 8152 PropertyDetails details = src->GetDetails(src_index); |
7995 Descriptor desc(src->GetKey(src_index), value, details); | 8153 Descriptor desc(src->GetKey(src_index), value, details); |
7996 Set(dst_index, &desc, witness); | 8154 Set(dst_index, &desc, witness); |
7997 } | 8155 } |
7998 | 8156 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8058 PropertyDetails details = GetDetails(descriptor); | 8216 PropertyDetails details = GetDetails(descriptor); |
8059 PropertyDetails other_details = other->GetDetails(descriptor); | 8217 PropertyDetails other_details = other->GetDetails(descriptor); |
8060 | 8218 |
8061 if (details.type() == FIELD || other_details.type() == FIELD || | 8219 if (details.type() == FIELD || other_details.type() == FIELD || |
8062 (store_mode == FORCE_FIELD && descriptor == modify_index) || | 8220 (store_mode == FORCE_FIELD && descriptor == modify_index) || |
8063 (details.type() == CONSTANT && | 8221 (details.type() == CONSTANT && |
8064 other_details.type() == CONSTANT && | 8222 other_details.type() == CONSTANT && |
8065 GetValue(descriptor) != other->GetValue(descriptor))) { | 8223 GetValue(descriptor) != other->GetValue(descriptor))) { |
8066 Representation representation = | 8224 Representation representation = |
8067 details.representation().generalize(other_details.representation()); | 8225 details.representation().generalize(other_details.representation()); |
8226 // TODO(bmeurer): Cleanup this crap! | |
8227 HeapType* field_type = HeapType::Any(); | |
8228 if (representation.IsHeapObject()) { | |
8229 Object* val = GetValue(descriptor); | |
8230 Object* other_val = other->GetValue(descriptor); | |
8231 if (details.type() == FIELD && other_details.type() == FIELD) { | |
8232 HeapType* type = HeapType::cast(val); | |
8233 HeapType* other_type = HeapType::cast(other_val); | |
8234 if (type->Is(other_type)) { | |
8235 field_type = other_type; | |
8236 } else if (other_type->Is(type)) { | |
8237 field_type = type; | |
8238 } | |
8239 } | |
8240 } | |
8068 FieldDescriptor d(key, | 8241 FieldDescriptor d(key, |
8069 current_offset++, | 8242 current_offset++, |
8243 field_type, | |
8070 other_details.attributes(), | 8244 other_details.attributes(), |
8071 representation); | 8245 representation); |
8072 result->Set(descriptor, &d, witness); | 8246 result->Set(descriptor, &d, witness); |
8073 } else { | 8247 } else { |
8074 result->CopyFrom(descriptor, other, descriptor, witness); | 8248 result->CopyFrom(descriptor, other, descriptor, witness); |
8075 } | 8249 } |
8076 } | 8250 } |
8077 | 8251 |
8078 // |valid| -> |new_size| | 8252 // |valid| -> |new_size| |
8079 for (; descriptor < new_size; descriptor++) { | 8253 for (; descriptor < new_size; descriptor++) { |
8080 PropertyDetails details = other->GetDetails(descriptor); | 8254 PropertyDetails details = other->GetDetails(descriptor); |
8081 if (details.type() == FIELD || | 8255 if (details.type() == FIELD || |
8082 (store_mode == FORCE_FIELD && descriptor == modify_index)) { | 8256 (store_mode == FORCE_FIELD && descriptor == modify_index)) { |
8083 Name* key = other->GetKey(descriptor); | 8257 Name* key = other->GetKey(descriptor); |
8084 FieldDescriptor d(key, | 8258 FieldDescriptor d(key, |
8085 current_offset++, | 8259 current_offset++, |
8260 HeapType::cast(other->GetValue(descriptor)), | |
8086 details.attributes(), | 8261 details.attributes(), |
8087 details.representation()); | 8262 details.representation()); |
8088 result->Set(descriptor, &d, witness); | 8263 result->Set(descriptor, &d, witness); |
8089 } else { | 8264 } else { |
8090 result->CopyFrom(descriptor, other, descriptor, witness); | 8265 result->CopyFrom(descriptor, other, descriptor, witness); |
8091 } | 8266 } |
8092 } | 8267 } |
8093 | 8268 |
8094 result->Sort(); | 8269 result->Sort(); |
8095 return result; | 8270 return result; |
(...skipping 7623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15719 if (current_offset < inobject_props) { | 15894 if (current_offset < inobject_props) { |
15720 obj->InObjectPropertyAtPut(current_offset, | 15895 obj->InObjectPropertyAtPut(current_offset, |
15721 value, | 15896 value, |
15722 UPDATE_WRITE_BARRIER); | 15897 UPDATE_WRITE_BARRIER); |
15723 } else { | 15898 } else { |
15724 int offset = current_offset - inobject_props; | 15899 int offset = current_offset - inobject_props; |
15725 fields->set(offset, value); | 15900 fields->set(offset, value); |
15726 } | 15901 } |
15727 FieldDescriptor d(key, | 15902 FieldDescriptor d(key, |
15728 current_offset++, | 15903 current_offset++, |
15904 HeapType::Any(), | |
15729 details.attributes(), | 15905 details.attributes(), |
15730 // TODO(verwaest): value->OptimalRepresentation(); | 15906 // TODO(verwaest): value->OptimalRepresentation(); |
15731 Representation::Tagged()); | 15907 Representation::Tagged()); |
15732 descriptors->Set(enumeration_index - 1, &d, witness); | 15908 descriptors->Set(enumeration_index - 1, &d, witness); |
15733 } else if (type == CALLBACKS) { | 15909 } else if (type == CALLBACKS) { |
15734 CallbacksDescriptor d(key, | 15910 CallbacksDescriptor d(key, |
15735 value, | 15911 value, |
15736 details.attributes()); | 15912 details.attributes()); |
15737 descriptors->Set(enumeration_index - 1, &d, witness); | 15913 descriptors->Set(enumeration_index - 1, &d, witness); |
15738 } else { | 15914 } else { |
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16478 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16654 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16479 static const char* error_messages_[] = { | 16655 static const char* error_messages_[] = { |
16480 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16656 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16481 }; | 16657 }; |
16482 #undef ERROR_MESSAGES_TEXTS | 16658 #undef ERROR_MESSAGES_TEXTS |
16483 return error_messages_[reason]; | 16659 return error_messages_[reason]; |
16484 } | 16660 } |
16485 | 16661 |
16486 | 16662 |
16487 } } // namespace v8::internal | 16663 } } // namespace v8::internal |
OLD | NEW |