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

Side by Side Diff: src/objects.cc

Issue 167303005: Track field types. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | src/property.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698