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

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