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