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

Side by Side Diff: src/objects.cc

Issue 236843002: Revert "Track field types." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 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
93 MaybeObject* Object::ToObject(Context* native_context) { 76 MaybeObject* Object::ToObject(Context* native_context) {
94 if (IsNumber()) { 77 if (IsNumber()) {
95 return CreateJSValue(native_context->number_function(), this); 78 return CreateJSValue(native_context->number_function(), this);
96 } else if (IsBoolean()) { 79 } else if (IsBoolean()) {
97 return CreateJSValue(native_context->boolean_function(), this); 80 return CreateJSValue(native_context->boolean_function(), this);
98 } else if (IsString()) { 81 } else if (IsString()) {
99 return CreateJSValue(native_context->string_function(), this); 82 return CreateJSValue(native_context->string_function(), this);
100 } else if (IsSymbol()) { 83 } else if (IsSymbol()) {
101 return CreateJSValue(native_context->symbol_function(), this); 84 return CreateJSValue(native_context->symbol_function(), this);
102 } 85 }
(...skipping 1354 matching lines...) Expand 10 before | Expand all | Expand 10 after
1457 } 1440 }
1458 1441
1459 1442
1460 void Map::PrintGeneralization(FILE* file, 1443 void Map::PrintGeneralization(FILE* file,
1461 const char* reason, 1444 const char* reason,
1462 int modify_index, 1445 int modify_index,
1463 int split, 1446 int split,
1464 int descriptors, 1447 int descriptors,
1465 bool constant_to_field, 1448 bool constant_to_field,
1466 Representation old_representation, 1449 Representation old_representation,
1467 Representation new_representation, 1450 Representation new_representation) {
1468 HeapType* old_field_type,
1469 HeapType* new_field_type) {
1470 PrintF(file, "[generalizing "); 1451 PrintF(file, "[generalizing ");
1471 constructor_name()->PrintOn(file); 1452 constructor_name()->PrintOn(file);
1472 PrintF(file, "] "); 1453 PrintF(file, "] ");
1473 Name* name = instance_descriptors()->GetKey(modify_index); 1454 Name* name = instance_descriptors()->GetKey(modify_index);
1474 if (name->IsString()) { 1455 if (name->IsString()) {
1475 String::cast(name)->PrintOn(file); 1456 String::cast(name)->PrintOn(file);
1476 } else { 1457 } else {
1477 PrintF(file, "{symbol %p}", static_cast<void*>(name)); 1458 PrintF(file, "{symbol %p}", static_cast<void*>(name));
1478 } 1459 }
1479 PrintF(file, ":");
1480 if (constant_to_field) { 1460 if (constant_to_field) {
1481 PrintF(file, "c"); 1461 PrintF(file, ":c->f");
1482 } else { 1462 } else {
1483 PrintF(file, "%s", old_representation.Mnemonic()); 1463 PrintF(file, ":%s->%s",
1484 PrintF(file, "{"); 1464 old_representation.Mnemonic(),
1485 old_field_type->TypePrint(file, HeapType::SEMANTIC_DIM); 1465 new_representation.Mnemonic());
1486 PrintF(file, "}");
1487 } 1466 }
1488 PrintF(file, "->%s", new_representation.Mnemonic());
1489 PrintF(file, "{");
1490 new_field_type->TypePrint(file, HeapType::SEMANTIC_DIM);
1491 PrintF(file, "}");
1492 PrintF(file, " ("); 1467 PrintF(file, " (");
1493 if (strlen(reason) > 0) { 1468 if (strlen(reason) > 0) {
1494 PrintF(file, "%s", reason); 1469 PrintF(file, "%s", reason);
1495 } else { 1470 } else {
1496 PrintF(file, "+%i maps", descriptors - split); 1471 PrintF(file, "+%i maps", descriptors - split);
1497 } 1472 }
1498 PrintF(file, ") ["); 1473 PrintF(file, ") [");
1499 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); 1474 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true);
1500 PrintF(file, "]\n"); 1475 PrintF(file, "]\n");
1501 } 1476 }
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
1873 Heap* heap = isolate->heap(); 1848 Heap* heap = isolate->heap();
1874 CALL_HEAP_FUNCTION(isolate, 1849 CALL_HEAP_FUNCTION(isolate,
1875 object->AllocateNewStorageFor(heap, representation), 1850 object->AllocateNewStorageFor(heap, representation),
1876 Object); 1851 Object);
1877 } 1852 }
1878 1853
1879 1854
1880 static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map, 1855 static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map,
1881 Handle<Name> name, 1856 Handle<Name> name,
1882 int index, 1857 int index,
1883 Handle<HeapType> field_type,
1884 PropertyAttributes attributes, 1858 PropertyAttributes attributes,
1885 Representation representation, 1859 Representation representation,
1886 TransitionFlag flag) { 1860 TransitionFlag flag) {
1887 FieldDescriptor new_field_desc(name, index, field_type, 1861 FieldDescriptor new_field_desc(name, index, attributes, representation);
1888 attributes, representation);
1889 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); 1862 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag);
1890 int unused_property_fields = map->unused_property_fields() - 1; 1863 int unused_property_fields = map->unused_property_fields() - 1;
1891 if (unused_property_fields < 0) { 1864 if (unused_property_fields < 0) {
1892 unused_property_fields += JSObject::kFieldsAdded; 1865 unused_property_fields += JSObject::kFieldsAdded;
1893 } 1866 }
1894 new_map->set_unused_property_fields(unused_property_fields); 1867 new_map->set_unused_property_fields(unused_property_fields);
1895 return new_map; 1868 return new_map;
1896 } 1869 }
1897 1870
1898 1871
(...skipping 16 matching lines...) Expand all
1915 if (!name->IsCacheable(isolate) || 1888 if (!name->IsCacheable(isolate) ||
1916 object->TooManyFastProperties(store_mode)) { 1889 object->TooManyFastProperties(store_mode)) {
1917 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); 1890 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
1918 AddSlowProperty(object, name, value, attributes); 1891 AddSlowProperty(object, name, value, attributes);
1919 return; 1892 return;
1920 } 1893 }
1921 1894
1922 // Compute the new index for new field. 1895 // Compute the new index for new field.
1923 int index = object->map()->NextFreePropertyIndex(); 1896 int index = object->map()->NextFreePropertyIndex();
1924 1897
1925 // Compute the optimal representation for the new field. 1898 // Allocate new instance descriptors with (name, index) added
1926 if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED; 1899 if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED;
1927 Representation representation = value->OptimalRepresentation(value_type); 1900 Representation representation = value->OptimalRepresentation(value_type);
1928
1929 Handle<Map> new_map = CopyAddFieldDescriptor( 1901 Handle<Map> new_map = CopyAddFieldDescriptor(
1930 handle(object->map()), name, index, 1902 handle(object->map()), name, index, attributes, representation, flag);
1931 value->OptimalType(isolate, representation),
1932 attributes, representation, flag);
1933 1903
1934 JSObject::MigrateToMap(object, new_map); 1904 JSObject::MigrateToMap(object, new_map);
1935 1905
1936 if (representation.IsDouble()) { 1906 if (representation.IsDouble()) {
1937 // Nothing more to be done. 1907 // Nothing more to be done.
1938 if (value->IsUninitialized()) return; 1908 if (value->IsUninitialized()) return;
1939 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index)); 1909 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index));
1940 box->set_value(value->Number()); 1910 box->set_value(value->Number());
1941 } else { 1911 } else {
1942 object->FastPropertyAtPut(index, *value); 1912 object->FastPropertyAtPut(index, *value);
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
2368 // fresly allocated page or on an already swept page. Hence, the sweeper 2338 // fresly allocated page or on an already swept page. Hence, the sweeper
2369 // thread can not get confused with the filler creation. No synchronization 2339 // thread can not get confused with the filler creation. No synchronization
2370 // needed. 2340 // needed.
2371 object->set_map(*new_map); 2341 object->set_map(*new_map);
2372 } 2342 }
2373 2343
2374 2344
2375 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, 2345 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object,
2376 int modify_index, 2346 int modify_index,
2377 Representation new_representation, 2347 Representation new_representation,
2378 Handle<HeapType> new_field_type,
2379 StoreMode store_mode) { 2348 StoreMode store_mode) {
2380 Handle<Map> new_map = Map::GeneralizeRepresentation( 2349 Handle<Map> new_map = Map::GeneralizeRepresentation(
2381 handle(object->map()), modify_index, new_representation, 2350 handle(object->map()), modify_index, new_representation, store_mode);
2382 new_field_type, store_mode);
2383 if (object->map() == *new_map) return; 2351 if (object->map() == *new_map) return;
2384 return MigrateToMap(object, new_map); 2352 return MigrateToMap(object, new_map);
2385 } 2353 }
2386 2354
2387 2355
2388 int Map::NumberOfFields() { 2356 int Map::NumberOfFields() {
2389 DescriptorArray* descriptors = instance_descriptors(); 2357 DescriptorArray* descriptors = instance_descriptors();
2390 int result = 0; 2358 int result = 0;
2391 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { 2359 for (int i = 0; i < NumberOfOwnDescriptors(); i++) {
2392 if (descriptors->GetDetails(i).type() == FIELD) result++; 2360 if (descriptors->GetDetails(i).type() == FIELD) result++;
2393 } 2361 }
2394 return result; 2362 return result;
2395 } 2363 }
2396 2364
2397 2365
2398 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, 2366 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map,
2399 int modify_index, 2367 int modify_index,
2400 StoreMode store_mode, 2368 StoreMode store_mode,
2401 PropertyAttributes attributes, 2369 PropertyAttributes attributes,
2402 const char* reason) { 2370 const char* reason) {
2403 Isolate* isolate = map->GetIsolate();
2404 Handle<Map> new_map = Copy(map); 2371 Handle<Map> new_map = Copy(map);
2405 2372
2406 DescriptorArray* descriptors = new_map->instance_descriptors(); 2373 DescriptorArray* descriptors = new_map->instance_descriptors();
2407 int length = descriptors->number_of_descriptors(); 2374 descriptors->InitializeRepresentations(Representation::Tagged());
2408 for (int i = 0; i < length; i++) {
2409 descriptors->SetRepresentation(i, Representation::Tagged());
2410 if (descriptors->GetDetails(i).type() == FIELD) {
2411 descriptors->SetValue(i, HeapType::Any());
2412 }
2413 }
2414 2375
2415 // Unless the instance is being migrated, ensure that modify_index is a field. 2376 // Unless the instance is being migrated, ensure that modify_index is a field.
2416 PropertyDetails details = descriptors->GetDetails(modify_index); 2377 PropertyDetails details = descriptors->GetDetails(modify_index);
2417 if (store_mode == FORCE_FIELD && details.type() != FIELD) { 2378 if (store_mode == FORCE_FIELD && details.type() != FIELD) {
2418 FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate), 2379 FieldDescriptor d(handle(descriptors->GetKey(modify_index),
2380 map->GetIsolate()),
2419 new_map->NumberOfFields(), 2381 new_map->NumberOfFields(),
2420 attributes, 2382 attributes,
2421 Representation::Tagged()); 2383 Representation::Tagged());
2422 descriptors->Replace(modify_index, &d); 2384 descriptors->Replace(modify_index, &d);
2423 int unused_property_fields = new_map->unused_property_fields() - 1; 2385 int unused_property_fields = new_map->unused_property_fields() - 1;
2424 if (unused_property_fields < 0) { 2386 if (unused_property_fields < 0) {
2425 unused_property_fields += JSObject::kFieldsAdded; 2387 unused_property_fields += JSObject::kFieldsAdded;
2426 } 2388 }
2427 new_map->set_unused_property_fields(unused_property_fields); 2389 new_map->set_unused_property_fields(unused_property_fields);
2428 } 2390 }
2429 2391
2430 if (FLAG_trace_generalization) { 2392 if (FLAG_trace_generalization) {
2431 HeapType* field_type = (details.type() == FIELD)
2432 ? map->instance_descriptors()->GetFieldType(modify_index)
2433 : NULL;
2434 map->PrintGeneralization(stdout, reason, modify_index, 2393 map->PrintGeneralization(stdout, reason, modify_index,
2435 new_map->NumberOfOwnDescriptors(), 2394 new_map->NumberOfOwnDescriptors(),
2436 new_map->NumberOfOwnDescriptors(), 2395 new_map->NumberOfOwnDescriptors(),
2437 details.type() == CONSTANT && store_mode == FORCE_FIELD, 2396 details.type() == CONSTANT && store_mode == FORCE_FIELD,
2438 details.representation(), Representation::Tagged(), 2397 Representation::Tagged(), Representation::Tagged());
2439 field_type, HeapType::Any());
2440 } 2398 }
2441 return new_map; 2399 return new_map;
2442 } 2400 }
2443 2401
2444 2402
2445 void Map::DeprecateTransitionTree() { 2403 void Map::DeprecateTransitionTree() {
2446 if (is_deprecated()) return; 2404 if (is_deprecated()) return;
2447 if (HasTransitionArray()) { 2405 if (HasTransitionArray()) {
2448 TransitionArray* transitions = this->transitions(); 2406 TransitionArray* transitions = this->transitions();
2449 for (int i = 0; i < transitions->number_of_transitions(); i++) { 2407 for (int i = 0; i < transitions->number_of_transitions(); i++) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2494 if (back->IsUndefined()) return result; 2452 if (back->IsUndefined()) return result;
2495 result = Map::cast(back); 2453 result = Map::cast(back);
2496 } 2454 }
2497 } 2455 }
2498 2456
2499 2457
2500 // Returns NULL if the updated map is incompatible. 2458 // Returns NULL if the updated map is incompatible.
2501 Map* Map::FindUpdatedMap(int verbatim, 2459 Map* Map::FindUpdatedMap(int verbatim,
2502 int length, 2460 int length,
2503 DescriptorArray* descriptors) { 2461 DescriptorArray* descriptors) {
2504 DisallowHeapAllocation no_allocation;
2505
2506 // This can only be called on roots of transition trees. 2462 // This can only be called on roots of transition trees.
2507 ASSERT(GetBackPointer()->IsUndefined()); 2463 ASSERT(GetBackPointer()->IsUndefined());
2508 2464
2509 Map* current = this; 2465 Map* current = this;
2510 2466
2511 for (int i = verbatim; i < length; i++) { 2467 for (int i = verbatim; i < length; i++) {
2512 if (!current->HasTransitionArray()) break; 2468 if (!current->HasTransitionArray()) break;
2513 Name* name = descriptors->GetKey(i); 2469 Name* name = descriptors->GetKey(i);
2514 TransitionArray* transitions = current->transitions(); 2470 TransitionArray* transitions = current->transitions();
2515 int transition = transitions->Search(name); 2471 int transition = transitions->Search(name);
(...skipping 14 matching lines...) Expand all
2530 } 2486 }
2531 } 2487 }
2532 2488
2533 return current; 2489 return current;
2534 } 2490 }
2535 2491
2536 2492
2537 Map* Map::FindLastMatchMap(int verbatim, 2493 Map* Map::FindLastMatchMap(int verbatim,
2538 int length, 2494 int length,
2539 DescriptorArray* descriptors) { 2495 DescriptorArray* descriptors) {
2540 DisallowHeapAllocation no_allocation;
2541
2542 // This can only be called on roots of transition trees. 2496 // This can only be called on roots of transition trees.
2543 ASSERT(GetBackPointer()->IsUndefined()); 2497 ASSERT(GetBackPointer()->IsUndefined());
2544 2498
2545 Map* current = this; 2499 Map* current = this;
2546 2500
2547 for (int i = verbatim; i < length; i++) { 2501 for (int i = verbatim; i < length; i++) {
2548 if (!current->HasTransitionArray()) break; 2502 if (!current->HasTransitionArray()) break;
2549 Name* name = descriptors->GetKey(i); 2503 Name* name = descriptors->GetKey(i);
2550 TransitionArray* transitions = current->transitions(); 2504 TransitionArray* transitions = current->transitions();
2551 int transition = transitions->Search(name); 2505 int transition = transitions->Search(name);
2552 if (transition == TransitionArray::kNotFound) break; 2506 if (transition == TransitionArray::kNotFound) break;
2553 2507
2554 Map* next = transitions->GetTarget(transition); 2508 Map* next = transitions->GetTarget(transition);
2555 DescriptorArray* next_descriptors = next->instance_descriptors(); 2509 DescriptorArray* next_descriptors = next->instance_descriptors();
2556 2510
2511 if (next_descriptors->GetValue(i) != descriptors->GetValue(i)) break;
2512
2557 PropertyDetails details = descriptors->GetDetails(i); 2513 PropertyDetails details = descriptors->GetDetails(i);
2558 PropertyDetails next_details = next_descriptors->GetDetails(i); 2514 PropertyDetails next_details = next_descriptors->GetDetails(i);
2559 if (details.type() != next_details.type()) break; 2515 if (details.type() != next_details.type()) break;
2560 if (details.attributes() != next_details.attributes()) break; 2516 if (details.attributes() != next_details.attributes()) break;
2561 if (!details.representation().Equals(next_details.representation())) break; 2517 if (!details.representation().Equals(next_details.representation())) break;
2562 if (next_details.type() == FIELD) {
2563 if (!descriptors->GetFieldType(i)->NowIs(
2564 next_descriptors->GetFieldType(i))) break;
2565 } else {
2566 if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break;
2567 }
2568 2518
2569 current = next; 2519 current = next;
2570 } 2520 }
2571 return current; 2521 return current;
2572 } 2522 }
2573 2523
2574 2524
2575 Map* Map::FindFieldOwner(int descriptor) {
2576 DisallowHeapAllocation no_allocation;
2577 ASSERT_EQ(FIELD, instance_descriptors()->GetDetails(descriptor).type());
2578 Map* result = this;
2579 while (true) {
2580 Object* back = result->GetBackPointer();
2581 if (back->IsUndefined()) break;
2582 Map* parent = Map::cast(back);
2583 if (parent->NumberOfOwnDescriptors() <= descriptor) break;
2584 result = parent;
2585 }
2586 return result;
2587 }
2588
2589
2590 void Map::UpdateDescriptor(int descriptor_number, Descriptor* desc) {
2591 DisallowHeapAllocation no_allocation;
2592 if (HasTransitionArray()) {
2593 TransitionArray* transitions = this->transitions();
2594 for (int i = 0; i < transitions->number_of_transitions(); ++i) {
2595 transitions->GetTarget(i)->UpdateDescriptor(descriptor_number, desc);
2596 }
2597 }
2598 instance_descriptors()->Replace(descriptor_number, desc);;
2599 }
2600
2601
2602 // static
2603 Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> old_field_type,
2604 Handle<HeapType> new_field_type,
2605 Isolate* isolate) {
2606 if (new_field_type->NowIs(old_field_type)) return old_field_type;
2607 if (old_field_type->NowIs(new_field_type)) return new_field_type;
2608 return HeapType::Any(isolate);
2609 }
2610
2611
2612 // static
2613 void Map::GeneralizeFieldType(Handle<Map> map,
2614 int modify_index,
2615 Handle<HeapType> new_field_type) {
2616 Isolate* isolate = map->GetIsolate();
2617 Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate);
2618 Handle<DescriptorArray> descriptors(
2619 field_owner->instance_descriptors(), isolate);
2620
2621 // Check if we actually need to generalize the field type at all.
2622 Handle<HeapType> old_field_type(
2623 descriptors->GetFieldType(modify_index), isolate);
2624 if (new_field_type->NowIs(old_field_type)) {
2625 ASSERT(Map::GeneralizeFieldType(old_field_type,
2626 new_field_type,
2627 isolate)->NowIs(old_field_type));
2628 return;
2629 }
2630
2631 // Determine the generalized new field type.
2632 new_field_type = Map::GeneralizeFieldType(
2633 old_field_type, new_field_type, isolate);
2634
2635 PropertyDetails details = descriptors->GetDetails(modify_index);
2636 FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate),
2637 descriptors->GetFieldIndex(modify_index),
2638 new_field_type,
2639 details.attributes(),
2640 details.representation());
2641 field_owner->UpdateDescriptor(modify_index, &d);
2642 field_owner->dependent_code()->DeoptimizeDependentCodeGroup(
2643 isolate, DependentCode::kFieldTypeGroup);
2644
2645 if (FLAG_trace_generalization) {
2646 map->PrintGeneralization(
2647 stdout, "field type generalization",
2648 modify_index, map->NumberOfOwnDescriptors(),
2649 map->NumberOfOwnDescriptors(), false,
2650 details.representation(), details.representation(),
2651 *old_field_type, *new_field_type);
2652 }
2653 }
2654
2655
2656 // Generalize the representation of the descriptor at |modify_index|. 2525 // Generalize the representation of the descriptor at |modify_index|.
2657 // This method rewrites the transition tree to reflect the new change. To avoid 2526 // This method rewrites the transition tree to reflect the new change. To avoid
2658 // high degrees over polymorphism, and to stabilize quickly, on every rewrite 2527 // high degrees over polymorphism, and to stabilize quickly, on every rewrite
2659 // the new type is deduced by merging the current type with any potential new 2528 // the new type is deduced by merging the current type with any potential new
2660 // (partial) version of the type in the transition tree. 2529 // (partial) version of the type in the transition tree.
2661 // To do this, on each rewrite: 2530 // To do this, on each rewrite:
2662 // - Search the root of the transition tree using FindRootMap. 2531 // - Search the root of the transition tree using FindRootMap.
2663 // - Find |updated|, the newest matching version of this map using 2532 // - Find |updated|, the newest matching version of this map using
2664 // FindUpdatedMap. This uses the keys in the own map's descriptor array to 2533 // FindUpdatedMap. This uses the keys in the own map's descriptor array to
2665 // walk the transition tree. 2534 // walk the transition tree.
2666 // - Merge/generalize the descriptor array of the current map and |updated|. 2535 // - Merge/generalize the descriptor array of the current map and |updated|.
2667 // - Generalize the |modify_index| descriptor using |new_representation|. 2536 // - Generalize the |modify_index| descriptor using |new_representation|.
2668 // - Walk the tree again starting from the root towards |updated|. Stop at 2537 // - Walk the tree again starting from the root towards |updated|. Stop at
2669 // |split_map|, the first map who's descriptor array does not match the merged 2538 // |split_map|, the first map who's descriptor array does not match the merged
2670 // descriptor array. 2539 // descriptor array.
2671 // - If |updated| == |split_map|, |updated| is in the expected state. Return it. 2540 // - If |updated| == |split_map|, |updated| is in the expected state. Return it.
2672 // - Otherwise, invalidate the outdated transition target from |updated|, and 2541 // - Otherwise, invalidate the outdated transition target from |updated|, and
2673 // replace its transition tree with a new branch for the updated descriptors. 2542 // replace its transition tree with a new branch for the updated descriptors.
2674 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, 2543 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
2675 int modify_index, 2544 int modify_index,
2676 Representation new_representation, 2545 Representation new_representation,
2677 Handle<HeapType> new_field_type,
2678 StoreMode store_mode) { 2546 StoreMode store_mode) {
2679 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); 2547 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
2680 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); 2548 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2681 Representation old_representation = old_details.representation(); 2549 Representation old_representation = old_details.representation();
2682 2550
2683 // It's fine to transition from None to anything but double without any 2551 // It's fine to transition from None to anything but double without any
2684 // modification to the object, because the default uninitialized value for 2552 // modification to the object, because the default uninitialized value for
2685 // representation None can be overwritten by both smi and tagged values. 2553 // representation None can be overwritten by both smi and tagged values.
2686 // Doubles, however, would require a box allocation. 2554 // Doubles, however, would require a box allocation.
2687 if (old_representation.IsNone() && 2555 if (old_representation.IsNone() &&
2688 !new_representation.IsNone() && 2556 !new_representation.IsNone() &&
2689 !new_representation.IsDouble()) { 2557 !new_representation.IsDouble()) {
2690 ASSERT(old_details.type() == FIELD);
2691 ASSERT(old_descriptors->GetFieldType(modify_index)->NowIs(
2692 HeapType::None()));
2693 if (FLAG_trace_generalization) {
2694 old_map->PrintGeneralization(
2695 stdout, "uninitialized field",
2696 modify_index, old_map->NumberOfOwnDescriptors(),
2697 old_map->NumberOfOwnDescriptors(), false,
2698 old_representation, new_representation,
2699 old_descriptors->GetFieldType(modify_index), *new_field_type);
2700 }
2701 old_descriptors->SetRepresentation(modify_index, new_representation); 2558 old_descriptors->SetRepresentation(modify_index, new_representation);
2702 old_descriptors->SetValue(modify_index, *new_field_type);
2703 return old_map; 2559 return old_map;
2704 } 2560 }
2705 2561
2706 if (new_representation.Equals(old_representation) && 2562 int descriptors = old_map->NumberOfOwnDescriptors();
2707 old_details.type() == FIELD) {
2708 Map::GeneralizeFieldType(old_map, modify_index, new_field_type);
2709 return old_map;
2710 }
2711
2712 Handle<Map> root_map(old_map->FindRootMap()); 2563 Handle<Map> root_map(old_map->FindRootMap());
2713 2564
2714 // Check the state of the root map. 2565 // Check the state of the root map.
2715 if (!old_map->EquivalentToForTransition(*root_map)) { 2566 if (!old_map->EquivalentToForTransition(*root_map)) {
2716 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, 2567 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2717 old_details.attributes(), "not equivalent"); 2568 old_details.attributes(), "not equivalent");
2718 } 2569 }
2719 2570
2720 int verbatim = root_map->NumberOfOwnDescriptors(); 2571 int verbatim = root_map->NumberOfOwnDescriptors();
2721 2572
2722 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) { 2573 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) {
2723 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, 2574 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2724 old_details.attributes(), "root modification"); 2575 old_details.attributes(), "root modification");
2725 } 2576 }
2726 2577
2727 int descriptors = old_map->NumberOfOwnDescriptors();
2728 Map* raw_updated = root_map->FindUpdatedMap( 2578 Map* raw_updated = root_map->FindUpdatedMap(
2729 verbatim, descriptors, *old_descriptors); 2579 verbatim, descriptors, *old_descriptors);
2730 if (raw_updated == NULL) { 2580 if (raw_updated == NULL) {
2731 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, 2581 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2732 old_details.attributes(), "incompatible"); 2582 old_details.attributes(), "incompatible");
2733 } 2583 }
2734 2584
2735 Handle<Map> updated(raw_updated); 2585 Handle<Map> updated(raw_updated);
2736 Handle<DescriptorArray> updated_descriptors(updated->instance_descriptors()); 2586 Handle<DescriptorArray> updated_descriptors(updated->instance_descriptors());
2737 2587
2738 int valid = updated->NumberOfOwnDescriptors(); 2588 int valid = updated->NumberOfOwnDescriptors();
2739 2589
2740 // Directly change the map if the target map is more general. Ensure that the 2590 // Directly change the map if the target map is more general. Ensure that the
2741 // target type of the modify_index is a FIELD, unless we are migrating. 2591 // target type of the modify_index is a FIELD, unless we are migrating.
2742 if (updated_descriptors->IsMoreGeneralThan( 2592 if (updated_descriptors->IsMoreGeneralThan(
2743 verbatim, valid, descriptors, *old_descriptors) && 2593 verbatim, valid, descriptors, *old_descriptors) &&
2744 (store_mode == ALLOW_AS_CONSTANT || 2594 (store_mode == ALLOW_AS_CONSTANT ||
2745 updated_descriptors->GetDetails(modify_index).type() == FIELD)) { 2595 updated_descriptors->GetDetails(modify_index).type() == FIELD)) {
2746 Representation updated_representation = 2596 Representation updated_representation =
2747 updated_descriptors->GetDetails(modify_index).representation(); 2597 updated_descriptors->GetDetails(modify_index).representation();
2748 if (new_representation.fits_into(updated_representation)) return updated; 2598 if (new_representation.fits_into(updated_representation)) return updated;
2749 } 2599 }
2750 2600
2751 Handle<DescriptorArray> new_descriptors = DescriptorArray::Merge( 2601 Handle<DescriptorArray> new_descriptors = DescriptorArray::Merge(
2752 updated, verbatim, valid, descriptors, modify_index, 2602 updated, verbatim, valid, descriptors, modify_index,
2753 store_mode, old_map); 2603 store_mode, old_map);
2754 ASSERT(store_mode == ALLOW_AS_CONSTANT || 2604 ASSERT(store_mode == ALLOW_AS_CONSTANT ||
2755 new_descriptors->GetDetails(modify_index).type() == FIELD); 2605 new_descriptors->GetDetails(modify_index).type() == FIELD);
2756 2606
2757 Isolate* isolate = new_descriptors->GetIsolate();
2758 old_representation = 2607 old_representation =
2759 new_descriptors->GetDetails(modify_index).representation(); 2608 new_descriptors->GetDetails(modify_index).representation();
2760 Representation updated_representation = 2609 Representation updated_representation =
2761 new_representation.generalize(old_representation); 2610 new_representation.generalize(old_representation);
2762 if (!updated_representation.Equals(old_representation)) { 2611 if (!updated_representation.Equals(old_representation)) {
2763 new_descriptors->SetRepresentation(modify_index, updated_representation); 2612 new_descriptors->SetRepresentation(modify_index, updated_representation);
2764 } 2613 }
2765 if (new_descriptors->GetDetails(modify_index).type() == FIELD) {
2766 Handle<HeapType> field_type(
2767 new_descriptors->GetFieldType(modify_index), isolate);
2768 new_field_type = Map::GeneralizeFieldType(
2769 field_type, new_field_type, isolate);
2770 new_descriptors->SetValue(modify_index, *new_field_type);
2771 }
2772 2614
2773 Handle<Map> split_map(root_map->FindLastMatchMap( 2615 Handle<Map> split_map(root_map->FindLastMatchMap(
2774 verbatim, descriptors, *new_descriptors)); 2616 verbatim, descriptors, *new_descriptors));
2775 2617
2776 int split_descriptors = split_map->NumberOfOwnDescriptors(); 2618 int split_descriptors = split_map->NumberOfOwnDescriptors();
2777 // This is shadowed by |updated_descriptors| being more general than 2619 // This is shadowed by |updated_descriptors| being more general than
2778 // |old_descriptors|. 2620 // |old_descriptors|.
2779 ASSERT(descriptors != split_descriptors); 2621 ASSERT(descriptors != split_descriptors);
2780 2622
2781 int descriptor = split_descriptors; 2623 int descriptor = split_descriptors;
2782 split_map->DeprecateTarget( 2624 split_map->DeprecateTarget(
2783 old_descriptors->GetKey(descriptor), *new_descriptors); 2625 old_descriptors->GetKey(descriptor), *new_descriptors);
2784 2626
2785 if (FLAG_trace_generalization) { 2627 if (FLAG_trace_generalization) {
2786 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2787 PropertyDetails new_details = new_descriptors->GetDetails(modify_index);
2788 Handle<HeapType> old_field_type = (old_details.type() == FIELD)
2789 ? handle(old_descriptors->GetFieldType(modify_index), isolate)
2790 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index),
2791 isolate), isolate);
2792 Handle<HeapType> new_field_type = (new_details.type() == FIELD)
2793 ? handle(new_descriptors->GetFieldType(modify_index), isolate)
2794 : HeapType::Constant(handle(new_descriptors->GetValue(modify_index),
2795 isolate), isolate);
2796 old_map->PrintGeneralization( 2628 old_map->PrintGeneralization(
2797 stdout, "", modify_index, descriptor, descriptors, 2629 stdout, "", modify_index, descriptor, descriptors,
2798 old_details.type() == CONSTANT && store_mode == FORCE_FIELD, 2630 old_descriptors->GetDetails(modify_index).type() == CONSTANT &&
2799 old_details.representation(), new_details.representation(), 2631 store_mode == FORCE_FIELD,
2800 *old_field_type, *new_field_type); 2632 old_representation, updated_representation);
2801 } 2633 }
2802 2634
2803 // Add missing transitions. 2635 // Add missing transitions.
2804 Handle<Map> new_map = split_map; 2636 Handle<Map> new_map = split_map;
2805 for (; descriptor < descriptors; descriptor++) { 2637 for (; descriptor < descriptors; descriptor++) {
2806 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors); 2638 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors);
2807 } 2639 }
2808 2640
2809 new_map->set_owns_descriptors(true); 2641 new_map->set_owns_descriptors(true);
2810 return new_map; 2642 return new_map;
2811 } 2643 }
2812 2644
2813 2645
2814 // Generalize the representation of all FIELD descriptors. 2646 // Generalize the representation of all FIELD descriptors.
2815 Handle<Map> Map::GeneralizeAllFieldRepresentations( 2647 Handle<Map> Map::GeneralizeAllFieldRepresentations(
2816 Handle<Map> map) { 2648 Handle<Map> map,
2649 Representation new_representation) {
2817 Handle<DescriptorArray> descriptors(map->instance_descriptors()); 2650 Handle<DescriptorArray> descriptors(map->instance_descriptors());
2818 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { 2651 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
2819 if (descriptors->GetDetails(i).type() == FIELD) { 2652 PropertyDetails details = descriptors->GetDetails(i);
2820 map = GeneralizeRepresentation(map, i, Representation::Tagged(), 2653 if (details.type() == FIELD) {
2821 HeapType::Any(map->GetIsolate()), 2654 map = GeneralizeRepresentation(map, i, new_representation, FORCE_FIELD);
2822 FORCE_FIELD);
2823 } 2655 }
2824 } 2656 }
2825 return map; 2657 return map;
2826 } 2658 }
2827 2659
2828 2660
2829 Handle<Map> Map::CurrentMapForDeprecated(Handle<Map> map) { 2661 Handle<Map> Map::CurrentMapForDeprecated(Handle<Map> map) {
2830 Handle<Map> proto_map(map); 2662 Handle<Map> proto_map(map);
2831 while (proto_map->prototype()->IsJSObject()) { 2663 while (proto_map->prototype()->IsJSObject()) {
2832 Handle<JSObject> holder(JSObject::cast(proto_map->prototype())); 2664 Handle<JSObject> holder(JSObject::cast(proto_map->prototype()));
(...skipping 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after
3951 JSObject::MigrateToMap(object, map); 3783 JSObject::MigrateToMap(object, map);
3952 } 3784 }
3953 3785
3954 3786
3955 void JSObject::MigrateInstance(Handle<JSObject> object) { 3787 void JSObject::MigrateInstance(Handle<JSObject> object) {
3956 // Converting any field to the most specific type will cause the 3788 // Converting any field to the most specific type will cause the
3957 // GeneralizeFieldRepresentation algorithm to create the most general existing 3789 // GeneralizeFieldRepresentation algorithm to create the most general existing
3958 // transition that matches the object. This achieves what is needed. 3790 // transition that matches the object. This achieves what is needed.
3959 Handle<Map> original_map(object->map()); 3791 Handle<Map> original_map(object->map());
3960 GeneralizeFieldRepresentation( 3792 GeneralizeFieldRepresentation(
3961 object, 0, Representation::None(), 3793 object, 0, Representation::None(), ALLOW_AS_CONSTANT);
3962 HeapType::None(object->GetIsolate()),
3963 ALLOW_AS_CONSTANT);
3964 object->map()->set_migration_target(true); 3794 object->map()->set_migration_target(true);
3965 if (FLAG_trace_migration) { 3795 if (FLAG_trace_migration) {
3966 object->PrintInstanceMigration(stdout, *original_map, object->map()); 3796 object->PrintInstanceMigration(stdout, *original_map, object->map());
3967 } 3797 }
3968 } 3798 }
3969 3799
3970 3800
3971 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { 3801 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) {
3972 Handle<Map> original_map(object->map()); 3802 Handle<Map> original_map(object->map());
3973 Handle<Map> new_map = Map::CurrentMapForDeprecatedInternal(original_map); 3803 Handle<Map> new_map = Map::CurrentMapForDeprecatedInternal(original_map);
3974 if (new_map.is_null()) return Handle<Object>(); 3804 if (new_map.is_null()) return Handle<Object>();
3975 JSObject::MigrateToMap(object, new_map); 3805 JSObject::MigrateToMap(object, new_map);
3976 if (FLAG_trace_migration) { 3806 if (FLAG_trace_migration) {
3977 object->PrintInstanceMigration(stdout, *original_map, object->map()); 3807 object->PrintInstanceMigration(stdout, *original_map, object->map());
3978 } 3808 }
3979 return object; 3809 return object;
3980 } 3810 }
3981 3811
3982 3812
3983 MaybeHandle<Object> JSObject::SetPropertyUsingTransition( 3813 MaybeHandle<Object> JSObject::SetPropertyUsingTransition(
3984 Handle<JSObject> object, 3814 Handle<JSObject> object,
3985 LookupResult* lookup, 3815 LookupResult* lookup,
3986 Handle<Name> name, 3816 Handle<Name> name,
3987 Handle<Object> value, 3817 Handle<Object> value,
3988 PropertyAttributes attributes) { 3818 PropertyAttributes attributes) {
3989 Handle<Map> transition_map(lookup->GetTransitionTarget()); 3819 Handle<Map> transition_map(lookup->GetTransitionTarget());
3990 int descriptor = transition_map->LastAdded(); 3820 int descriptor = transition_map->LastAdded();
3991 3821
3992 Handle<DescriptorArray> descriptors(transition_map->instance_descriptors()); 3822 DescriptorArray* descriptors = transition_map->instance_descriptors();
3993 PropertyDetails details = descriptors->GetDetails(descriptor); 3823 PropertyDetails details = descriptors->GetDetails(descriptor);
3994 3824
3995 if (details.type() == CALLBACKS || attributes != details.attributes()) { 3825 if (details.type() == CALLBACKS || attributes != details.attributes()) {
3996 // AddProperty will either normalize the object, or create a new fast copy 3826 // AddProperty will either normalize the object, or create a new fast copy
3997 // of the map. If we get a fast copy of the map, all field representations 3827 // of the map. If we get a fast copy of the map, all field representations
3998 // will be tagged since the transition is omitted. 3828 // will be tagged since the transition is omitted.
3999 return JSObject::AddProperty( 3829 return JSObject::AddProperty(
4000 object, name, value, attributes, SLOPPY, 3830 object, name, value, attributes, SLOPPY,
4001 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, 3831 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED,
4002 JSReceiver::OMIT_EXTENSIBILITY_CHECK, 3832 JSReceiver::OMIT_EXTENSIBILITY_CHECK,
4003 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); 3833 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION);
4004 } 3834 }
4005 3835
4006 // Keep the target CONSTANT if the same value is stored. 3836 // Keep the target CONSTANT if the same value is stored.
4007 // TODO(verwaest): Also support keeping the placeholder 3837 // TODO(verwaest): Also support keeping the placeholder
4008 // (value->IsUninitialized) as constant. 3838 // (value->IsUninitialized) as constant.
4009 if (!lookup->CanHoldValue(value)) { 3839 if (!lookup->CanHoldValue(value) ||
4010 Representation field_representation = value->OptimalRepresentation(); 3840 (details.type() == CONSTANT &&
4011 Handle<HeapType> field_type = value->OptimalType( 3841 descriptors->GetValue(descriptor) != *value)) {
4012 lookup->isolate(), field_representation); 3842 transition_map = Map::GeneralizeRepresentation(transition_map,
4013 transition_map = Map::GeneralizeRepresentation( 3843 descriptor, value->OptimalRepresentation(), FORCE_FIELD);
4014 transition_map, descriptor,
4015 field_representation, field_type, FORCE_FIELD);
4016 } 3844 }
4017 3845
4018 JSObject::MigrateToMap(object, transition_map); 3846 JSObject::MigrateToMap(object, transition_map);
4019 3847
4020 // Reload. 3848 // Reload.
4021 descriptors = handle(transition_map->instance_descriptors()); 3849 descriptors = transition_map->instance_descriptors();
4022 details = descriptors->GetDetails(descriptor); 3850 details = descriptors->GetDetails(descriptor);
4023 3851
4024 if (details.type() != FIELD) return value; 3852 if (details.type() != FIELD) return value;
4025 3853
4026 int field_index = descriptors->GetFieldIndex(descriptor); 3854 int field_index = descriptors->GetFieldIndex(descriptor);
4027 if (details.representation().IsDouble()) { 3855 if (details.representation().IsDouble()) {
4028 // Nothing more to be done. 3856 // Nothing more to be done.
4029 if (value->IsUninitialized()) return value; 3857 if (value->IsUninitialized()) return value;
4030 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index)); 3858 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index));
4031 box->set_value(value->Number()); 3859 box->set_value(value->Number());
4032 } else { 3860 } else {
4033 object->FastPropertyAtPut(field_index, *value); 3861 object->FastPropertyAtPut(field_index, *value);
4034 } 3862 }
4035 3863
4036 return value; 3864 return value;
4037 } 3865 }
4038 3866
4039 3867
4040 static void SetPropertyToField(LookupResult* lookup, 3868 static void SetPropertyToField(LookupResult* lookup,
4041 Handle<Object> value) { 3869 Handle<Object> value) {
4042 Representation representation = lookup->representation(); 3870 Representation representation = lookup->representation();
4043 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { 3871 if (!lookup->CanHoldValue(value) ||
4044 Representation field_representation = value->OptimalRepresentation(); 3872 lookup->type() == CONSTANT) {
4045 Handle<HeapType> field_type = value->OptimalType(
4046 lookup->isolate(), field_representation);
4047 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), 3873 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()),
4048 lookup->GetDescriptorIndex(), 3874 lookup->GetDescriptorIndex(),
4049 field_representation, field_type, 3875 value->OptimalRepresentation(),
4050 FORCE_FIELD); 3876 FORCE_FIELD);
4051 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); 3877 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
4052 int descriptor = lookup->GetDescriptorIndex(); 3878 int descriptor = lookup->GetDescriptorIndex();
4053 representation = desc->GetDetails(descriptor).representation(); 3879 representation = desc->GetDetails(descriptor).representation();
4054 } 3880 }
4055 3881
4056 if (representation.IsDouble()) { 3882 if (representation.IsDouble()) {
4057 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( 3883 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
4058 lookup->GetFieldIndex().field_index())); 3884 lookup->GetFieldIndex().field_index()));
4059 storage->set_value(value->Number()); 3885 storage->set_value(value->Number());
(...skipping 15 matching lines...) Expand all
4075 } 3901 }
4076 3902
4077 if (!object->HasFastProperties()) { 3903 if (!object->HasFastProperties()) {
4078 ReplaceSlowProperty(object, name, value, attributes); 3904 ReplaceSlowProperty(object, name, value, attributes);
4079 return; 3905 return;
4080 } 3906 }
4081 3907
4082 int descriptor_index = lookup->GetDescriptorIndex(); 3908 int descriptor_index = lookup->GetDescriptorIndex();
4083 if (lookup->GetAttributes() == attributes) { 3909 if (lookup->GetAttributes() == attributes) {
4084 JSObject::GeneralizeFieldRepresentation( 3910 JSObject::GeneralizeFieldRepresentation(
4085 object, descriptor_index, Representation::Tagged(), 3911 object, descriptor_index, Representation::Tagged(), FORCE_FIELD);
4086 HeapType::Any(lookup->isolate()), FORCE_FIELD);
4087 } else { 3912 } else {
4088 Handle<Map> old_map(object->map()); 3913 Handle<Map> old_map(object->map());
4089 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, 3914 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map,
4090 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); 3915 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch");
4091 JSObject::MigrateToMap(object, new_map); 3916 JSObject::MigrateToMap(object, new_map);
4092 } 3917 }
4093 3918
4094 DescriptorArray* descriptors = object->map()->instance_descriptors(); 3919 DescriptorArray* descriptors = object->map()->instance_descriptors();
4095 int index = descriptors->GetDetails(descriptor_index).field_index(); 3920 int index = descriptors->GetDetails(descriptor_index).field_index();
4096 object->FastPropertyAtPut(index, *value); 3921 object->FastPropertyAtPut(index, *value);
(...skipping 2967 matching lines...) Expand 10 before | Expand all | Expand 10 after
7064 6889
7065 Handle<Map> result = CopyDropDescriptors(map); 6890 Handle<Map> result = CopyDropDescriptors(map);
7066 result->InitializeDescriptors(*descriptors); 6891 result->InitializeDescriptors(*descriptors);
7067 6892
7068 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { 6893 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) {
7069 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( 6894 Handle<TransitionArray> transitions = TransitionArray::CopyInsert(
7070 map, name, result, simple_flag); 6895 map, name, result, simple_flag);
7071 map->set_transitions(*transitions); 6896 map->set_transitions(*transitions);
7072 result->SetBackPointer(*map); 6897 result->SetBackPointer(*map);
7073 } else { 6898 } else {
7074 int length = descriptors->number_of_descriptors(); 6899 descriptors->InitializeRepresentations(Representation::Tagged());
7075 for (int i = 0; i < length; i++) {
7076 descriptors->SetRepresentation(i, Representation::Tagged());
7077 if (descriptors->GetDetails(i).type() == FIELD) {
7078 descriptors->SetValue(i, HeapType::Any());
7079 }
7080 }
7081 } 6900 }
7082 6901
7083 return result; 6902 return result;
7084 } 6903 }
7085 6904
7086 6905
7087 // Since this method is used to rewrite an existing transition tree, it can 6906 // Since this method is used to rewrite an existing transition tree, it can
7088 // always insert transitions without checking. 6907 // always insert transitions without checking.
7089 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, 6908 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
7090 int new_descriptor, 6909 int new_descriptor,
(...skipping 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after
8259 8078
8260 // |verbatim| -> |valid| 8079 // |verbatim| -> |valid|
8261 for (; descriptor < valid; descriptor++) { 8080 for (; descriptor < valid; descriptor++) {
8262 PropertyDetails left_details = left->GetDetails(descriptor); 8081 PropertyDetails left_details = left->GetDetails(descriptor);
8263 PropertyDetails right_details = right->GetDetails(descriptor); 8082 PropertyDetails right_details = right->GetDetails(descriptor);
8264 if (left_details.type() == FIELD || right_details.type() == FIELD || 8083 if (left_details.type() == FIELD || right_details.type() == FIELD ||
8265 (store_mode == FORCE_FIELD && descriptor == modify_index) || 8084 (store_mode == FORCE_FIELD && descriptor == modify_index) ||
8266 (left_details.type() == CONSTANT && 8085 (left_details.type() == CONSTANT &&
8267 right_details.type() == CONSTANT && 8086 right_details.type() == CONSTANT &&
8268 left->GetValue(descriptor) != right->GetValue(descriptor))) { 8087 left->GetValue(descriptor) != right->GetValue(descriptor))) {
8269 ASSERT(left_details.type() == CONSTANT || left_details.type() == FIELD);
8270 ASSERT(right_details.type() == CONSTANT || right_details.type() == FIELD);
8271 Representation representation = left_details.representation().generalize( 8088 Representation representation = left_details.representation().generalize(
8272 right_details.representation()); 8089 right_details.representation());
8273 Handle<HeapType> left_type = (left_details.type() == FIELD) 8090 FieldDescriptor d(handle(left->GetKey(descriptor)),
8274 ? handle(left->GetFieldType(descriptor), isolate)
8275 : left->GetValue(descriptor)->OptimalType(isolate, representation);
8276 Handle<HeapType> right_type = (right_details.type() == FIELD)
8277 ? handle(right->GetFieldType(descriptor), isolate)
8278 : right->GetValue(descriptor)->OptimalType(isolate, representation);
8279 Handle<HeapType> field_type = Map::GeneralizeFieldType(
8280 left_type, right_type, isolate);
8281 FieldDescriptor d(handle(left->GetKey(descriptor), isolate),
8282 current_offset++, 8091 current_offset++,
8283 field_type,
8284 right_details.attributes(), 8092 right_details.attributes(),
8285 representation); 8093 representation);
8286 result->Set(descriptor, &d); 8094 result->Set(descriptor, &d);
8287 } else { 8095 } else {
8288 Descriptor d(handle(right->GetKey(descriptor), isolate), 8096 Descriptor d(handle(right->GetKey(descriptor)),
8289 handle(right->GetValue(descriptor), isolate), 8097 handle(right->GetValue(descriptor), right->GetIsolate()),
8290 right_details); 8098 right_details);
8291 result->Set(descriptor, &d); 8099 result->Set(descriptor, &d);
8292 } 8100 }
8293 } 8101 }
8294 8102
8295 // |valid| -> |new_size| 8103 // |valid| -> |new_size|
8296 for (; descriptor < new_size; descriptor++) { 8104 for (; descriptor < new_size; descriptor++) {
8297 PropertyDetails right_details = right->GetDetails(descriptor); 8105 PropertyDetails right_details = right->GetDetails(descriptor);
8298 if (right_details.type() == FIELD) { 8106 if (right_details.type() == FIELD ||
8299 FieldDescriptor d(handle(right->GetKey(descriptor), isolate), 8107 (store_mode == FORCE_FIELD && descriptor == modify_index)) {
8108 FieldDescriptor d(handle(right->GetKey(descriptor)),
8300 current_offset++, 8109 current_offset++,
8301 handle(right->GetFieldType(descriptor), isolate),
8302 right_details.attributes(), 8110 right_details.attributes(),
8303 right_details.representation()); 8111 right_details.representation());
8304 result->Set(descriptor, &d); 8112 result->Set(descriptor, &d);
8305 } else if (store_mode == FORCE_FIELD && descriptor == modify_index) {
8306 ASSERT_EQ(CONSTANT, right_details.type());
8307 Representation field_representation = right_details.representation();
8308 Handle<HeapType> field_type = right->GetValue(descriptor)->OptimalType(
8309 isolate, field_representation);
8310 FieldDescriptor d(handle(right->GetKey(descriptor), isolate),
8311 current_offset++,
8312 field_type,
8313 right_details.attributes(),
8314 field_representation);
8315 result->Set(descriptor, &d);
8316 } else { 8113 } else {
8317 Descriptor d(handle(right->GetKey(descriptor), isolate), 8114 Descriptor d(handle(right->GetKey(descriptor)),
8318 handle(right->GetValue(descriptor), isolate), 8115 handle(right->GetValue(descriptor), right->GetIsolate()),
8319 right_details); 8116 right_details);
8320 result->Set(descriptor, &d); 8117 result->Set(descriptor, &d);
8321 } 8118 }
8322 } 8119 }
8323 8120
8324 result->Sort(); 8121 result->Sort();
8325 return result; 8122 return result;
8326 } 8123 }
8327 8124
8328 8125
(...skipping 8391 matching lines...) Expand 10 before | Expand all | Expand 10 after
16720 #define ERROR_MESSAGES_TEXTS(C, T) T, 16517 #define ERROR_MESSAGES_TEXTS(C, T) T,
16721 static const char* error_messages_[] = { 16518 static const char* error_messages_[] = {
16722 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16519 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16723 }; 16520 };
16724 #undef ERROR_MESSAGES_TEXTS 16521 #undef ERROR_MESSAGES_TEXTS
16725 return error_messages_[reason]; 16522 return error_messages_[reason];
16726 } 16523 }
16727 16524
16728 16525
16729 } } // namespace v8::internal 16526 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698