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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 Object* result; | 66 Object* result; |
67 { MaybeObject* maybe_result = | 67 { MaybeObject* maybe_result = |
68 constructor->GetHeap()->AllocateJSObject(constructor); | 68 constructor->GetHeap()->AllocateJSObject(constructor); |
69 if (!maybe_result->ToObject(&result)) return maybe_result; | 69 if (!maybe_result->ToObject(&result)) return maybe_result; |
70 } | 70 } |
71 JSValue::cast(result)->set_value(value); | 71 JSValue::cast(result)->set_value(value); |
72 return result; | 72 return result; |
73 } | 73 } |
74 | 74 |
75 | 75 |
76 Handle<HeapType> Object::OptimalType(Isolate* isolate, | |
77 Representation representation) { | |
78 if (!FLAG_track_field_types) return HeapType::Any(isolate); | |
79 if (representation.IsNone()) return HeapType::None(isolate); | |
80 if (representation.IsHeapObject() && IsHeapObject()) { | |
81 // We can track only JavaScript objects with stable maps. | |
82 Handle<Map> map(HeapObject::cast(this)->map(), isolate); | |
83 if (map->is_stable() && | |
84 map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE && | |
85 map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE) { | |
86 return HeapType::Class(map, isolate); | |
87 } | |
88 } | |
89 return HeapType::Any(isolate); | |
90 } | |
91 | |
92 | |
76 MaybeObject* Object::ToObject(Context* native_context) { | 93 MaybeObject* Object::ToObject(Context* native_context) { |
77 if (IsNumber()) { | 94 if (IsNumber()) { |
78 return CreateJSValue(native_context->number_function(), this); | 95 return CreateJSValue(native_context->number_function(), this); |
79 } else if (IsBoolean()) { | 96 } else if (IsBoolean()) { |
80 return CreateJSValue(native_context->boolean_function(), this); | 97 return CreateJSValue(native_context->boolean_function(), this); |
81 } else if (IsString()) { | 98 } else if (IsString()) { |
82 return CreateJSValue(native_context->string_function(), this); | 99 return CreateJSValue(native_context->string_function(), this); |
83 } else if (IsSymbol()) { | 100 } else if (IsSymbol()) { |
84 return CreateJSValue(native_context->symbol_function(), this); | 101 return CreateJSValue(native_context->symbol_function(), this); |
85 } | 102 } |
(...skipping 1447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1533 } | 1550 } |
1534 | 1551 |
1535 | 1552 |
1536 void Map::PrintGeneralization(FILE* file, | 1553 void Map::PrintGeneralization(FILE* file, |
1537 const char* reason, | 1554 const char* reason, |
1538 int modify_index, | 1555 int modify_index, |
1539 int split, | 1556 int split, |
1540 int descriptors, | 1557 int descriptors, |
1541 bool constant_to_field, | 1558 bool constant_to_field, |
1542 Representation old_representation, | 1559 Representation old_representation, |
1543 Representation new_representation) { | 1560 Representation new_representation, |
1561 HeapType* old_field_type, | |
1562 HeapType* new_field_type) { | |
1544 PrintF(file, "[generalizing "); | 1563 PrintF(file, "[generalizing "); |
1545 constructor_name()->PrintOn(file); | 1564 constructor_name()->PrintOn(file); |
1546 PrintF(file, "] "); | 1565 PrintF(file, "] "); |
1547 Name* name = instance_descriptors()->GetKey(modify_index); | 1566 Name* name = instance_descriptors()->GetKey(modify_index); |
1548 if (name->IsString()) { | 1567 if (name->IsString()) { |
1549 String::cast(name)->PrintOn(file); | 1568 String::cast(name)->PrintOn(file); |
1550 } else { | 1569 } else { |
1551 PrintF(file, "{symbol %p}", static_cast<void*>(name)); | 1570 PrintF(file, "{symbol %p}", static_cast<void*>(name)); |
1552 } | 1571 } |
1572 PrintF(file, ":"); | |
1553 if (constant_to_field) { | 1573 if (constant_to_field) { |
1554 PrintF(file, ":c->f"); | 1574 PrintF(file, "c"); |
1555 } else { | 1575 } else { |
1556 PrintF(file, ":%s->%s", | 1576 PrintF(file, "%s", old_representation.Mnemonic()); |
1557 old_representation.Mnemonic(), | 1577 PrintF(file, "{"); |
1558 new_representation.Mnemonic()); | 1578 old_field_type->TypePrint(file, HeapType::SEMANTIC_DIM); |
1579 PrintF(file, "}"); | |
1559 } | 1580 } |
1581 PrintF(file, "->%s", new_representation.Mnemonic()); | |
1582 PrintF(file, "{"); | |
1583 new_field_type->TypePrint(file, HeapType::SEMANTIC_DIM); | |
1584 PrintF(file, "}"); | |
1560 PrintF(file, " ("); | 1585 PrintF(file, " ("); |
1561 if (strlen(reason) > 0) { | 1586 if (strlen(reason) > 0) { |
1562 PrintF(file, "%s", reason); | 1587 PrintF(file, "%s", reason); |
1563 } else { | 1588 } else { |
1564 PrintF(file, "+%i maps", descriptors - split); | 1589 PrintF(file, "+%i maps", descriptors - split); |
1565 } | 1590 } |
1566 PrintF(file, ") ["); | 1591 PrintF(file, ") ["); |
1567 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); | 1592 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); |
1568 PrintF(file, "]\n"); | 1593 PrintF(file, "]\n"); |
1569 } | 1594 } |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1941 Heap* heap = isolate->heap(); | 1966 Heap* heap = isolate->heap(); |
1942 CALL_HEAP_FUNCTION(isolate, | 1967 CALL_HEAP_FUNCTION(isolate, |
1943 object->AllocateNewStorageFor(heap, representation), | 1968 object->AllocateNewStorageFor(heap, representation), |
1944 Object); | 1969 Object); |
1945 } | 1970 } |
1946 | 1971 |
1947 | 1972 |
1948 static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map, | 1973 static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map, |
1949 Handle<Name> name, | 1974 Handle<Name> name, |
1950 int index, | 1975 int index, |
1976 Handle<HeapType> field_type, | |
1951 PropertyAttributes attributes, | 1977 PropertyAttributes attributes, |
1952 Representation representation, | 1978 Representation representation, |
1953 TransitionFlag flag) { | 1979 TransitionFlag flag) { |
1954 FieldDescriptor new_field_desc(name, index, attributes, representation); | 1980 FieldDescriptor new_field_desc(name, index, field_type, |
1981 attributes, representation); | |
1955 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); | 1982 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); |
1956 int unused_property_fields = map->unused_property_fields() - 1; | 1983 int unused_property_fields = map->unused_property_fields() - 1; |
1957 if (unused_property_fields < 0) { | 1984 if (unused_property_fields < 0) { |
1958 unused_property_fields += JSObject::kFieldsAdded; | 1985 unused_property_fields += JSObject::kFieldsAdded; |
1959 } | 1986 } |
1960 new_map->set_unused_property_fields(unused_property_fields); | 1987 new_map->set_unused_property_fields(unused_property_fields); |
1961 return new_map; | 1988 return new_map; |
1962 } | 1989 } |
1963 | 1990 |
1964 | 1991 |
(...skipping 16 matching lines...) Expand all Loading... | |
1981 if (!name->IsCacheable(isolate) || | 2008 if (!name->IsCacheable(isolate) || |
1982 object->TooManyFastProperties(store_mode)) { | 2009 object->TooManyFastProperties(store_mode)) { |
1983 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 2010 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
1984 AddSlowProperty(object, name, value, attributes); | 2011 AddSlowProperty(object, name, value, attributes); |
1985 return; | 2012 return; |
1986 } | 2013 } |
1987 | 2014 |
1988 // Compute the new index for new field. | 2015 // Compute the new index for new field. |
1989 int index = object->map()->NextFreePropertyIndex(); | 2016 int index = object->map()->NextFreePropertyIndex(); |
1990 | 2017 |
1991 // Allocate new instance descriptors with (name, index) added | 2018 // Compute the optimal representation for the new field. |
1992 if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED; | 2019 if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED; |
1993 Representation representation = value->OptimalRepresentation(value_type); | 2020 Representation representation = value->OptimalRepresentation(value_type); |
2021 | |
2022 // Allocate new instance descriptors with (name, index) added | |
Toon Verwaest
2014/04/11 12:49:43
This comment is a bit weird. I'd just drop it enti
Benedikt Meurer
2014/04/14 06:29:04
Done.
| |
1994 Handle<Map> new_map = CopyAddFieldDescriptor( | 2023 Handle<Map> new_map = CopyAddFieldDescriptor( |
1995 handle(object->map()), name, index, attributes, representation, flag); | 2024 handle(object->map()), name, index, |
2025 value->OptimalType(isolate, representation), | |
2026 attributes, representation, flag); | |
1996 | 2027 |
1997 JSObject::MigrateToMap(object, new_map); | 2028 JSObject::MigrateToMap(object, new_map); |
1998 | 2029 |
1999 if (representation.IsDouble()) { | 2030 if (representation.IsDouble()) { |
2000 // Nothing more to be done. | 2031 // Nothing more to be done. |
2001 if (value->IsUninitialized()) return; | 2032 if (value->IsUninitialized()) return; |
2002 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index)); | 2033 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index)); |
2003 box->set_value(value->Number()); | 2034 box->set_value(value->Number()); |
2004 } else { | 2035 } else { |
2005 object->FastPropertyAtPut(index, *value); | 2036 object->FastPropertyAtPut(index, *value); |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2431 // fresly allocated page or on an already swept page. Hence, the sweeper | 2462 // fresly allocated page or on an already swept page. Hence, the sweeper |
2432 // thread can not get confused with the filler creation. No synchronization | 2463 // thread can not get confused with the filler creation. No synchronization |
2433 // needed. | 2464 // needed. |
2434 object->set_map(*new_map); | 2465 object->set_map(*new_map); |
2435 } | 2466 } |
2436 | 2467 |
2437 | 2468 |
2438 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, | 2469 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, |
2439 int modify_index, | 2470 int modify_index, |
2440 Representation new_representation, | 2471 Representation new_representation, |
2472 Handle<HeapType> new_field_type, | |
2441 StoreMode store_mode) { | 2473 StoreMode store_mode) { |
2442 Handle<Map> new_map = Map::GeneralizeRepresentation( | 2474 Handle<Map> new_map = Map::GeneralizeRepresentation( |
2443 handle(object->map()), modify_index, new_representation, store_mode); | 2475 handle(object->map()), modify_index, new_representation, |
2476 new_field_type, store_mode); | |
2444 if (object->map() == *new_map) return; | 2477 if (object->map() == *new_map) return; |
2445 return MigrateToMap(object, new_map); | 2478 return MigrateToMap(object, new_map); |
2446 } | 2479 } |
2447 | 2480 |
2448 | 2481 |
2449 int Map::NumberOfFields() { | 2482 int Map::NumberOfFields() { |
2450 DescriptorArray* descriptors = instance_descriptors(); | 2483 DescriptorArray* descriptors = instance_descriptors(); |
2451 int result = 0; | 2484 int result = 0; |
2452 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { | 2485 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { |
2453 if (descriptors->GetDetails(i).type() == FIELD) result++; | 2486 if (descriptors->GetDetails(i).type() == FIELD) result++; |
2454 } | 2487 } |
2455 return result; | 2488 return result; |
2456 } | 2489 } |
2457 | 2490 |
2458 | 2491 |
2459 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, | 2492 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, |
2460 int modify_index, | 2493 int modify_index, |
2461 StoreMode store_mode, | 2494 StoreMode store_mode, |
2462 PropertyAttributes attributes, | 2495 PropertyAttributes attributes, |
2463 const char* reason) { | 2496 const char* reason) { |
2497 Isolate* isolate = map->GetIsolate(); | |
2464 Handle<Map> new_map = Copy(map); | 2498 Handle<Map> new_map = Copy(map); |
2465 | 2499 |
2466 DescriptorArray* descriptors = new_map->instance_descriptors(); | 2500 DescriptorArray* descriptors = new_map->instance_descriptors(); |
2467 descriptors->InitializeRepresentations(Representation::Tagged()); | 2501 int length = descriptors->number_of_descriptors(); |
2502 for (int i = 0; i < length; i++) { | |
2503 descriptors->SetRepresentation(i, Representation::Tagged()); | |
2504 if (descriptors->GetDetails(i).type() == FIELD) { | |
2505 descriptors->SetValue(i, HeapType::Any()); | |
2506 } | |
2507 } | |
2468 | 2508 |
2469 // Unless the instance is being migrated, ensure that modify_index is a field. | 2509 // Unless the instance is being migrated, ensure that modify_index is a field. |
2470 PropertyDetails details = descriptors->GetDetails(modify_index); | 2510 PropertyDetails details = descriptors->GetDetails(modify_index); |
2471 if (store_mode == FORCE_FIELD && details.type() != FIELD) { | 2511 if (store_mode == FORCE_FIELD && details.type() != FIELD) { |
2472 FieldDescriptor d(handle(descriptors->GetKey(modify_index), | 2512 FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate), |
2473 map->GetIsolate()), | |
2474 new_map->NumberOfFields(), | 2513 new_map->NumberOfFields(), |
2475 attributes, | 2514 attributes, |
2476 Representation::Tagged()); | 2515 Representation::Tagged()); |
2477 descriptors->Replace(modify_index, &d); | 2516 descriptors->Replace(modify_index, &d); |
2478 int unused_property_fields = new_map->unused_property_fields() - 1; | 2517 int unused_property_fields = new_map->unused_property_fields() - 1; |
2479 if (unused_property_fields < 0) { | 2518 if (unused_property_fields < 0) { |
2480 unused_property_fields += JSObject::kFieldsAdded; | 2519 unused_property_fields += JSObject::kFieldsAdded; |
2481 } | 2520 } |
2482 new_map->set_unused_property_fields(unused_property_fields); | 2521 new_map->set_unused_property_fields(unused_property_fields); |
2483 } | 2522 } |
2484 | 2523 |
2485 if (FLAG_trace_generalization) { | 2524 if (FLAG_trace_generalization) { |
2525 HeapType* field_type = (details.type() == FIELD) | |
2526 ? map->instance_descriptors()->GetFieldType(modify_index) | |
2527 : NULL; | |
2486 map->PrintGeneralization(stdout, reason, modify_index, | 2528 map->PrintGeneralization(stdout, reason, modify_index, |
2487 new_map->NumberOfOwnDescriptors(), | 2529 new_map->NumberOfOwnDescriptors(), |
2488 new_map->NumberOfOwnDescriptors(), | 2530 new_map->NumberOfOwnDescriptors(), |
2489 details.type() == CONSTANT && store_mode == FORCE_FIELD, | 2531 details.type() == CONSTANT && store_mode == FORCE_FIELD, |
2490 Representation::Tagged(), Representation::Tagged()); | 2532 details.representation(), Representation::Tagged(), |
2533 field_type, HeapType::Any()); | |
2491 } | 2534 } |
2492 return new_map; | 2535 return new_map; |
2493 } | 2536 } |
2494 | 2537 |
2495 | 2538 |
2496 void Map::DeprecateTransitionTree() { | 2539 void Map::DeprecateTransitionTree() { |
2497 if (is_deprecated()) return; | 2540 if (is_deprecated()) return; |
2498 if (HasTransitionArray()) { | 2541 if (HasTransitionArray()) { |
2499 TransitionArray* transitions = this->transitions(); | 2542 TransitionArray* transitions = this->transitions(); |
2500 for (int i = 0; i < transitions->number_of_transitions(); i++) { | 2543 for (int i = 0; i < transitions->number_of_transitions(); i++) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2545 if (back->IsUndefined()) return result; | 2588 if (back->IsUndefined()) return result; |
2546 result = Map::cast(back); | 2589 result = Map::cast(back); |
2547 } | 2590 } |
2548 } | 2591 } |
2549 | 2592 |
2550 | 2593 |
2551 // Returns NULL if the updated map is incompatible. | 2594 // Returns NULL if the updated map is incompatible. |
2552 Map* Map::FindUpdatedMap(int verbatim, | 2595 Map* Map::FindUpdatedMap(int verbatim, |
2553 int length, | 2596 int length, |
2554 DescriptorArray* descriptors) { | 2597 DescriptorArray* descriptors) { |
2598 DisallowHeapAllocation no_allocation; | |
2599 | |
2555 // This can only be called on roots of transition trees. | 2600 // This can only be called on roots of transition trees. |
2556 ASSERT(GetBackPointer()->IsUndefined()); | 2601 ASSERT(GetBackPointer()->IsUndefined()); |
2557 | 2602 |
2558 Map* current = this; | 2603 Map* current = this; |
2559 | 2604 |
2560 for (int i = verbatim; i < length; i++) { | 2605 for (int i = verbatim; i < length; i++) { |
2561 if (!current->HasTransitionArray()) break; | 2606 if (!current->HasTransitionArray()) break; |
2562 Name* name = descriptors->GetKey(i); | 2607 Name* name = descriptors->GetKey(i); |
2563 TransitionArray* transitions = current->transitions(); | 2608 TransitionArray* transitions = current->transitions(); |
2564 int transition = transitions->Search(name); | 2609 int transition = transitions->Search(name); |
(...skipping 14 matching lines...) Expand all Loading... | |
2579 } | 2624 } |
2580 } | 2625 } |
2581 | 2626 |
2582 return current; | 2627 return current; |
2583 } | 2628 } |
2584 | 2629 |
2585 | 2630 |
2586 Map* Map::FindLastMatchMap(int verbatim, | 2631 Map* Map::FindLastMatchMap(int verbatim, |
2587 int length, | 2632 int length, |
2588 DescriptorArray* descriptors) { | 2633 DescriptorArray* descriptors) { |
2634 DisallowHeapAllocation no_allocation; | |
2635 | |
2589 // This can only be called on roots of transition trees. | 2636 // This can only be called on roots of transition trees. |
2590 ASSERT(GetBackPointer()->IsUndefined()); | 2637 ASSERT(GetBackPointer()->IsUndefined()); |
2591 | 2638 |
2592 Map* current = this; | 2639 Map* current = this; |
2593 | 2640 |
2594 for (int i = verbatim; i < length; i++) { | 2641 for (int i = verbatim; i < length; i++) { |
2595 if (!current->HasTransitionArray()) break; | 2642 if (!current->HasTransitionArray()) break; |
2596 Name* name = descriptors->GetKey(i); | 2643 Name* name = descriptors->GetKey(i); |
2597 TransitionArray* transitions = current->transitions(); | 2644 TransitionArray* transitions = current->transitions(); |
2598 int transition = transitions->Search(name); | 2645 int transition = transitions->Search(name); |
2599 if (transition == TransitionArray::kNotFound) break; | 2646 if (transition == TransitionArray::kNotFound) break; |
2600 | 2647 |
2601 Map* next = transitions->GetTarget(transition); | 2648 Map* next = transitions->GetTarget(transition); |
2602 DescriptorArray* next_descriptors = next->instance_descriptors(); | 2649 DescriptorArray* next_descriptors = next->instance_descriptors(); |
2603 | 2650 |
2604 if (next_descriptors->GetValue(i) != descriptors->GetValue(i)) break; | |
2605 | |
2606 PropertyDetails details = descriptors->GetDetails(i); | 2651 PropertyDetails details = descriptors->GetDetails(i); |
2607 PropertyDetails next_details = next_descriptors->GetDetails(i); | 2652 PropertyDetails next_details = next_descriptors->GetDetails(i); |
2608 if (details.type() != next_details.type()) break; | 2653 if (details.type() != next_details.type()) break; |
2609 if (details.attributes() != next_details.attributes()) break; | 2654 if (details.attributes() != next_details.attributes()) break; |
2610 if (!details.representation().Equals(next_details.representation())) break; | 2655 if (!details.representation().Equals(next_details.representation())) break; |
2656 if (next_details.type() == FIELD) { | |
2657 if (!descriptors->GetFieldType(i)->NowIs( | |
2658 next_descriptors->GetFieldType(i))) break; | |
2659 } else { | |
2660 if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break; | |
2661 } | |
2611 | 2662 |
2612 current = next; | 2663 current = next; |
2613 } | 2664 } |
2614 return current; | 2665 return current; |
2615 } | 2666 } |
2616 | 2667 |
2617 | 2668 |
2669 Map* Map::FindFieldOwner(int descriptor) { | |
2670 DisallowHeapAllocation no_allocation; | |
2671 ASSERT_EQ(FIELD, instance_descriptors()->GetDetails(descriptor).type()); | |
2672 Map* result = this; | |
2673 while (true) { | |
2674 Object* back = result->GetBackPointer(); | |
2675 if (back->IsUndefined()) break; | |
2676 Map* parent = Map::cast(back); | |
2677 if (parent->NumberOfOwnDescriptors() <= descriptor) break; | |
2678 result = parent; | |
2679 } | |
2680 return result; | |
2681 } | |
2682 | |
2683 | |
2684 void Map::UpdateDescriptor(int descriptor_number, Descriptor* desc) { | |
2685 DisallowHeapAllocation no_allocation; | |
2686 if (HasTransitionArray()) { | |
2687 TransitionArray* transitions = this->transitions(); | |
2688 for (int i = 0; i < transitions->number_of_transitions(); ++i) { | |
2689 transitions->GetTarget(i)->UpdateDescriptor(descriptor_number, desc); | |
2690 } | |
2691 } | |
2692 instance_descriptors()->Replace(descriptor_number, desc);; | |
2693 } | |
2694 | |
2695 | |
2696 // static | |
2697 void Map::GeneralizeFieldType(Handle<Map> map, | |
2698 int modify_index, | |
2699 Handle<HeapType> new_field_type) { | |
2700 Isolate* isolate = map->GetIsolate(); | |
2701 Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate); | |
2702 Handle<DescriptorArray> descriptors( | |
2703 field_owner->instance_descriptors(), isolate); | |
2704 PropertyDetails details = descriptors->GetDetails(modify_index); | |
2705 | |
2706 // Check if we actually need to generalize the field type at all. | |
2707 Handle<HeapType> old_field_type( | |
2708 descriptors->GetFieldType(modify_index), isolate); | |
2709 if (new_field_type->NowIs(old_field_type)) return; | |
2710 | |
2711 // Determine the generalized new field type. | |
2712 if (!old_field_type->NowIs(new_field_type)) { | |
2713 new_field_type = HeapType::Any(isolate); | |
2714 } | |
2715 | |
2716 FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate), | |
2717 descriptors->GetFieldIndex(modify_index), | |
2718 new_field_type, | |
2719 details.attributes(), | |
2720 details.representation()); | |
2721 field_owner->UpdateDescriptor(modify_index, &d); | |
2722 field_owner->dependent_code()->DeoptimizeDependentCodeGroup( | |
2723 isolate, DependentCode::kFieldTypeGroup); | |
2724 | |
2725 if (FLAG_trace_generalization) { | |
2726 map->PrintGeneralization( | |
2727 stdout, "field type update", | |
2728 modify_index, map->NumberOfOwnDescriptors(), | |
2729 map->NumberOfOwnDescriptors(), false, | |
2730 details.representation(), details.representation(), | |
2731 *old_field_type, *new_field_type); | |
2732 } | |
2733 } | |
2734 | |
2735 | |
2618 // Generalize the representation of the descriptor at |modify_index|. | 2736 // Generalize the representation of the descriptor at |modify_index|. |
2619 // This method rewrites the transition tree to reflect the new change. To avoid | 2737 // This method rewrites the transition tree to reflect the new change. To avoid |
2620 // high degrees over polymorphism, and to stabilize quickly, on every rewrite | 2738 // high degrees over polymorphism, and to stabilize quickly, on every rewrite |
2621 // the new type is deduced by merging the current type with any potential new | 2739 // the new type is deduced by merging the current type with any potential new |
2622 // (partial) version of the type in the transition tree. | 2740 // (partial) version of the type in the transition tree. |
2623 // To do this, on each rewrite: | 2741 // To do this, on each rewrite: |
2624 // - Search the root of the transition tree using FindRootMap. | 2742 // - Search the root of the transition tree using FindRootMap. |
2625 // - Find |updated|, the newest matching version of this map using | 2743 // - Find |updated|, the newest matching version of this map using |
2626 // FindUpdatedMap. This uses the keys in the own map's descriptor array to | 2744 // FindUpdatedMap. This uses the keys in the own map's descriptor array to |
2627 // walk the transition tree. | 2745 // walk the transition tree. |
2628 // - Merge/generalize the descriptor array of the current map and |updated|. | 2746 // - Merge/generalize the descriptor array of the current map and |updated|. |
2629 // - Generalize the |modify_index| descriptor using |new_representation|. | 2747 // - Generalize the |modify_index| descriptor using |new_representation|. |
2630 // - Walk the tree again starting from the root towards |updated|. Stop at | 2748 // - Walk the tree again starting from the root towards |updated|. Stop at |
2631 // |split_map|, the first map who's descriptor array does not match the merged | 2749 // |split_map|, the first map who's descriptor array does not match the merged |
2632 // descriptor array. | 2750 // descriptor array. |
2633 // - If |updated| == |split_map|, |updated| is in the expected state. Return it. | 2751 // - If |updated| == |split_map|, |updated| is in the expected state. Return it. |
2634 // - Otherwise, invalidate the outdated transition target from |updated|, and | 2752 // - Otherwise, invalidate the outdated transition target from |updated|, and |
2635 // replace its transition tree with a new branch for the updated descriptors. | 2753 // replace its transition tree with a new branch for the updated descriptors. |
2636 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, | 2754 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, |
2637 int modify_index, | 2755 int modify_index, |
2638 Representation new_representation, | 2756 Representation new_representation, |
2757 Handle<HeapType> new_field_type, | |
2639 StoreMode store_mode) { | 2758 StoreMode store_mode) { |
2640 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); | 2759 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); |
2641 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2760 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
2642 Representation old_representation = old_details.representation(); | 2761 Representation old_representation = old_details.representation(); |
2643 | 2762 |
2644 // It's fine to transition from None to anything but double without any | 2763 // It's fine to transition from None to anything but double without any |
2645 // modification to the object, because the default uninitialized value for | 2764 // modification to the object, because the default uninitialized value for |
2646 // representation None can be overwritten by both smi and tagged values. | 2765 // representation None can be overwritten by both smi and tagged values. |
2647 // Doubles, however, would require a box allocation. | 2766 // Doubles, however, would require a box allocation. |
2648 if (old_representation.IsNone() && | 2767 if (old_representation.IsNone() && |
2649 !new_representation.IsNone() && | 2768 !new_representation.IsNone() && |
2650 !new_representation.IsDouble()) { | 2769 !new_representation.IsDouble()) { |
2770 ASSERT(old_details.type() == FIELD); | |
2771 ASSERT(old_descriptors->GetFieldType(modify_index)->NowIs( | |
2772 HeapType::None())); | |
2773 if (FLAG_trace_generalization) { | |
2774 old_map->PrintGeneralization( | |
2775 stdout, "uninitialized field", | |
2776 modify_index, old_map->NumberOfOwnDescriptors(), | |
2777 old_map->NumberOfOwnDescriptors(), false, | |
2778 old_representation, new_representation, | |
2779 old_descriptors->GetFieldType(modify_index), *new_field_type); | |
2780 } | |
2651 old_descriptors->SetRepresentation(modify_index, new_representation); | 2781 old_descriptors->SetRepresentation(modify_index, new_representation); |
2782 old_descriptors->SetValue(modify_index, *new_field_type); | |
2652 return old_map; | 2783 return old_map; |
2653 } | 2784 } |
2654 | 2785 |
2655 int descriptors = old_map->NumberOfOwnDescriptors(); | 2786 if (new_representation.Equals(old_representation) && |
2787 old_details.type() == FIELD) { | |
2788 Map::GeneralizeFieldType(old_map, modify_index, new_field_type); | |
2789 return old_map; | |
2790 } | |
2791 | |
2656 Handle<Map> root_map(old_map->FindRootMap()); | 2792 Handle<Map> root_map(old_map->FindRootMap()); |
2657 | 2793 |
2658 // Check the state of the root map. | 2794 // Check the state of the root map. |
2659 if (!old_map->EquivalentToForTransition(*root_map)) { | 2795 if (!old_map->EquivalentToForTransition(*root_map)) { |
2660 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2796 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2661 old_details.attributes(), "not equivalent"); | 2797 old_details.attributes(), "not equivalent"); |
2662 } | 2798 } |
2663 | 2799 |
2664 int verbatim = root_map->NumberOfOwnDescriptors(); | 2800 int verbatim = root_map->NumberOfOwnDescriptors(); |
2665 | 2801 |
2666 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) { | 2802 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) { |
2667 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2803 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2668 old_details.attributes(), "root modification"); | 2804 old_details.attributes(), "root modification"); |
2669 } | 2805 } |
2670 | 2806 |
2807 int descriptors = old_map->NumberOfOwnDescriptors(); | |
2671 Map* raw_updated = root_map->FindUpdatedMap( | 2808 Map* raw_updated = root_map->FindUpdatedMap( |
2672 verbatim, descriptors, *old_descriptors); | 2809 verbatim, descriptors, *old_descriptors); |
2673 if (raw_updated == NULL) { | 2810 if (raw_updated == NULL) { |
2674 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2811 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2675 old_details.attributes(), "incompatible"); | 2812 old_details.attributes(), "incompatible"); |
2676 } | 2813 } |
2677 | 2814 |
2678 Handle<Map> updated(raw_updated); | 2815 Handle<Map> updated(raw_updated); |
2679 Handle<DescriptorArray> updated_descriptors(updated->instance_descriptors()); | 2816 Handle<DescriptorArray> updated_descriptors(updated->instance_descriptors()); |
2680 | 2817 |
(...skipping 16 matching lines...) Expand all Loading... | |
2697 ASSERT(store_mode == ALLOW_AS_CONSTANT || | 2834 ASSERT(store_mode == ALLOW_AS_CONSTANT || |
2698 new_descriptors->GetDetails(modify_index).type() == FIELD); | 2835 new_descriptors->GetDetails(modify_index).type() == FIELD); |
2699 | 2836 |
2700 old_representation = | 2837 old_representation = |
2701 new_descriptors->GetDetails(modify_index).representation(); | 2838 new_descriptors->GetDetails(modify_index).representation(); |
2702 Representation updated_representation = | 2839 Representation updated_representation = |
2703 new_representation.generalize(old_representation); | 2840 new_representation.generalize(old_representation); |
2704 if (!updated_representation.Equals(old_representation)) { | 2841 if (!updated_representation.Equals(old_representation)) { |
2705 new_descriptors->SetRepresentation(modify_index, updated_representation); | 2842 new_descriptors->SetRepresentation(modify_index, updated_representation); |
2706 } | 2843 } |
2844 if (new_descriptors->GetDetails(modify_index).type() == FIELD) { | |
2845 Handle<HeapType> field_type(new_descriptors->GetFieldType(modify_index), | |
2846 new_descriptors->GetIsolate()); | |
2847 if (!new_field_type->NowIs(field_type)) { | |
2848 if (!field_type->NowIs(new_field_type)) { | |
2849 new_field_type = HeapType::Any(updated->GetIsolate()); | |
Toon Verwaest
2014/04/11 12:49:43
Could you introduce a method similar to new_repres
Benedikt Meurer
2014/04/14 06:29:04
Done.
| |
2850 } | |
2851 new_descriptors->SetValue(modify_index, *new_field_type); | |
2852 } | |
2853 } | |
2707 | 2854 |
2708 Handle<Map> split_map(root_map->FindLastMatchMap( | 2855 Handle<Map> split_map(root_map->FindLastMatchMap( |
2709 verbatim, descriptors, *new_descriptors)); | 2856 verbatim, descriptors, *new_descriptors)); |
2710 | 2857 |
2711 int split_descriptors = split_map->NumberOfOwnDescriptors(); | 2858 int split_descriptors = split_map->NumberOfOwnDescriptors(); |
2712 // This is shadowed by |updated_descriptors| being more general than | 2859 // This is shadowed by |updated_descriptors| being more general than |
2713 // |old_descriptors|. | 2860 // |old_descriptors|. |
2714 ASSERT(descriptors != split_descriptors); | 2861 ASSERT(descriptors != split_descriptors); |
2715 | 2862 |
2716 int descriptor = split_descriptors; | 2863 int descriptor = split_descriptors; |
2717 split_map->DeprecateTarget( | 2864 split_map->DeprecateTarget( |
2718 old_descriptors->GetKey(descriptor), *new_descriptors); | 2865 old_descriptors->GetKey(descriptor), *new_descriptors); |
2719 | 2866 |
2720 if (FLAG_trace_generalization) { | 2867 if (FLAG_trace_generalization) { |
2868 Isolate* isolate = old_map->GetIsolate(); | |
2869 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | |
2870 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); | |
2871 Handle<HeapType> old_field_type = (old_details.type() == FIELD) | |
2872 ? handle(old_descriptors->GetFieldType(modify_index), isolate) | |
2873 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), | |
2874 isolate), isolate); | |
2875 Handle<HeapType> new_field_type = (new_details.type() == FIELD) | |
2876 ? handle(new_descriptors->GetFieldType(modify_index), isolate) | |
2877 : HeapType::Constant(handle(new_descriptors->GetValue(modify_index), | |
2878 isolate), isolate); | |
2721 old_map->PrintGeneralization( | 2879 old_map->PrintGeneralization( |
2722 stdout, "", modify_index, descriptor, descriptors, | 2880 stdout, "", modify_index, descriptor, descriptors, |
2723 old_descriptors->GetDetails(modify_index).type() == CONSTANT && | 2881 old_details.type() == CONSTANT && store_mode == FORCE_FIELD, |
2724 store_mode == FORCE_FIELD, | 2882 old_details.representation(), new_details.representation(), |
2725 old_representation, updated_representation); | 2883 *old_field_type, *new_field_type); |
2726 } | 2884 } |
2727 | 2885 |
2728 // Add missing transitions. | 2886 // Add missing transitions. |
2729 Handle<Map> new_map = split_map; | 2887 Handle<Map> new_map = split_map; |
2730 for (; descriptor < descriptors; descriptor++) { | 2888 for (; descriptor < descriptors; descriptor++) { |
2731 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors); | 2889 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors); |
2732 } | 2890 } |
2733 | 2891 |
2734 new_map->set_owns_descriptors(true); | 2892 new_map->set_owns_descriptors(true); |
2735 return new_map; | 2893 return new_map; |
2736 } | 2894 } |
2737 | 2895 |
2738 | 2896 |
2739 // Generalize the representation of all FIELD descriptors. | 2897 // Generalize the representation of all FIELD descriptors. |
2740 Handle<Map> Map::GeneralizeAllFieldRepresentations( | 2898 Handle<Map> Map::GeneralizeAllFieldRepresentations( |
2741 Handle<Map> map, | 2899 Handle<Map> map) { |
2742 Representation new_representation) { | |
2743 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 2900 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
2744 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { | 2901 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { |
2745 PropertyDetails details = descriptors->GetDetails(i); | 2902 if (descriptors->GetDetails(i).type() == FIELD) { |
2746 if (details.type() == FIELD) { | 2903 map = GeneralizeRepresentation(map, i, Representation::Tagged(), |
2747 map = GeneralizeRepresentation(map, i, new_representation, FORCE_FIELD); | 2904 HeapType::Any(map->GetIsolate()), |
2905 FORCE_FIELD); | |
2748 } | 2906 } |
2749 } | 2907 } |
2750 return map; | 2908 return map; |
2751 } | 2909 } |
2752 | 2910 |
2753 | 2911 |
2754 Handle<Map> Map::CurrentMapForDeprecated(Handle<Map> map) { | 2912 Handle<Map> Map::CurrentMapForDeprecated(Handle<Map> map) { |
2755 Handle<Map> proto_map(map); | 2913 Handle<Map> proto_map(map); |
2756 while (proto_map->prototype()->IsJSObject()) { | 2914 while (proto_map->prototype()->IsJSObject()) { |
2757 Handle<JSObject> holder(JSObject::cast(proto_map->prototype())); | 2915 Handle<JSObject> holder(JSObject::cast(proto_map->prototype())); |
(...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3873 JSObject::MigrateToMap(object, map); | 4031 JSObject::MigrateToMap(object, map); |
3874 } | 4032 } |
3875 | 4033 |
3876 | 4034 |
3877 void JSObject::MigrateInstance(Handle<JSObject> object) { | 4035 void JSObject::MigrateInstance(Handle<JSObject> object) { |
3878 // Converting any field to the most specific type will cause the | 4036 // Converting any field to the most specific type will cause the |
3879 // GeneralizeFieldRepresentation algorithm to create the most general existing | 4037 // GeneralizeFieldRepresentation algorithm to create the most general existing |
3880 // transition that matches the object. This achieves what is needed. | 4038 // transition that matches the object. This achieves what is needed. |
3881 Handle<Map> original_map(object->map()); | 4039 Handle<Map> original_map(object->map()); |
3882 GeneralizeFieldRepresentation( | 4040 GeneralizeFieldRepresentation( |
3883 object, 0, Representation::None(), ALLOW_AS_CONSTANT); | 4041 object, 0, Representation::None(), |
4042 HeapType::None(object->GetIsolate()), | |
4043 ALLOW_AS_CONSTANT); | |
3884 object->map()->set_migration_target(true); | 4044 object->map()->set_migration_target(true); |
3885 if (FLAG_trace_migration) { | 4045 if (FLAG_trace_migration) { |
3886 object->PrintInstanceMigration(stdout, *original_map, object->map()); | 4046 object->PrintInstanceMigration(stdout, *original_map, object->map()); |
3887 } | 4047 } |
3888 } | 4048 } |
3889 | 4049 |
3890 | 4050 |
3891 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { | 4051 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { |
3892 Handle<Map> original_map(object->map()); | 4052 Handle<Map> original_map(object->map()); |
3893 Handle<Map> new_map = Map::CurrentMapForDeprecatedInternal(original_map); | 4053 Handle<Map> new_map = Map::CurrentMapForDeprecatedInternal(original_map); |
3894 if (new_map.is_null()) return Handle<Object>(); | 4054 if (new_map.is_null()) return Handle<Object>(); |
3895 JSObject::MigrateToMap(object, new_map); | 4055 JSObject::MigrateToMap(object, new_map); |
3896 if (FLAG_trace_migration) { | 4056 if (FLAG_trace_migration) { |
3897 object->PrintInstanceMigration(stdout, *original_map, object->map()); | 4057 object->PrintInstanceMigration(stdout, *original_map, object->map()); |
3898 } | 4058 } |
3899 return object; | 4059 return object; |
3900 } | 4060 } |
3901 | 4061 |
3902 | 4062 |
3903 MaybeHandle<Object> JSObject::SetPropertyUsingTransition( | 4063 MaybeHandle<Object> JSObject::SetPropertyUsingTransition( |
3904 Handle<JSObject> object, | 4064 Handle<JSObject> object, |
3905 LookupResult* lookup, | 4065 LookupResult* lookup, |
3906 Handle<Name> name, | 4066 Handle<Name> name, |
3907 Handle<Object> value, | 4067 Handle<Object> value, |
3908 PropertyAttributes attributes) { | 4068 PropertyAttributes attributes) { |
3909 Handle<Map> transition_map(lookup->GetTransitionTarget()); | 4069 Handle<Map> transition_map(lookup->GetTransitionTarget()); |
3910 int descriptor = transition_map->LastAdded(); | 4070 int descriptor = transition_map->LastAdded(); |
3911 | 4071 |
3912 DescriptorArray* descriptors = transition_map->instance_descriptors(); | 4072 Handle<DescriptorArray> descriptors(transition_map->instance_descriptors()); |
3913 PropertyDetails details = descriptors->GetDetails(descriptor); | 4073 PropertyDetails details = descriptors->GetDetails(descriptor); |
3914 | 4074 |
3915 if (details.type() == CALLBACKS || attributes != details.attributes()) { | 4075 if (details.type() == CALLBACKS || attributes != details.attributes()) { |
3916 // AddProperty will either normalize the object, or create a new fast copy | 4076 // AddProperty will either normalize the object, or create a new fast copy |
3917 // of the map. If we get a fast copy of the map, all field representations | 4077 // of the map. If we get a fast copy of the map, all field representations |
3918 // will be tagged since the transition is omitted. | 4078 // will be tagged since the transition is omitted. |
3919 return JSObject::AddProperty( | 4079 return JSObject::AddProperty( |
3920 object, name, value, attributes, SLOPPY, | 4080 object, name, value, attributes, SLOPPY, |
3921 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, | 4081 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, |
3922 JSReceiver::OMIT_EXTENSIBILITY_CHECK, | 4082 JSReceiver::OMIT_EXTENSIBILITY_CHECK, |
3923 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); | 4083 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); |
3924 } | 4084 } |
3925 | 4085 |
3926 // Keep the target CONSTANT if the same value is stored. | 4086 // Keep the target CONSTANT if the same value is stored. |
3927 // TODO(verwaest): Also support keeping the placeholder | 4087 // TODO(verwaest): Also support keeping the placeholder |
3928 // (value->IsUninitialized) as constant. | 4088 // (value->IsUninitialized) as constant. |
3929 if (!lookup->CanHoldValue(value) || | 4089 if (!lookup->CanHoldValue(value)) { |
3930 (details.type() == CONSTANT && | 4090 Representation field_representation = value->OptimalRepresentation(); |
3931 descriptors->GetValue(descriptor) != *value)) { | 4091 Handle<HeapType> field_type = value->OptimalType( |
3932 transition_map = Map::GeneralizeRepresentation(transition_map, | 4092 lookup->isolate(), field_representation); |
3933 descriptor, value->OptimalRepresentation(), FORCE_FIELD); | 4093 transition_map = Map::GeneralizeRepresentation( |
4094 transition_map, descriptor, | |
4095 field_representation, field_type, FORCE_FIELD); | |
3934 } | 4096 } |
3935 | 4097 |
3936 JSObject::MigrateToMap(object, transition_map); | 4098 JSObject::MigrateToMap(object, transition_map); |
3937 | 4099 |
3938 // Reload. | 4100 // Reload. |
3939 descriptors = transition_map->instance_descriptors(); | 4101 descriptors = handle(transition_map->instance_descriptors()); |
3940 details = descriptors->GetDetails(descriptor); | 4102 details = descriptors->GetDetails(descriptor); |
3941 | 4103 |
3942 if (details.type() != FIELD) return value; | 4104 if (details.type() != FIELD) return value; |
3943 | 4105 |
3944 int field_index = descriptors->GetFieldIndex(descriptor); | 4106 int field_index = descriptors->GetFieldIndex(descriptor); |
3945 if (details.representation().IsDouble()) { | 4107 if (details.representation().IsDouble()) { |
3946 // Nothing more to be done. | 4108 // Nothing more to be done. |
3947 if (value->IsUninitialized()) return value; | 4109 if (value->IsUninitialized()) return value; |
3948 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index)); | 4110 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index)); |
3949 box->set_value(value->Number()); | 4111 box->set_value(value->Number()); |
3950 } else { | 4112 } else { |
3951 object->FastPropertyAtPut(field_index, *value); | 4113 object->FastPropertyAtPut(field_index, *value); |
3952 } | 4114 } |
3953 | 4115 |
3954 return value; | 4116 return value; |
3955 } | 4117 } |
3956 | 4118 |
3957 | 4119 |
3958 static void SetPropertyToField(LookupResult* lookup, | 4120 static void SetPropertyToField(LookupResult* lookup, |
3959 Handle<Object> value) { | 4121 Handle<Object> value) { |
3960 Representation representation = lookup->representation(); | 4122 Representation representation = lookup->representation(); |
3961 if (!lookup->CanHoldValue(value) || | 4123 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { |
3962 lookup->type() == CONSTANT) { | 4124 Representation field_representation = value->OptimalRepresentation(); |
4125 Handle<HeapType> field_type = value->OptimalType( | |
4126 lookup->isolate(), field_representation); | |
3963 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), | 4127 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), |
3964 lookup->GetDescriptorIndex(), | 4128 lookup->GetDescriptorIndex(), |
3965 value->OptimalRepresentation(), | 4129 field_representation, field_type, |
3966 FORCE_FIELD); | 4130 FORCE_FIELD); |
3967 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); | 4131 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); |
3968 int descriptor = lookup->GetDescriptorIndex(); | 4132 int descriptor = lookup->GetDescriptorIndex(); |
3969 representation = desc->GetDetails(descriptor).representation(); | 4133 representation = desc->GetDetails(descriptor).representation(); |
3970 } | 4134 } |
3971 | 4135 |
3972 if (representation.IsDouble()) { | 4136 if (representation.IsDouble()) { |
3973 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( | 4137 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( |
3974 lookup->GetFieldIndex().field_index())); | 4138 lookup->GetFieldIndex().field_index())); |
3975 storage->set_value(value->Number()); | 4139 storage->set_value(value->Number()); |
(...skipping 15 matching lines...) Expand all Loading... | |
3991 } | 4155 } |
3992 | 4156 |
3993 if (!object->HasFastProperties()) { | 4157 if (!object->HasFastProperties()) { |
3994 ReplaceSlowProperty(object, name, value, attributes); | 4158 ReplaceSlowProperty(object, name, value, attributes); |
3995 return; | 4159 return; |
3996 } | 4160 } |
3997 | 4161 |
3998 int descriptor_index = lookup->GetDescriptorIndex(); | 4162 int descriptor_index = lookup->GetDescriptorIndex(); |
3999 if (lookup->GetAttributes() == attributes) { | 4163 if (lookup->GetAttributes() == attributes) { |
4000 JSObject::GeneralizeFieldRepresentation( | 4164 JSObject::GeneralizeFieldRepresentation( |
4001 object, descriptor_index, Representation::Tagged(), FORCE_FIELD); | 4165 object, descriptor_index, Representation::Tagged(), |
4166 HeapType::Any(lookup->isolate()), FORCE_FIELD); | |
4002 } else { | 4167 } else { |
4003 Handle<Map> old_map(object->map()); | 4168 Handle<Map> old_map(object->map()); |
4004 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, | 4169 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, |
4005 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); | 4170 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); |
4006 JSObject::MigrateToMap(object, new_map); | 4171 JSObject::MigrateToMap(object, new_map); |
4007 } | 4172 } |
4008 | 4173 |
4009 DescriptorArray* descriptors = object->map()->instance_descriptors(); | 4174 DescriptorArray* descriptors = object->map()->instance_descriptors(); |
4010 int index = descriptors->GetDetails(descriptor_index).field_index(); | 4175 int index = descriptors->GetDetails(descriptor_index).field_index(); |
4011 object->FastPropertyAtPut(index, *value); | 4176 object->FastPropertyAtPut(index, *value); |
(...skipping 2821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6833 | 6998 |
6834 Handle<Map> result = CopyDropDescriptors(map); | 6999 Handle<Map> result = CopyDropDescriptors(map); |
6835 result->InitializeDescriptors(*descriptors); | 7000 result->InitializeDescriptors(*descriptors); |
6836 | 7001 |
6837 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { | 7002 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { |
6838 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( | 7003 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( |
6839 map, name, result, simple_flag); | 7004 map, name, result, simple_flag); |
6840 map->set_transitions(*transitions); | 7005 map->set_transitions(*transitions); |
6841 result->SetBackPointer(*map); | 7006 result->SetBackPointer(*map); |
6842 } else { | 7007 } else { |
6843 descriptors->InitializeRepresentations(Representation::Tagged()); | 7008 int length = descriptors->number_of_descriptors(); |
7009 for (int i = 0; i < length; i++) { | |
7010 descriptors->SetRepresentation(i, Representation::Tagged()); | |
7011 if (descriptors->GetDetails(i).type() == FIELD) { | |
7012 descriptors->SetValue(i, HeapType::Any()); | |
7013 } | |
7014 } | |
6844 } | 7015 } |
6845 | 7016 |
6846 return result; | 7017 return result; |
6847 } | 7018 } |
6848 | 7019 |
6849 | 7020 |
6850 // Since this method is used to rewrite an existing transition tree, it can | 7021 // Since this method is used to rewrite an existing transition tree, it can |
6851 // always insert transitions without checking. | 7022 // always insert transitions without checking. |
6852 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, | 7023 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, |
6853 int new_descriptor, | 7024 int new_descriptor, |
(...skipping 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7990 int valid, | 8161 int valid, |
7991 int new_size, | 8162 int new_size, |
7992 int modify_index, | 8163 int modify_index, |
7993 StoreMode store_mode, | 8164 StoreMode store_mode, |
7994 Handle<Map> right_map) { | 8165 Handle<Map> right_map) { |
7995 ASSERT(verbatim <= valid); | 8166 ASSERT(verbatim <= valid); |
7996 ASSERT(valid <= new_size); | 8167 ASSERT(valid <= new_size); |
7997 | 8168 |
7998 // Allocate a new descriptor array large enough to hold the required | 8169 // Allocate a new descriptor array large enough to hold the required |
7999 // descriptors, with minimally the exact same size as this descriptor array. | 8170 // descriptors, with minimally the exact same size as this descriptor array. |
8000 Factory* factory = left_map->GetIsolate()->factory(); | 8171 Isolate* isolate = left_map->GetIsolate(); |
8001 Handle<DescriptorArray> left(left_map->instance_descriptors()); | 8172 Handle<DescriptorArray> left(left_map->instance_descriptors()); |
8002 Handle<DescriptorArray> right(right_map->instance_descriptors()); | 8173 Handle<DescriptorArray> right(right_map->instance_descriptors()); |
8003 Handle<DescriptorArray> result = factory->NewDescriptorArray( | 8174 Handle<DescriptorArray> result = isolate->factory()->NewDescriptorArray( |
8004 new_size, Max(new_size, right->number_of_descriptors()) - new_size); | 8175 new_size, Max(new_size, right->number_of_descriptors()) - new_size); |
8005 ASSERT(result->length() > left->length() || | 8176 ASSERT(result->length() > left->length() || |
8006 result->NumberOfSlackDescriptors() > 0 || | 8177 result->NumberOfSlackDescriptors() > 0 || |
8007 result->number_of_descriptors() == right->number_of_descriptors()); | 8178 result->number_of_descriptors() == right->number_of_descriptors()); |
8008 ASSERT(result->number_of_descriptors() == new_size); | 8179 ASSERT(result->number_of_descriptors() == new_size); |
8009 | 8180 |
8010 int descriptor; | 8181 int descriptor; |
8011 | 8182 |
8012 // 0 -> |verbatim| | 8183 // 0 -> |verbatim| |
8013 int current_offset = 0; | 8184 int current_offset = 0; |
8014 for (descriptor = 0; descriptor < verbatim; descriptor++) { | 8185 for (descriptor = 0; descriptor < verbatim; descriptor++) { |
8015 if (left->GetDetails(descriptor).type() == FIELD) current_offset++; | 8186 if (left->GetDetails(descriptor).type() == FIELD) current_offset++; |
8016 Descriptor d(handle(right->GetKey(descriptor)), | 8187 Descriptor d(handle(right->GetKey(descriptor)), |
8017 handle(right->GetValue(descriptor), right->GetIsolate()), | 8188 handle(right->GetValue(descriptor), right->GetIsolate()), |
8018 right->GetDetails(descriptor)); | 8189 right->GetDetails(descriptor)); |
8019 result->Set(descriptor, &d); | 8190 result->Set(descriptor, &d); |
8020 } | 8191 } |
8021 | 8192 |
8022 // |verbatim| -> |valid| | 8193 // |verbatim| -> |valid| |
8023 for (; descriptor < valid; descriptor++) { | 8194 for (; descriptor < valid; descriptor++) { |
8024 PropertyDetails left_details = left->GetDetails(descriptor); | 8195 PropertyDetails left_details = left->GetDetails(descriptor); |
8025 PropertyDetails right_details = right->GetDetails(descriptor); | 8196 PropertyDetails right_details = right->GetDetails(descriptor); |
8026 if (left_details.type() == FIELD || right_details.type() == FIELD || | 8197 if (left_details.type() == FIELD || right_details.type() == FIELD || |
8027 (store_mode == FORCE_FIELD && descriptor == modify_index) || | 8198 (store_mode == FORCE_FIELD && descriptor == modify_index) || |
8028 (left_details.type() == CONSTANT && | 8199 (left_details.type() == CONSTANT && |
8029 right_details.type() == CONSTANT && | 8200 right_details.type() == CONSTANT && |
8030 left->GetValue(descriptor) != right->GetValue(descriptor))) { | 8201 left->GetValue(descriptor) != right->GetValue(descriptor))) { |
8202 ASSERT(left_details.type() == CONSTANT || left_details.type() == FIELD); | |
8203 ASSERT(right_details.type() == CONSTANT || right_details.type() == FIELD); | |
8031 Representation representation = left_details.representation().generalize( | 8204 Representation representation = left_details.representation().generalize( |
8032 right_details.representation()); | 8205 right_details.representation()); |
8033 FieldDescriptor d(handle(left->GetKey(descriptor)), | 8206 Handle<HeapType> left_type = (left_details.type() == FIELD) |
8207 ? handle(left->GetFieldType(descriptor), isolate) | |
8208 : left->GetValue(descriptor)->OptimalType(isolate, representation); | |
8209 Handle<HeapType> right_type = (right_details.type() == FIELD) | |
8210 ? handle(right->GetFieldType(descriptor), isolate) | |
8211 : right->GetValue(descriptor)->OptimalType(isolate, representation); | |
8212 Handle<HeapType> field_type; | |
8213 if (right_type->NowIs(left_type)) { | |
Toon Verwaest
2014/04/11 12:49:43
Same generalize logic would apply here
Benedikt Meurer
2014/04/14 06:29:04
Done.
| |
8214 field_type = left_type; | |
8215 } else if (left_type->NowIs(right_type)) { | |
8216 field_type = right_type; | |
8217 } else { | |
8218 field_type = HeapType::Any(isolate); | |
8219 } | |
8220 FieldDescriptor d(handle(left->GetKey(descriptor), isolate), | |
8034 current_offset++, | 8221 current_offset++, |
8222 field_type, | |
8035 right_details.attributes(), | 8223 right_details.attributes(), |
8036 representation); | 8224 representation); |
8037 result->Set(descriptor, &d); | 8225 result->Set(descriptor, &d); |
8038 } else { | 8226 } else { |
8039 Descriptor d(handle(right->GetKey(descriptor)), | 8227 Descriptor d(handle(right->GetKey(descriptor), isolate), |
8040 handle(right->GetValue(descriptor), right->GetIsolate()), | 8228 handle(right->GetValue(descriptor), isolate), |
8041 right_details); | 8229 right_details); |
8042 result->Set(descriptor, &d); | 8230 result->Set(descriptor, &d); |
8043 } | 8231 } |
8044 } | 8232 } |
8045 | 8233 |
8046 // |valid| -> |new_size| | 8234 // |valid| -> |new_size| |
8047 for (; descriptor < new_size; descriptor++) { | 8235 for (; descriptor < new_size; descriptor++) { |
8048 PropertyDetails right_details = right->GetDetails(descriptor); | 8236 PropertyDetails right_details = right->GetDetails(descriptor); |
8049 if (right_details.type() == FIELD || | 8237 if (right_details.type() == FIELD) { |
8050 (store_mode == FORCE_FIELD && descriptor == modify_index)) { | 8238 FieldDescriptor d(handle(right->GetKey(descriptor), isolate), |
8051 FieldDescriptor d(handle(right->GetKey(descriptor)), | |
8052 current_offset++, | 8239 current_offset++, |
8240 handle(right->GetFieldType(descriptor), isolate), | |
8053 right_details.attributes(), | 8241 right_details.attributes(), |
8054 right_details.representation()); | 8242 right_details.representation()); |
8055 result->Set(descriptor, &d); | 8243 result->Set(descriptor, &d); |
8244 } else if (store_mode == FORCE_FIELD && descriptor == modify_index) { | |
8245 ASSERT_EQ(CONSTANT, right_details.type()); | |
8246 Representation field_representation = right_details.representation(); | |
8247 Handle<HeapType> field_type = right->GetValue(descriptor)->OptimalType( | |
8248 isolate, field_representation); | |
8249 FieldDescriptor d(handle(right->GetKey(descriptor), isolate), | |
8250 current_offset++, | |
8251 field_type, | |
8252 right_details.attributes(), | |
8253 field_representation); | |
8254 result->Set(descriptor, &d); | |
8056 } else { | 8255 } else { |
8057 Descriptor d(handle(right->GetKey(descriptor)), | 8256 Descriptor d(handle(right->GetKey(descriptor), isolate), |
8058 handle(right->GetValue(descriptor), right->GetIsolate()), | 8257 handle(right->GetValue(descriptor), isolate), |
8059 right_details); | 8258 right_details); |
8060 result->Set(descriptor, &d); | 8259 result->Set(descriptor, &d); |
8061 } | 8260 } |
8062 } | 8261 } |
8063 | 8262 |
8064 result->Sort(); | 8263 result->Sort(); |
8065 return result; | 8264 return result; |
8066 } | 8265 } |
8067 | 8266 |
8068 | 8267 |
(...skipping 8539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16608 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16807 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16609 static const char* error_messages_[] = { | 16808 static const char* error_messages_[] = { |
16610 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16809 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16611 }; | 16810 }; |
16612 #undef ERROR_MESSAGES_TEXTS | 16811 #undef ERROR_MESSAGES_TEXTS |
16613 return error_messages_[reason]; | 16812 return error_messages_[reason]; |
16614 } | 16813 } |
16615 | 16814 |
16616 | 16815 |
16617 } } // namespace v8::internal | 16816 } } // namespace v8::internal |
OLD | NEW |