OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 Object* result; | 66 Object* result; |
67 { MaybeObject* maybe_result = | 67 { MaybeObject* maybe_result = |
68 constructor->GetHeap()->AllocateJSObject(constructor); | 68 constructor->GetHeap()->AllocateJSObject(constructor); |
69 if (!maybe_result->ToObject(&result)) return maybe_result; | 69 if (!maybe_result->ToObject(&result)) return maybe_result; |
70 } | 70 } |
71 JSValue::cast(result)->set_value(value); | 71 JSValue::cast(result)->set_value(value); |
72 return result; | 72 return result; |
73 } | 73 } |
74 | 74 |
75 | 75 |
| 76 Handle<HeapType> Object::OptimalType(Isolate* isolate, |
| 77 Representation representation) { |
| 78 if (!FLAG_track_field_types) return HeapType::Any(isolate); |
| 79 if (representation.IsNone()) return HeapType::None(isolate); |
| 80 if (representation.IsHeapObject() && IsHeapObject()) { |
| 81 // We can track only JavaScript objects with stable maps. |
| 82 Handle<Map> map(HeapObject::cast(this)->map(), isolate); |
| 83 if (map->is_stable() && |
| 84 map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE && |
| 85 map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE) { |
| 86 return HeapType::Class(map, isolate); |
| 87 } |
| 88 } |
| 89 return HeapType::Any(isolate); |
| 90 } |
| 91 |
| 92 |
76 MaybeObject* Object::ToObject(Context* native_context) { | 93 MaybeObject* Object::ToObject(Context* native_context) { |
77 if (IsNumber()) { | 94 if (IsNumber()) { |
78 return CreateJSValue(native_context->number_function(), this); | 95 return CreateJSValue(native_context->number_function(), this); |
79 } else if (IsBoolean()) { | 96 } else if (IsBoolean()) { |
80 return CreateJSValue(native_context->boolean_function(), this); | 97 return CreateJSValue(native_context->boolean_function(), this); |
81 } else if (IsString()) { | 98 } else if (IsString()) { |
82 return CreateJSValue(native_context->string_function(), this); | 99 return CreateJSValue(native_context->string_function(), this); |
83 } else if (IsSymbol()) { | 100 } else if (IsSymbol()) { |
84 return CreateJSValue(native_context->symbol_function(), this); | 101 return CreateJSValue(native_context->symbol_function(), this); |
85 } | 102 } |
(...skipping 1354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |