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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 #include "utils.h" | 53 #include "utils.h" |
54 | 54 |
55 #ifdef ENABLE_DISASSEMBLER | 55 #ifdef ENABLE_DISASSEMBLER |
56 #include "disasm.h" | 56 #include "disasm.h" |
57 #include "disassembler.h" | 57 #include "disassembler.h" |
58 #endif | 58 #endif |
59 | 59 |
60 namespace v8 { | 60 namespace v8 { |
61 namespace internal { | 61 namespace internal { |
62 | 62 |
| 63 Handle<HeapType> Object::OptimalType(Isolate* isolate, |
| 64 Representation representation) { |
| 65 if (!FLAG_track_field_types) return HeapType::Any(isolate); |
| 66 if (representation.IsNone()) return HeapType::None(isolate); |
| 67 if (representation.IsHeapObject() && IsHeapObject()) { |
| 68 // We can track only JavaScript objects with stable maps. |
| 69 Handle<Map> map(HeapObject::cast(this)->map(), isolate); |
| 70 if (map->is_stable() && |
| 71 map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE && |
| 72 map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE) { |
| 73 return HeapType::Class(map, isolate); |
| 74 } |
| 75 } |
| 76 return HeapType::Any(isolate); |
| 77 } |
| 78 |
| 79 |
63 MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate, | 80 MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate, |
64 Handle<Object> object, | 81 Handle<Object> object, |
65 Handle<Context> native_context) { | 82 Handle<Context> native_context) { |
66 if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object); | 83 if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object); |
67 Handle<JSFunction> constructor; | 84 Handle<JSFunction> constructor; |
68 if (object->IsNumber()) { | 85 if (object->IsNumber()) { |
69 constructor = handle(native_context->number_function(), isolate); | 86 constructor = handle(native_context->number_function(), isolate); |
70 } else if (object->IsBoolean()) { | 87 } else if (object->IsBoolean()) { |
71 constructor = handle(native_context->boolean_function(), isolate); | 88 constructor = handle(native_context->boolean_function(), isolate); |
72 } else if (object->IsString()) { | 89 } else if (object->IsString()) { |
(...skipping 1322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1395 } | 1412 } |
1396 | 1413 |
1397 | 1414 |
1398 void Map::PrintGeneralization(FILE* file, | 1415 void Map::PrintGeneralization(FILE* file, |
1399 const char* reason, | 1416 const char* reason, |
1400 int modify_index, | 1417 int modify_index, |
1401 int split, | 1418 int split, |
1402 int descriptors, | 1419 int descriptors, |
1403 bool constant_to_field, | 1420 bool constant_to_field, |
1404 Representation old_representation, | 1421 Representation old_representation, |
1405 Representation new_representation) { | 1422 Representation new_representation, |
| 1423 HeapType* old_field_type, |
| 1424 HeapType* new_field_type) { |
1406 PrintF(file, "[generalizing "); | 1425 PrintF(file, "[generalizing "); |
1407 constructor_name()->PrintOn(file); | 1426 constructor_name()->PrintOn(file); |
1408 PrintF(file, "] "); | 1427 PrintF(file, "] "); |
1409 Name* name = instance_descriptors()->GetKey(modify_index); | 1428 Name* name = instance_descriptors()->GetKey(modify_index); |
1410 if (name->IsString()) { | 1429 if (name->IsString()) { |
1411 String::cast(name)->PrintOn(file); | 1430 String::cast(name)->PrintOn(file); |
1412 } else { | 1431 } else { |
1413 PrintF(file, "{symbol %p}", static_cast<void*>(name)); | 1432 PrintF(file, "{symbol %p}", static_cast<void*>(name)); |
1414 } | 1433 } |
| 1434 PrintF(file, ":"); |
1415 if (constant_to_field) { | 1435 if (constant_to_field) { |
1416 PrintF(file, ":c->f"); | 1436 PrintF(file, "c"); |
1417 } else { | 1437 } else { |
1418 PrintF(file, ":%s->%s", | 1438 PrintF(file, "%s", old_representation.Mnemonic()); |
1419 old_representation.Mnemonic(), | 1439 PrintF(file, "{"); |
1420 new_representation.Mnemonic()); | 1440 old_field_type->TypePrint(file, HeapType::SEMANTIC_DIM); |
| 1441 PrintF(file, "}"); |
1421 } | 1442 } |
| 1443 PrintF(file, "->%s", new_representation.Mnemonic()); |
| 1444 PrintF(file, "{"); |
| 1445 new_field_type->TypePrint(file, HeapType::SEMANTIC_DIM); |
| 1446 PrintF(file, "}"); |
1422 PrintF(file, " ("); | 1447 PrintF(file, " ("); |
1423 if (strlen(reason) > 0) { | 1448 if (strlen(reason) > 0) { |
1424 PrintF(file, "%s", reason); | 1449 PrintF(file, "%s", reason); |
1425 } else { | 1450 } else { |
1426 PrintF(file, "+%i maps", descriptors - split); | 1451 PrintF(file, "+%i maps", descriptors - split); |
1427 } | 1452 } |
1428 PrintF(file, ") ["); | 1453 PrintF(file, ") ["); |
1429 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); | 1454 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); |
1430 PrintF(file, "]\n"); | 1455 PrintF(file, "]\n"); |
1431 } | 1456 } |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1830 return; | 1855 return; |
1831 } | 1856 } |
1832 | 1857 |
1833 // Allocate new instance descriptors with (name, index) added | 1858 // Allocate new instance descriptors with (name, index) added |
1834 if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED; | 1859 if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED; |
1835 Representation representation = value->OptimalRepresentation(value_type); | 1860 Representation representation = value->OptimalRepresentation(value_type); |
1836 | 1861 |
1837 // Compute the new index for new field. | 1862 // Compute the new index for new field. |
1838 int index = object->map()->NextFreePropertyIndex(); | 1863 int index = object->map()->NextFreePropertyIndex(); |
1839 | 1864 |
1840 FieldDescriptor new_field_desc(name, index, attributes, representation); | 1865 Handle<HeapType> type = value->OptimalType(isolate, representation); |
| 1866 FieldDescriptor new_field_desc(name, index, type, attributes, representation); |
1841 Handle<Map> new_map = Map::CopyAddDescriptor( | 1867 Handle<Map> new_map = Map::CopyAddDescriptor( |
1842 handle(object->map()), &new_field_desc, flag); | 1868 handle(object->map()), &new_field_desc, flag); |
1843 int unused_property_fields = new_map->unused_property_fields() - 1; | 1869 int unused_property_fields = new_map->unused_property_fields() - 1; |
1844 if (unused_property_fields < 0) { | 1870 if (unused_property_fields < 0) { |
1845 unused_property_fields += JSObject::kFieldsAdded; | 1871 unused_property_fields += JSObject::kFieldsAdded; |
1846 } | 1872 } |
1847 new_map->set_unused_property_fields(unused_property_fields); | 1873 new_map->set_unused_property_fields(unused_property_fields); |
1848 | 1874 |
1849 JSObject::MigrateToMap(object, new_map); | 1875 JSObject::MigrateToMap(object, new_map); |
1850 | 1876 |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2222 } | 2248 } |
2223 ASSERT(!(details.representation().IsDouble() && value->IsSmi())); | 2249 ASSERT(!(details.representation().IsDouble() && value->IsSmi())); |
2224 int target_index = new_descriptors->GetFieldIndex(i) - inobject; | 2250 int target_index = new_descriptors->GetFieldIndex(i) - inobject; |
2225 if (target_index < 0) target_index += total_size; | 2251 if (target_index < 0) target_index += total_size; |
2226 array->set(target_index, *value); | 2252 array->set(target_index, *value); |
2227 } | 2253 } |
2228 | 2254 |
2229 for (int i = old_nof; i < new_nof; i++) { | 2255 for (int i = old_nof; i < new_nof; i++) { |
2230 PropertyDetails details = new_descriptors->GetDetails(i); | 2256 PropertyDetails details = new_descriptors->GetDetails(i); |
2231 if (details.type() != FIELD) continue; | 2257 if (details.type() != FIELD) continue; |
| 2258 Handle<Object> value; |
2232 if (details.representation().IsDouble()) { | 2259 if (details.representation().IsDouble()) { |
2233 int target_index = new_descriptors->GetFieldIndex(i) - inobject; | 2260 value = isolate->factory()->NewHeapNumber(0); |
2234 if (target_index < 0) target_index += total_size; | 2261 } else { |
2235 Handle<Object> box = isolate->factory()->NewHeapNumber(0); | 2262 value = isolate->factory()->uninitialized_value(); |
2236 array->set(target_index, *box); | |
2237 } | 2263 } |
| 2264 int target_index = new_descriptors->GetFieldIndex(i) - inobject; |
| 2265 if (target_index < 0) target_index += total_size; |
| 2266 array->set(target_index, *value); |
2238 } | 2267 } |
2239 | 2268 |
2240 // From here on we cannot fail and we shouldn't GC anymore. | 2269 // From here on we cannot fail and we shouldn't GC anymore. |
2241 DisallowHeapAllocation no_allocation; | 2270 DisallowHeapAllocation no_allocation; |
2242 | 2271 |
2243 // Copy (real) inobject properties. If necessary, stop at number_of_fields to | 2272 // Copy (real) inobject properties. If necessary, stop at number_of_fields to |
2244 // avoid overwriting |one_pointer_filler_map|. | 2273 // avoid overwriting |one_pointer_filler_map|. |
2245 int limit = Min(inobject, number_of_fields); | 2274 int limit = Min(inobject, number_of_fields); |
2246 for (int i = 0; i < limit; i++) { | 2275 for (int i = 0; i < limit; i++) { |
2247 object->FastPropertyAtPut(i, array->get(external + i)); | 2276 object->FastPropertyAtPut(i, array->get(external + i)); |
(...skipping 22 matching lines...) Expand all Loading... |
2270 // fresly allocated page or on an already swept page. Hence, the sweeper | 2299 // fresly allocated page or on an already swept page. Hence, the sweeper |
2271 // thread can not get confused with the filler creation. No synchronization | 2300 // thread can not get confused with the filler creation. No synchronization |
2272 // needed. | 2301 // needed. |
2273 object->set_map(*new_map); | 2302 object->set_map(*new_map); |
2274 } | 2303 } |
2275 | 2304 |
2276 | 2305 |
2277 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, | 2306 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, |
2278 int modify_index, | 2307 int modify_index, |
2279 Representation new_representation, | 2308 Representation new_representation, |
| 2309 Handle<HeapType> new_field_type, |
2280 StoreMode store_mode) { | 2310 StoreMode store_mode) { |
2281 Handle<Map> new_map = Map::GeneralizeRepresentation( | 2311 Handle<Map> new_map = Map::GeneralizeRepresentation( |
2282 handle(object->map()), modify_index, new_representation, store_mode); | 2312 handle(object->map()), modify_index, new_representation, |
| 2313 new_field_type, store_mode); |
2283 if (object->map() == *new_map) return; | 2314 if (object->map() == *new_map) return; |
2284 return MigrateToMap(object, new_map); | 2315 return MigrateToMap(object, new_map); |
2285 } | 2316 } |
2286 | 2317 |
2287 | 2318 |
2288 int Map::NumberOfFields() { | 2319 int Map::NumberOfFields() { |
2289 DescriptorArray* descriptors = instance_descriptors(); | 2320 DescriptorArray* descriptors = instance_descriptors(); |
2290 int result = 0; | 2321 int result = 0; |
2291 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { | 2322 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { |
2292 if (descriptors->GetDetails(i).type() == FIELD) result++; | 2323 if (descriptors->GetDetails(i).type() == FIELD) result++; |
2293 } | 2324 } |
2294 return result; | 2325 return result; |
2295 } | 2326 } |
2296 | 2327 |
2297 | 2328 |
2298 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, | 2329 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, |
2299 int modify_index, | 2330 int modify_index, |
2300 StoreMode store_mode, | 2331 StoreMode store_mode, |
2301 PropertyAttributes attributes, | 2332 PropertyAttributes attributes, |
2302 const char* reason) { | 2333 const char* reason) { |
| 2334 Isolate* isolate = map->GetIsolate(); |
2303 Handle<Map> new_map = Copy(map); | 2335 Handle<Map> new_map = Copy(map); |
2304 | 2336 |
2305 DescriptorArray* descriptors = new_map->instance_descriptors(); | 2337 DescriptorArray* descriptors = new_map->instance_descriptors(); |
2306 descriptors->InitializeRepresentations(Representation::Tagged()); | 2338 int length = descriptors->number_of_descriptors(); |
| 2339 for (int i = 0; i < length; i++) { |
| 2340 descriptors->SetRepresentation(i, Representation::Tagged()); |
| 2341 if (descriptors->GetDetails(i).type() == FIELD) { |
| 2342 descriptors->SetValue(i, HeapType::Any()); |
| 2343 } |
| 2344 } |
2307 | 2345 |
2308 // Unless the instance is being migrated, ensure that modify_index is a field. | 2346 // Unless the instance is being migrated, ensure that modify_index is a field. |
2309 PropertyDetails details = descriptors->GetDetails(modify_index); | 2347 PropertyDetails details = descriptors->GetDetails(modify_index); |
2310 if (store_mode == FORCE_FIELD && details.type() != FIELD) { | 2348 if (store_mode == FORCE_FIELD && details.type() != FIELD) { |
2311 FieldDescriptor d(handle(descriptors->GetKey(modify_index), | 2349 FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate), |
2312 map->GetIsolate()), | |
2313 new_map->NumberOfFields(), | 2350 new_map->NumberOfFields(), |
2314 attributes, | 2351 attributes, |
2315 Representation::Tagged()); | 2352 Representation::Tagged()); |
2316 descriptors->Replace(modify_index, &d); | 2353 descriptors->Replace(modify_index, &d); |
2317 int unused_property_fields = new_map->unused_property_fields() - 1; | 2354 int unused_property_fields = new_map->unused_property_fields() - 1; |
2318 if (unused_property_fields < 0) { | 2355 if (unused_property_fields < 0) { |
2319 unused_property_fields += JSObject::kFieldsAdded; | 2356 unused_property_fields += JSObject::kFieldsAdded; |
2320 } | 2357 } |
2321 new_map->set_unused_property_fields(unused_property_fields); | 2358 new_map->set_unused_property_fields(unused_property_fields); |
2322 } | 2359 } |
2323 | 2360 |
2324 if (FLAG_trace_generalization) { | 2361 if (FLAG_trace_generalization) { |
| 2362 HeapType* field_type = (details.type() == FIELD) |
| 2363 ? map->instance_descriptors()->GetFieldType(modify_index) |
| 2364 : NULL; |
2325 map->PrintGeneralization(stdout, reason, modify_index, | 2365 map->PrintGeneralization(stdout, reason, modify_index, |
2326 new_map->NumberOfOwnDescriptors(), | 2366 new_map->NumberOfOwnDescriptors(), |
2327 new_map->NumberOfOwnDescriptors(), | 2367 new_map->NumberOfOwnDescriptors(), |
2328 details.type() == CONSTANT && store_mode == FORCE_FIELD, | 2368 details.type() == CONSTANT && store_mode == FORCE_FIELD, |
2329 Representation::Tagged(), Representation::Tagged()); | 2369 details.representation(), Representation::Tagged(), |
| 2370 field_type, HeapType::Any()); |
2330 } | 2371 } |
2331 return new_map; | 2372 return new_map; |
2332 } | 2373 } |
2333 | 2374 |
2334 | 2375 |
2335 void Map::DeprecateTransitionTree() { | 2376 void Map::DeprecateTransitionTree() { |
2336 if (is_deprecated()) return; | 2377 if (is_deprecated()) return; |
2337 if (HasTransitionArray()) { | 2378 if (HasTransitionArray()) { |
2338 TransitionArray* transitions = this->transitions(); | 2379 TransitionArray* transitions = this->transitions(); |
2339 for (int i = 0; i < transitions->number_of_transitions(); i++) { | 2380 for (int i = 0; i < transitions->number_of_transitions(); i++) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2384 if (back->IsUndefined()) return result; | 2425 if (back->IsUndefined()) return result; |
2385 result = Map::cast(back); | 2426 result = Map::cast(back); |
2386 } | 2427 } |
2387 } | 2428 } |
2388 | 2429 |
2389 | 2430 |
2390 // Returns NULL if the updated map is incompatible. | 2431 // Returns NULL if the updated map is incompatible. |
2391 Map* Map::FindUpdatedMap(int verbatim, | 2432 Map* Map::FindUpdatedMap(int verbatim, |
2392 int length, | 2433 int length, |
2393 DescriptorArray* descriptors) { | 2434 DescriptorArray* descriptors) { |
| 2435 DisallowHeapAllocation no_allocation; |
| 2436 |
2394 // This can only be called on roots of transition trees. | 2437 // This can only be called on roots of transition trees. |
2395 ASSERT(GetBackPointer()->IsUndefined()); | 2438 ASSERT(GetBackPointer()->IsUndefined()); |
2396 | 2439 |
2397 Map* current = this; | 2440 Map* current = this; |
2398 | 2441 |
2399 for (int i = verbatim; i < length; i++) { | 2442 for (int i = verbatim; i < length; i++) { |
2400 if (!current->HasTransitionArray()) break; | 2443 if (!current->HasTransitionArray()) break; |
2401 Name* name = descriptors->GetKey(i); | 2444 Name* name = descriptors->GetKey(i); |
2402 TransitionArray* transitions = current->transitions(); | 2445 TransitionArray* transitions = current->transitions(); |
2403 int transition = transitions->Search(name); | 2446 int transition = transitions->Search(name); |
(...skipping 14 matching lines...) Expand all Loading... |
2418 } | 2461 } |
2419 } | 2462 } |
2420 | 2463 |
2421 return current; | 2464 return current; |
2422 } | 2465 } |
2423 | 2466 |
2424 | 2467 |
2425 Map* Map::FindLastMatchMap(int verbatim, | 2468 Map* Map::FindLastMatchMap(int verbatim, |
2426 int length, | 2469 int length, |
2427 DescriptorArray* descriptors) { | 2470 DescriptorArray* descriptors) { |
| 2471 DisallowHeapAllocation no_allocation; |
| 2472 |
2428 // This can only be called on roots of transition trees. | 2473 // This can only be called on roots of transition trees. |
2429 ASSERT(GetBackPointer()->IsUndefined()); | 2474 ASSERT(GetBackPointer()->IsUndefined()); |
2430 | 2475 |
2431 Map* current = this; | 2476 Map* current = this; |
2432 | 2477 |
2433 for (int i = verbatim; i < length; i++) { | 2478 for (int i = verbatim; i < length; i++) { |
2434 if (!current->HasTransitionArray()) break; | 2479 if (!current->HasTransitionArray()) break; |
2435 Name* name = descriptors->GetKey(i); | 2480 Name* name = descriptors->GetKey(i); |
2436 TransitionArray* transitions = current->transitions(); | 2481 TransitionArray* transitions = current->transitions(); |
2437 int transition = transitions->Search(name); | 2482 int transition = transitions->Search(name); |
2438 if (transition == TransitionArray::kNotFound) break; | 2483 if (transition == TransitionArray::kNotFound) break; |
2439 | 2484 |
2440 Map* next = transitions->GetTarget(transition); | 2485 Map* next = transitions->GetTarget(transition); |
2441 DescriptorArray* next_descriptors = next->instance_descriptors(); | 2486 DescriptorArray* next_descriptors = next->instance_descriptors(); |
2442 | 2487 |
2443 if (next_descriptors->GetValue(i) != descriptors->GetValue(i)) break; | |
2444 | |
2445 PropertyDetails details = descriptors->GetDetails(i); | 2488 PropertyDetails details = descriptors->GetDetails(i); |
2446 PropertyDetails next_details = next_descriptors->GetDetails(i); | 2489 PropertyDetails next_details = next_descriptors->GetDetails(i); |
2447 if (details.type() != next_details.type()) break; | 2490 if (details.type() != next_details.type()) break; |
2448 if (details.attributes() != next_details.attributes()) break; | 2491 if (details.attributes() != next_details.attributes()) break; |
2449 if (!details.representation().Equals(next_details.representation())) break; | 2492 if (!details.representation().Equals(next_details.representation())) break; |
| 2493 if (next_details.type() == FIELD) { |
| 2494 if (!descriptors->GetFieldType(i)->NowIs( |
| 2495 next_descriptors->GetFieldType(i))) break; |
| 2496 } else { |
| 2497 if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break; |
| 2498 } |
2450 | 2499 |
2451 current = next; | 2500 current = next; |
2452 } | 2501 } |
2453 return current; | 2502 return current; |
2454 } | 2503 } |
2455 | 2504 |
2456 | 2505 |
| 2506 Map* Map::FindFieldOwner(int descriptor) { |
| 2507 DisallowHeapAllocation no_allocation; |
| 2508 ASSERT_EQ(FIELD, instance_descriptors()->GetDetails(descriptor).type()); |
| 2509 Map* result = this; |
| 2510 while (true) { |
| 2511 Object* back = result->GetBackPointer(); |
| 2512 if (back->IsUndefined()) break; |
| 2513 Map* parent = Map::cast(back); |
| 2514 if (parent->NumberOfOwnDescriptors() <= descriptor) break; |
| 2515 result = parent; |
| 2516 } |
| 2517 return result; |
| 2518 } |
| 2519 |
| 2520 |
| 2521 void Map::UpdateDescriptor(int descriptor_number, Descriptor* desc) { |
| 2522 DisallowHeapAllocation no_allocation; |
| 2523 if (HasTransitionArray()) { |
| 2524 TransitionArray* transitions = this->transitions(); |
| 2525 for (int i = 0; i < transitions->number_of_transitions(); ++i) { |
| 2526 transitions->GetTarget(i)->UpdateDescriptor(descriptor_number, desc); |
| 2527 } |
| 2528 } |
| 2529 instance_descriptors()->Replace(descriptor_number, desc);; |
| 2530 } |
| 2531 |
| 2532 |
| 2533 // static |
| 2534 Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> old_field_type, |
| 2535 Handle<HeapType> new_field_type, |
| 2536 Isolate* isolate) { |
| 2537 if (new_field_type->NowIs(old_field_type)) return old_field_type; |
| 2538 if (old_field_type->NowIs(new_field_type)) return new_field_type; |
| 2539 return HeapType::Any(isolate); |
| 2540 } |
| 2541 |
| 2542 |
| 2543 // static |
| 2544 void Map::GeneralizeFieldType(Handle<Map> map, |
| 2545 int modify_index, |
| 2546 Handle<HeapType> new_field_type) { |
| 2547 Isolate* isolate = map->GetIsolate(); |
| 2548 Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate); |
| 2549 Handle<DescriptorArray> descriptors( |
| 2550 field_owner->instance_descriptors(), isolate); |
| 2551 |
| 2552 // Check if we actually need to generalize the field type at all. |
| 2553 Handle<HeapType> old_field_type( |
| 2554 descriptors->GetFieldType(modify_index), isolate); |
| 2555 if (new_field_type->NowIs(old_field_type)) { |
| 2556 ASSERT(Map::GeneralizeFieldType(old_field_type, |
| 2557 new_field_type, |
| 2558 isolate)->NowIs(old_field_type)); |
| 2559 return; |
| 2560 } |
| 2561 |
| 2562 // Determine the generalized new field type. |
| 2563 new_field_type = Map::GeneralizeFieldType( |
| 2564 old_field_type, new_field_type, isolate); |
| 2565 |
| 2566 PropertyDetails details = descriptors->GetDetails(modify_index); |
| 2567 FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate), |
| 2568 descriptors->GetFieldIndex(modify_index), |
| 2569 new_field_type, |
| 2570 details.attributes(), |
| 2571 details.representation()); |
| 2572 field_owner->UpdateDescriptor(modify_index, &d); |
| 2573 field_owner->dependent_code()->DeoptimizeDependentCodeGroup( |
| 2574 isolate, DependentCode::kFieldTypeGroup); |
| 2575 |
| 2576 if (FLAG_trace_generalization) { |
| 2577 map->PrintGeneralization( |
| 2578 stdout, "field type generalization", |
| 2579 modify_index, map->NumberOfOwnDescriptors(), |
| 2580 map->NumberOfOwnDescriptors(), false, |
| 2581 details.representation(), details.representation(), |
| 2582 *old_field_type, *new_field_type); |
| 2583 } |
| 2584 } |
| 2585 |
| 2586 |
2457 // Generalize the representation of the descriptor at |modify_index|. | 2587 // Generalize the representation of the descriptor at |modify_index|. |
2458 // This method rewrites the transition tree to reflect the new change. To avoid | 2588 // This method rewrites the transition tree to reflect the new change. To avoid |
2459 // high degrees over polymorphism, and to stabilize quickly, on every rewrite | 2589 // high degrees over polymorphism, and to stabilize quickly, on every rewrite |
2460 // the new type is deduced by merging the current type with any potential new | 2590 // the new type is deduced by merging the current type with any potential new |
2461 // (partial) version of the type in the transition tree. | 2591 // (partial) version of the type in the transition tree. |
2462 // To do this, on each rewrite: | 2592 // To do this, on each rewrite: |
2463 // - Search the root of the transition tree using FindRootMap. | 2593 // - Search the root of the transition tree using FindRootMap. |
2464 // - Find |updated|, the newest matching version of this map using | 2594 // - Find |updated|, the newest matching version of this map using |
2465 // FindUpdatedMap. This uses the keys in the own map's descriptor array to | 2595 // FindUpdatedMap. This uses the keys in the own map's descriptor array to |
2466 // walk the transition tree. | 2596 // walk the transition tree. |
2467 // - Merge/generalize the descriptor array of the current map and |updated|. | 2597 // - Merge/generalize the descriptor array of the current map and |updated|. |
2468 // - Generalize the |modify_index| descriptor using |new_representation|. | 2598 // - Generalize the |modify_index| descriptor using |new_representation|. |
2469 // - Walk the tree again starting from the root towards |updated|. Stop at | 2599 // - Walk the tree again starting from the root towards |updated|. Stop at |
2470 // |split_map|, the first map who's descriptor array does not match the merged | 2600 // |split_map|, the first map who's descriptor array does not match the merged |
2471 // descriptor array. | 2601 // descriptor array. |
2472 // - If |updated| == |split_map|, |updated| is in the expected state. Return it. | 2602 // - If |updated| == |split_map|, |updated| is in the expected state. Return it. |
2473 // - Otherwise, invalidate the outdated transition target from |updated|, and | 2603 // - Otherwise, invalidate the outdated transition target from |updated|, and |
2474 // replace its transition tree with a new branch for the updated descriptors. | 2604 // replace its transition tree with a new branch for the updated descriptors. |
2475 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, | 2605 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, |
2476 int modify_index, | 2606 int modify_index, |
2477 Representation new_representation, | 2607 Representation new_representation, |
| 2608 Handle<HeapType> new_field_type, |
2478 StoreMode store_mode) { | 2609 StoreMode store_mode) { |
2479 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); | 2610 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); |
2480 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2611 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
2481 Representation old_representation = old_details.representation(); | 2612 Representation old_representation = old_details.representation(); |
2482 | 2613 |
2483 // It's fine to transition from None to anything but double without any | 2614 // It's fine to transition from None to anything but double without any |
2484 // modification to the object, because the default uninitialized value for | 2615 // modification to the object, because the default uninitialized value for |
2485 // representation None can be overwritten by both smi and tagged values. | 2616 // representation None can be overwritten by both smi and tagged values. |
2486 // Doubles, however, would require a box allocation. | 2617 // Doubles, however, would require a box allocation. |
2487 if (old_representation.IsNone() && | 2618 if (old_representation.IsNone() && |
2488 !new_representation.IsNone() && | 2619 !new_representation.IsNone() && |
2489 !new_representation.IsDouble()) { | 2620 !new_representation.IsDouble()) { |
| 2621 ASSERT(old_details.type() == FIELD); |
| 2622 ASSERT(old_descriptors->GetFieldType(modify_index)->NowIs( |
| 2623 HeapType::None())); |
| 2624 if (FLAG_trace_generalization) { |
| 2625 old_map->PrintGeneralization( |
| 2626 stdout, "uninitialized field", |
| 2627 modify_index, old_map->NumberOfOwnDescriptors(), |
| 2628 old_map->NumberOfOwnDescriptors(), false, |
| 2629 old_representation, new_representation, |
| 2630 old_descriptors->GetFieldType(modify_index), *new_field_type); |
| 2631 } |
2490 old_descriptors->SetRepresentation(modify_index, new_representation); | 2632 old_descriptors->SetRepresentation(modify_index, new_representation); |
| 2633 old_descriptors->SetValue(modify_index, *new_field_type); |
2491 return old_map; | 2634 return old_map; |
2492 } | 2635 } |
2493 | 2636 |
2494 int descriptors = old_map->NumberOfOwnDescriptors(); | 2637 if (new_representation.Equals(old_representation) && |
| 2638 old_details.type() == FIELD) { |
| 2639 Map::GeneralizeFieldType(old_map, modify_index, new_field_type); |
| 2640 return old_map; |
| 2641 } |
| 2642 |
2495 Handle<Map> root_map(old_map->FindRootMap()); | 2643 Handle<Map> root_map(old_map->FindRootMap()); |
2496 | 2644 |
2497 // Check the state of the root map. | 2645 // Check the state of the root map. |
2498 if (!old_map->EquivalentToForTransition(*root_map)) { | 2646 if (!old_map->EquivalentToForTransition(*root_map)) { |
2499 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2647 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2500 old_details.attributes(), "not equivalent"); | 2648 old_details.attributes(), "not equivalent"); |
2501 } | 2649 } |
2502 | 2650 |
2503 int verbatim = root_map->NumberOfOwnDescriptors(); | 2651 int verbatim = root_map->NumberOfOwnDescriptors(); |
2504 | 2652 |
2505 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) { | 2653 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) { |
2506 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2654 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2507 old_details.attributes(), "root modification"); | 2655 old_details.attributes(), "root modification"); |
2508 } | 2656 } |
2509 | 2657 |
| 2658 int descriptors = old_map->NumberOfOwnDescriptors(); |
2510 Map* raw_updated = root_map->FindUpdatedMap( | 2659 Map* raw_updated = root_map->FindUpdatedMap( |
2511 verbatim, descriptors, *old_descriptors); | 2660 verbatim, descriptors, *old_descriptors); |
2512 if (raw_updated == NULL) { | 2661 if (raw_updated == NULL) { |
2513 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2662 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2514 old_details.attributes(), "incompatible"); | 2663 old_details.attributes(), "incompatible"); |
2515 } | 2664 } |
2516 | 2665 |
2517 Handle<Map> updated(raw_updated); | 2666 Handle<Map> updated(raw_updated); |
2518 Handle<DescriptorArray> updated_descriptors(updated->instance_descriptors()); | 2667 Handle<DescriptorArray> updated_descriptors(updated->instance_descriptors()); |
2519 | 2668 |
2520 int valid = updated->NumberOfOwnDescriptors(); | 2669 int valid = updated->NumberOfOwnDescriptors(); |
2521 | 2670 |
2522 // Directly change the map if the target map is more general. Ensure that the | 2671 // Directly change the map if the target map is more general. Ensure that the |
2523 // target type of the modify_index is a FIELD, unless we are migrating. | 2672 // target type of the modify_index is a FIELD, unless we are migrating. |
2524 if (updated_descriptors->IsMoreGeneralThan( | 2673 if (updated_descriptors->IsMoreGeneralThan( |
2525 verbatim, valid, descriptors, *old_descriptors) && | 2674 verbatim, valid, descriptors, *old_descriptors) && |
2526 (store_mode == ALLOW_AS_CONSTANT || | 2675 (store_mode == ALLOW_AS_CONSTANT || |
2527 updated_descriptors->GetDetails(modify_index).type() == FIELD)) { | 2676 updated_descriptors->GetDetails(modify_index).type() == FIELD)) { |
2528 Representation updated_representation = | 2677 Representation updated_representation = |
2529 updated_descriptors->GetDetails(modify_index).representation(); | 2678 updated_descriptors->GetDetails(modify_index).representation(); |
2530 if (new_representation.fits_into(updated_representation)) return updated; | 2679 if (new_representation.fits_into(updated_representation)) return updated; |
2531 } | 2680 } |
2532 | 2681 |
2533 Handle<DescriptorArray> new_descriptors = DescriptorArray::Merge( | 2682 Handle<DescriptorArray> new_descriptors = DescriptorArray::Merge( |
2534 updated, verbatim, valid, descriptors, modify_index, | 2683 updated, verbatim, valid, descriptors, modify_index, |
2535 store_mode, old_map); | 2684 store_mode, old_map); |
2536 ASSERT(store_mode == ALLOW_AS_CONSTANT || | 2685 ASSERT(store_mode == ALLOW_AS_CONSTANT || |
2537 new_descriptors->GetDetails(modify_index).type() == FIELD); | 2686 new_descriptors->GetDetails(modify_index).type() == FIELD); |
2538 | 2687 |
| 2688 Isolate* isolate = new_descriptors->GetIsolate(); |
2539 old_representation = | 2689 old_representation = |
2540 new_descriptors->GetDetails(modify_index).representation(); | 2690 new_descriptors->GetDetails(modify_index).representation(); |
2541 Representation updated_representation = | 2691 Representation updated_representation = |
2542 new_representation.generalize(old_representation); | 2692 new_representation.generalize(old_representation); |
2543 if (!updated_representation.Equals(old_representation)) { | 2693 if (!updated_representation.Equals(old_representation)) { |
2544 new_descriptors->SetRepresentation(modify_index, updated_representation); | 2694 new_descriptors->SetRepresentation(modify_index, updated_representation); |
2545 } | 2695 } |
| 2696 if (new_descriptors->GetDetails(modify_index).type() == FIELD) { |
| 2697 Handle<HeapType> field_type( |
| 2698 new_descriptors->GetFieldType(modify_index), isolate); |
| 2699 new_field_type = Map::GeneralizeFieldType( |
| 2700 field_type, new_field_type, isolate); |
| 2701 new_descriptors->SetValue(modify_index, *new_field_type); |
| 2702 } |
2546 | 2703 |
2547 Handle<Map> split_map(root_map->FindLastMatchMap( | 2704 Handle<Map> split_map(root_map->FindLastMatchMap( |
2548 verbatim, descriptors, *new_descriptors)); | 2705 verbatim, descriptors, *new_descriptors)); |
2549 | 2706 |
2550 int split_descriptors = split_map->NumberOfOwnDescriptors(); | 2707 int split_descriptors = split_map->NumberOfOwnDescriptors(); |
2551 // This is shadowed by |updated_descriptors| being more general than | 2708 // This is shadowed by |updated_descriptors| being more general than |
2552 // |old_descriptors|. | 2709 // |old_descriptors|. |
2553 ASSERT(descriptors != split_descriptors); | 2710 ASSERT(descriptors != split_descriptors); |
2554 | 2711 |
2555 int descriptor = split_descriptors; | 2712 int descriptor = split_descriptors; |
2556 split_map->DeprecateTarget( | 2713 split_map->DeprecateTarget( |
2557 old_descriptors->GetKey(descriptor), *new_descriptors); | 2714 old_descriptors->GetKey(descriptor), *new_descriptors); |
2558 | 2715 |
2559 if (FLAG_trace_generalization) { | 2716 if (FLAG_trace_generalization) { |
| 2717 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| 2718 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); |
| 2719 Handle<HeapType> old_field_type = (old_details.type() == FIELD) |
| 2720 ? handle(old_descriptors->GetFieldType(modify_index), isolate) |
| 2721 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), |
| 2722 isolate), isolate); |
| 2723 Handle<HeapType> new_field_type = (new_details.type() == FIELD) |
| 2724 ? handle(new_descriptors->GetFieldType(modify_index), isolate) |
| 2725 : HeapType::Constant(handle(new_descriptors->GetValue(modify_index), |
| 2726 isolate), isolate); |
2560 old_map->PrintGeneralization( | 2727 old_map->PrintGeneralization( |
2561 stdout, "", modify_index, descriptor, descriptors, | 2728 stdout, "", modify_index, descriptor, descriptors, |
2562 old_descriptors->GetDetails(modify_index).type() == CONSTANT && | 2729 old_details.type() == CONSTANT && store_mode == FORCE_FIELD, |
2563 store_mode == FORCE_FIELD, | 2730 old_details.representation(), new_details.representation(), |
2564 old_representation, updated_representation); | 2731 *old_field_type, *new_field_type); |
2565 } | 2732 } |
2566 | 2733 |
2567 // Add missing transitions. | 2734 // Add missing transitions. |
2568 Handle<Map> new_map = split_map; | 2735 Handle<Map> new_map = split_map; |
2569 for (; descriptor < descriptors; descriptor++) { | 2736 for (; descriptor < descriptors; descriptor++) { |
2570 new_map = CopyInstallDescriptors(new_map, descriptor, new_descriptors); | 2737 new_map = CopyInstallDescriptors(new_map, descriptor, new_descriptors); |
2571 } | 2738 } |
2572 | 2739 |
2573 new_map->set_owns_descriptors(true); | 2740 new_map->set_owns_descriptors(true); |
2574 return new_map; | 2741 return new_map; |
2575 } | 2742 } |
2576 | 2743 |
2577 | 2744 |
2578 // Generalize the representation of all FIELD descriptors. | 2745 // Generalize the representation of all FIELD descriptors. |
2579 Handle<Map> Map::GeneralizeAllFieldRepresentations( | 2746 Handle<Map> Map::GeneralizeAllFieldRepresentations( |
2580 Handle<Map> map, | 2747 Handle<Map> map) { |
2581 Representation new_representation) { | |
2582 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 2748 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
2583 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { | 2749 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { |
2584 PropertyDetails details = descriptors->GetDetails(i); | 2750 if (descriptors->GetDetails(i).type() == FIELD) { |
2585 if (details.type() == FIELD) { | 2751 map = GeneralizeRepresentation(map, i, Representation::Tagged(), |
2586 map = GeneralizeRepresentation(map, i, new_representation, FORCE_FIELD); | 2752 HeapType::Any(map->GetIsolate()), |
| 2753 FORCE_FIELD); |
2587 } | 2754 } |
2588 } | 2755 } |
2589 return map; | 2756 return map; |
2590 } | 2757 } |
2591 | 2758 |
2592 | 2759 |
2593 Handle<Map> Map::CurrentMapForDeprecated(Handle<Map> map) { | 2760 Handle<Map> Map::CurrentMapForDeprecated(Handle<Map> map) { |
2594 Handle<Map> proto_map(map); | 2761 Handle<Map> proto_map(map); |
2595 while (proto_map->prototype()->IsJSObject()) { | 2762 while (proto_map->prototype()->IsJSObject()) { |
2596 Handle<JSObject> holder(JSObject::cast(proto_map->prototype())); | 2763 Handle<JSObject> holder(JSObject::cast(proto_map->prototype())); |
(...skipping 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3715 JSObject::MigrateToMap(object, map); | 3882 JSObject::MigrateToMap(object, map); |
3716 } | 3883 } |
3717 | 3884 |
3718 | 3885 |
3719 void JSObject::MigrateInstance(Handle<JSObject> object) { | 3886 void JSObject::MigrateInstance(Handle<JSObject> object) { |
3720 // Converting any field to the most specific type will cause the | 3887 // Converting any field to the most specific type will cause the |
3721 // GeneralizeFieldRepresentation algorithm to create the most general existing | 3888 // GeneralizeFieldRepresentation algorithm to create the most general existing |
3722 // transition that matches the object. This achieves what is needed. | 3889 // transition that matches the object. This achieves what is needed. |
3723 Handle<Map> original_map(object->map()); | 3890 Handle<Map> original_map(object->map()); |
3724 GeneralizeFieldRepresentation( | 3891 GeneralizeFieldRepresentation( |
3725 object, 0, Representation::None(), ALLOW_AS_CONSTANT); | 3892 object, 0, Representation::None(), |
| 3893 HeapType::None(object->GetIsolate()), |
| 3894 ALLOW_AS_CONSTANT); |
3726 object->map()->set_migration_target(true); | 3895 object->map()->set_migration_target(true); |
3727 if (FLAG_trace_migration) { | 3896 if (FLAG_trace_migration) { |
3728 object->PrintInstanceMigration(stdout, *original_map, object->map()); | 3897 object->PrintInstanceMigration(stdout, *original_map, object->map()); |
3729 } | 3898 } |
3730 } | 3899 } |
3731 | 3900 |
3732 | 3901 |
3733 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { | 3902 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { |
3734 Handle<Map> original_map(object->map()); | 3903 Handle<Map> original_map(object->map()); |
3735 Handle<Map> new_map = Map::CurrentMapForDeprecatedInternal(original_map); | 3904 Handle<Map> new_map = Map::CurrentMapForDeprecatedInternal(original_map); |
3736 if (new_map.is_null()) return Handle<Object>(); | 3905 if (new_map.is_null()) return Handle<Object>(); |
3737 JSObject::MigrateToMap(object, new_map); | 3906 JSObject::MigrateToMap(object, new_map); |
3738 if (FLAG_trace_migration) { | 3907 if (FLAG_trace_migration) { |
3739 object->PrintInstanceMigration(stdout, *original_map, object->map()); | 3908 object->PrintInstanceMigration(stdout, *original_map, object->map()); |
3740 } | 3909 } |
3741 return object; | 3910 return object; |
3742 } | 3911 } |
3743 | 3912 |
3744 | 3913 |
3745 MaybeHandle<Object> JSObject::SetPropertyUsingTransition( | 3914 MaybeHandle<Object> JSObject::SetPropertyUsingTransition( |
3746 Handle<JSObject> object, | 3915 Handle<JSObject> object, |
3747 LookupResult* lookup, | 3916 LookupResult* lookup, |
3748 Handle<Name> name, | 3917 Handle<Name> name, |
3749 Handle<Object> value, | 3918 Handle<Object> value, |
3750 PropertyAttributes attributes) { | 3919 PropertyAttributes attributes) { |
3751 Handle<Map> transition_map(lookup->GetTransitionTarget()); | 3920 Handle<Map> transition_map(lookup->GetTransitionTarget()); |
3752 int descriptor = transition_map->LastAdded(); | 3921 int descriptor = transition_map->LastAdded(); |
3753 | 3922 |
3754 DescriptorArray* descriptors = transition_map->instance_descriptors(); | 3923 Handle<DescriptorArray> descriptors(transition_map->instance_descriptors()); |
3755 PropertyDetails details = descriptors->GetDetails(descriptor); | 3924 PropertyDetails details = descriptors->GetDetails(descriptor); |
3756 | 3925 |
3757 if (details.type() == CALLBACKS || attributes != details.attributes()) { | 3926 if (details.type() == CALLBACKS || attributes != details.attributes()) { |
3758 // AddProperty will either normalize the object, or create a new fast copy | 3927 // AddProperty will either normalize the object, or create a new fast copy |
3759 // of the map. If we get a fast copy of the map, all field representations | 3928 // of the map. If we get a fast copy of the map, all field representations |
3760 // will be tagged since the transition is omitted. | 3929 // will be tagged since the transition is omitted. |
3761 return JSObject::AddProperty( | 3930 return JSObject::AddProperty( |
3762 object, name, value, attributes, SLOPPY, | 3931 object, name, value, attributes, SLOPPY, |
3763 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, | 3932 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, |
3764 JSReceiver::OMIT_EXTENSIBILITY_CHECK, | 3933 JSReceiver::OMIT_EXTENSIBILITY_CHECK, |
3765 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); | 3934 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); |
3766 } | 3935 } |
3767 | 3936 |
3768 // Keep the target CONSTANT if the same value is stored. | 3937 // Keep the target CONSTANT if the same value is stored. |
3769 // TODO(verwaest): Also support keeping the placeholder | 3938 // TODO(verwaest): Also support keeping the placeholder |
3770 // (value->IsUninitialized) as constant. | 3939 // (value->IsUninitialized) as constant. |
3771 if (!lookup->CanHoldValue(value) || | 3940 if (!lookup->CanHoldValue(value)) { |
3772 (details.type() == CONSTANT && | 3941 Representation field_representation = value->OptimalRepresentation(); |
3773 descriptors->GetValue(descriptor) != *value)) { | 3942 Handle<HeapType> field_type = value->OptimalType( |
3774 transition_map = Map::GeneralizeRepresentation(transition_map, | 3943 lookup->isolate(), field_representation); |
3775 descriptor, value->OptimalRepresentation(), FORCE_FIELD); | 3944 transition_map = Map::GeneralizeRepresentation( |
| 3945 transition_map, descriptor, |
| 3946 field_representation, field_type, FORCE_FIELD); |
3776 } | 3947 } |
3777 | 3948 |
3778 JSObject::MigrateToMap(object, transition_map); | 3949 JSObject::MigrateToMap(object, transition_map); |
3779 | 3950 |
3780 // Reload. | 3951 // Reload. |
3781 descriptors = transition_map->instance_descriptors(); | 3952 descriptors = handle(transition_map->instance_descriptors()); |
3782 details = descriptors->GetDetails(descriptor); | 3953 details = descriptors->GetDetails(descriptor); |
3783 | 3954 |
3784 if (details.type() != FIELD) return value; | 3955 if (details.type() != FIELD) return value; |
3785 | 3956 |
3786 int field_index = descriptors->GetFieldIndex(descriptor); | 3957 int field_index = descriptors->GetFieldIndex(descriptor); |
3787 if (details.representation().IsDouble()) { | 3958 if (details.representation().IsDouble()) { |
3788 // Nothing more to be done. | 3959 // Nothing more to be done. |
3789 if (value->IsUninitialized()) return value; | 3960 if (value->IsUninitialized()) return value; |
3790 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index)); | 3961 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index)); |
3791 box->set_value(value->Number()); | 3962 box->set_value(value->Number()); |
3792 } else { | 3963 } else { |
3793 object->FastPropertyAtPut(field_index, *value); | 3964 object->FastPropertyAtPut(field_index, *value); |
3794 } | 3965 } |
3795 | 3966 |
3796 return value; | 3967 return value; |
3797 } | 3968 } |
3798 | 3969 |
3799 | 3970 |
3800 static void SetPropertyToField(LookupResult* lookup, | 3971 static void SetPropertyToField(LookupResult* lookup, |
3801 Handle<Object> value) { | 3972 Handle<Object> value) { |
3802 Representation representation = lookup->representation(); | 3973 Representation representation = lookup->representation(); |
3803 if (!lookup->CanHoldValue(value) || | 3974 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { |
3804 lookup->type() == CONSTANT) { | 3975 Representation field_representation = value->OptimalRepresentation(); |
| 3976 Handle<HeapType> field_type = value->OptimalType( |
| 3977 lookup->isolate(), field_representation); |
3805 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), | 3978 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), |
3806 lookup->GetDescriptorIndex(), | 3979 lookup->GetDescriptorIndex(), |
3807 value->OptimalRepresentation(), | 3980 field_representation, field_type, |
3808 FORCE_FIELD); | 3981 FORCE_FIELD); |
3809 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); | 3982 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); |
3810 int descriptor = lookup->GetDescriptorIndex(); | 3983 int descriptor = lookup->GetDescriptorIndex(); |
3811 representation = desc->GetDetails(descriptor).representation(); | 3984 representation = desc->GetDetails(descriptor).representation(); |
3812 } | 3985 } |
3813 | 3986 |
3814 if (representation.IsDouble()) { | 3987 if (representation.IsDouble()) { |
3815 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( | 3988 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( |
3816 lookup->GetFieldIndex().field_index())); | 3989 lookup->GetFieldIndex().field_index())); |
3817 storage->set_value(value->Number()); | 3990 storage->set_value(value->Number()); |
(...skipping 15 matching lines...) Expand all Loading... |
3833 } | 4006 } |
3834 | 4007 |
3835 if (!object->HasFastProperties()) { | 4008 if (!object->HasFastProperties()) { |
3836 ReplaceSlowProperty(object, name, value, attributes); | 4009 ReplaceSlowProperty(object, name, value, attributes); |
3837 return; | 4010 return; |
3838 } | 4011 } |
3839 | 4012 |
3840 int descriptor_index = lookup->GetDescriptorIndex(); | 4013 int descriptor_index = lookup->GetDescriptorIndex(); |
3841 if (lookup->GetAttributes() == attributes) { | 4014 if (lookup->GetAttributes() == attributes) { |
3842 JSObject::GeneralizeFieldRepresentation( | 4015 JSObject::GeneralizeFieldRepresentation( |
3843 object, descriptor_index, Representation::Tagged(), FORCE_FIELD); | 4016 object, descriptor_index, Representation::Tagged(), |
| 4017 HeapType::Any(lookup->isolate()), FORCE_FIELD); |
3844 } else { | 4018 } else { |
3845 Handle<Map> old_map(object->map()); | 4019 Handle<Map> old_map(object->map()); |
3846 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, | 4020 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, |
3847 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); | 4021 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); |
3848 JSObject::MigrateToMap(object, new_map); | 4022 JSObject::MigrateToMap(object, new_map); |
3849 } | 4023 } |
3850 | 4024 |
3851 DescriptorArray* descriptors = object->map()->instance_descriptors(); | 4025 DescriptorArray* descriptors = object->map()->instance_descriptors(); |
3852 int index = descriptors->GetDetails(descriptor_index).field_index(); | 4026 int index = descriptors->GetDetails(descriptor_index).field_index(); |
3853 object->FastPropertyAtPut(index, *value); | 4027 object->FastPropertyAtPut(index, *value); |
(...skipping 2967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6821 | 6995 |
6822 Handle<Map> result = CopyDropDescriptors(map); | 6996 Handle<Map> result = CopyDropDescriptors(map); |
6823 result->InitializeDescriptors(*descriptors); | 6997 result->InitializeDescriptors(*descriptors); |
6824 | 6998 |
6825 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { | 6999 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { |
6826 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( | 7000 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( |
6827 map, name, result, simple_flag); | 7001 map, name, result, simple_flag); |
6828 map->set_transitions(*transitions); | 7002 map->set_transitions(*transitions); |
6829 result->SetBackPointer(*map); | 7003 result->SetBackPointer(*map); |
6830 } else { | 7004 } else { |
6831 descriptors->InitializeRepresentations(Representation::Tagged()); | 7005 int length = descriptors->number_of_descriptors(); |
| 7006 for (int i = 0; i < length; i++) { |
| 7007 descriptors->SetRepresentation(i, Representation::Tagged()); |
| 7008 if (descriptors->GetDetails(i).type() == FIELD) { |
| 7009 descriptors->SetValue(i, HeapType::Any()); |
| 7010 } |
| 7011 } |
6832 } | 7012 } |
6833 | 7013 |
6834 return result; | 7014 return result; |
6835 } | 7015 } |
6836 | 7016 |
6837 | 7017 |
6838 // Since this method is used to rewrite an existing transition tree, it can | 7018 // Since this method is used to rewrite an existing transition tree, it can |
6839 // always insert transitions without checking. | 7019 // always insert transitions without checking. |
6840 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, | 7020 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, |
6841 int new_descriptor, | 7021 int new_descriptor, |
(...skipping 1166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8008 | 8188 |
8009 // |verbatim| -> |valid| | 8189 // |verbatim| -> |valid| |
8010 for (; descriptor < valid; descriptor++) { | 8190 for (; descriptor < valid; descriptor++) { |
8011 PropertyDetails left_details = left->GetDetails(descriptor); | 8191 PropertyDetails left_details = left->GetDetails(descriptor); |
8012 PropertyDetails right_details = right->GetDetails(descriptor); | 8192 PropertyDetails right_details = right->GetDetails(descriptor); |
8013 if (left_details.type() == FIELD || right_details.type() == FIELD || | 8193 if (left_details.type() == FIELD || right_details.type() == FIELD || |
8014 (store_mode == FORCE_FIELD && descriptor == modify_index) || | 8194 (store_mode == FORCE_FIELD && descriptor == modify_index) || |
8015 (left_details.type() == CONSTANT && | 8195 (left_details.type() == CONSTANT && |
8016 right_details.type() == CONSTANT && | 8196 right_details.type() == CONSTANT && |
8017 left->GetValue(descriptor) != right->GetValue(descriptor))) { | 8197 left->GetValue(descriptor) != right->GetValue(descriptor))) { |
| 8198 ASSERT(left_details.type() == CONSTANT || left_details.type() == FIELD); |
| 8199 ASSERT(right_details.type() == CONSTANT || right_details.type() == FIELD); |
8018 Representation representation = left_details.representation().generalize( | 8200 Representation representation = left_details.representation().generalize( |
8019 right_details.representation()); | 8201 right_details.representation()); |
8020 FieldDescriptor d(handle(left->GetKey(descriptor)), | 8202 Handle<HeapType> left_type = (left_details.type() == FIELD) |
| 8203 ? handle(left->GetFieldType(descriptor), isolate) |
| 8204 : left->GetValue(descriptor)->OptimalType(isolate, representation); |
| 8205 Handle<HeapType> right_type = (right_details.type() == FIELD) |
| 8206 ? handle(right->GetFieldType(descriptor), isolate) |
| 8207 : right->GetValue(descriptor)->OptimalType(isolate, representation); |
| 8208 Handle<HeapType> field_type = Map::GeneralizeFieldType( |
| 8209 left_type, right_type, isolate); |
| 8210 FieldDescriptor d(handle(left->GetKey(descriptor), isolate), |
8021 current_offset++, | 8211 current_offset++, |
| 8212 field_type, |
8022 right_details.attributes(), | 8213 right_details.attributes(), |
8023 representation); | 8214 representation); |
8024 result->Set(descriptor, &d); | 8215 result->Set(descriptor, &d); |
8025 } else { | 8216 } else { |
8026 Descriptor d(handle(right->GetKey(descriptor)), | 8217 Descriptor d(handle(right->GetKey(descriptor), isolate), |
8027 handle(right->GetValue(descriptor), right->GetIsolate()), | 8218 handle(right->GetValue(descriptor), isolate), |
8028 right_details); | 8219 right_details); |
8029 result->Set(descriptor, &d); | 8220 result->Set(descriptor, &d); |
8030 } | 8221 } |
8031 } | 8222 } |
8032 | 8223 |
8033 // |valid| -> |new_size| | 8224 // |valid| -> |new_size| |
8034 for (; descriptor < new_size; descriptor++) { | 8225 for (; descriptor < new_size; descriptor++) { |
8035 PropertyDetails right_details = right->GetDetails(descriptor); | 8226 PropertyDetails right_details = right->GetDetails(descriptor); |
8036 if (right_details.type() == FIELD || | 8227 if (right_details.type() == FIELD) { |
8037 (store_mode == FORCE_FIELD && descriptor == modify_index)) { | 8228 FieldDescriptor d(handle(right->GetKey(descriptor), isolate), |
8038 FieldDescriptor d(handle(right->GetKey(descriptor)), | |
8039 current_offset++, | 8229 current_offset++, |
| 8230 handle(right->GetFieldType(descriptor), isolate), |
8040 right_details.attributes(), | 8231 right_details.attributes(), |
8041 right_details.representation()); | 8232 right_details.representation()); |
8042 result->Set(descriptor, &d); | 8233 result->Set(descriptor, &d); |
| 8234 } else if (store_mode == FORCE_FIELD && descriptor == modify_index) { |
| 8235 ASSERT_EQ(CONSTANT, right_details.type()); |
| 8236 Representation field_representation = right_details.representation(); |
| 8237 Handle<HeapType> field_type = right->GetValue(descriptor)->OptimalType( |
| 8238 isolate, field_representation); |
| 8239 FieldDescriptor d(handle(right->GetKey(descriptor), isolate), |
| 8240 current_offset++, |
| 8241 field_type, |
| 8242 right_details.attributes(), |
| 8243 field_representation); |
| 8244 result->Set(descriptor, &d); |
8043 } else { | 8245 } else { |
8044 Descriptor d(handle(right->GetKey(descriptor)), | 8246 Descriptor d(handle(right->GetKey(descriptor), isolate), |
8045 handle(right->GetValue(descriptor), right->GetIsolate()), | 8247 handle(right->GetValue(descriptor), isolate), |
8046 right_details); | 8248 right_details); |
8047 result->Set(descriptor, &d); | 8249 result->Set(descriptor, &d); |
8048 } | 8250 } |
8049 } | 8251 } |
8050 | 8252 |
8051 result->Sort(); | 8253 result->Sort(); |
8052 return result; | 8254 return result; |
8053 } | 8255 } |
8054 | 8256 |
8055 | 8257 |
(...skipping 8438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16494 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16696 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16495 static const char* error_messages_[] = { | 16697 static const char* error_messages_[] = { |
16496 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16698 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16497 }; | 16699 }; |
16498 #undef ERROR_MESSAGES_TEXTS | 16700 #undef ERROR_MESSAGES_TEXTS |
16499 return error_messages_[reason]; | 16701 return error_messages_[reason]; |
16500 } | 16702 } |
16501 | 16703 |
16502 | 16704 |
16503 } } // namespace v8::internal | 16705 } } // namespace v8::internal |
OLD | NEW |