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

Side by Side Diff: src/objects.cc

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

Powered by Google App Engine
This is Rietveld 408576698