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 1986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1997 static Handle<Object> NewStorageFor(Isolate* isolate, | 1997 static Handle<Object> NewStorageFor(Isolate* isolate, |
1998 Handle<Object> object, | 1998 Handle<Object> object, |
1999 Representation representation) { | 1999 Representation representation) { |
2000 Heap* heap = isolate->heap(); | 2000 Heap* heap = isolate->heap(); |
2001 CALL_HEAP_FUNCTION(isolate, | 2001 CALL_HEAP_FUNCTION(isolate, |
2002 object->AllocateNewStorageFor(heap, representation), | 2002 object->AllocateNewStorageFor(heap, representation), |
2003 Object); | 2003 Object); |
2004 } | 2004 } |
2005 | 2005 |
2006 | 2006 |
2007 static MaybeObject* CopyAddFieldDescriptor(Map* map, | 2007 static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map, |
2008 Name* name, | 2008 Handle<Name> name, |
2009 int index, | 2009 int index, |
2010 PropertyAttributes attributes, | 2010 PropertyAttributes attributes, |
2011 Representation representation, | 2011 Representation representation, |
2012 TransitionFlag flag) { | 2012 TransitionFlag flag) { |
2013 Map* new_map; | |
2014 FieldDescriptor new_field_desc(name, index, attributes, representation); | 2013 FieldDescriptor new_field_desc(name, index, attributes, representation); |
2015 MaybeObject* maybe_map = map->CopyAddDescriptor(&new_field_desc, flag); | 2014 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); |
2016 if (!maybe_map->To(&new_map)) return maybe_map; | |
2017 int unused_property_fields = map->unused_property_fields() - 1; | 2015 int unused_property_fields = map->unused_property_fields() - 1; |
2018 if (unused_property_fields < 0) { | 2016 if (unused_property_fields < 0) { |
2019 unused_property_fields += JSObject::kFieldsAdded; | 2017 unused_property_fields += JSObject::kFieldsAdded; |
2020 } | 2018 } |
2021 new_map->set_unused_property_fields(unused_property_fields); | 2019 new_map->set_unused_property_fields(unused_property_fields); |
2022 return new_map; | 2020 return new_map; |
2023 } | 2021 } |
2024 | 2022 |
2025 | 2023 |
2026 static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map, | |
2027 Handle<Name> name, | |
2028 int index, | |
2029 PropertyAttributes attributes, | |
2030 Representation representation, | |
2031 TransitionFlag flag) { | |
2032 CALL_HEAP_FUNCTION(map->GetIsolate(), | |
2033 CopyAddFieldDescriptor( | |
2034 *map, *name, index, attributes, representation, flag), | |
2035 Map); | |
2036 } | |
2037 | |
2038 | |
2039 void JSObject::AddFastProperty(Handle<JSObject> object, | 2024 void JSObject::AddFastProperty(Handle<JSObject> object, |
2040 Handle<Name> name, | 2025 Handle<Name> name, |
2041 Handle<Object> value, | 2026 Handle<Object> value, |
2042 PropertyAttributes attributes, | 2027 PropertyAttributes attributes, |
2043 StoreFromKeyed store_mode, | 2028 StoreFromKeyed store_mode, |
2044 ValueType value_type, | 2029 ValueType value_type, |
2045 TransitionFlag flag) { | 2030 TransitionFlag flag) { |
2046 ASSERT(!object->IsJSGlobalProxy()); | 2031 ASSERT(!object->IsJSGlobalProxy()); |
2047 ASSERT(DescriptorArray::kNotFound == | 2032 ASSERT(DescriptorArray::kNotFound == |
2048 object->map()->instance_descriptors()->Search( | 2033 object->map()->instance_descriptors()->Search( |
(...skipping 25 matching lines...) Expand all Loading... |
2074 // Nothing more to be done. | 2059 // Nothing more to be done. |
2075 if (value->IsUninitialized()) return; | 2060 if (value->IsUninitialized()) return; |
2076 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index)); | 2061 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index)); |
2077 box->set_value(value->Number()); | 2062 box->set_value(value->Number()); |
2078 } else { | 2063 } else { |
2079 object->FastPropertyAtPut(index, *value); | 2064 object->FastPropertyAtPut(index, *value); |
2080 } | 2065 } |
2081 } | 2066 } |
2082 | 2067 |
2083 | 2068 |
2084 static MaybeObject* CopyAddConstantDescriptor(Map* map, | |
2085 Name* name, | |
2086 Object* value, | |
2087 PropertyAttributes attributes, | |
2088 TransitionFlag flag) { | |
2089 ConstantDescriptor new_constant_desc(name, value, attributes); | |
2090 return map->CopyAddDescriptor(&new_constant_desc, flag); | |
2091 } | |
2092 | |
2093 | |
2094 static Handle<Map> CopyAddConstantDescriptor(Handle<Map> map, | 2069 static Handle<Map> CopyAddConstantDescriptor(Handle<Map> map, |
2095 Handle<Name> name, | 2070 Handle<Name> name, |
2096 Handle<Object> value, | 2071 Handle<Object> value, |
2097 PropertyAttributes attributes, | 2072 PropertyAttributes attributes, |
2098 TransitionFlag flag) { | 2073 TransitionFlag flag) { |
2099 CALL_HEAP_FUNCTION(map->GetIsolate(), | 2074 ConstantDescriptor new_constant_desc(name, value, attributes); |
2100 CopyAddConstantDescriptor( | 2075 return Map::CopyAddDescriptor(map, &new_constant_desc, flag); |
2101 *map, *name, *value, attributes, flag), | |
2102 Map); | |
2103 } | 2076 } |
2104 | 2077 |
2105 | 2078 |
2106 void JSObject::AddConstantProperty(Handle<JSObject> object, | 2079 void JSObject::AddConstantProperty(Handle<JSObject> object, |
2107 Handle<Name> name, | 2080 Handle<Name> name, |
2108 Handle<Object> constant, | 2081 Handle<Object> constant, |
2109 PropertyAttributes attributes, | 2082 PropertyAttributes attributes, |
2110 TransitionFlag initial_flag) { | 2083 TransitionFlag initial_flag) { |
2111 TransitionFlag flag = | 2084 TransitionFlag flag = |
2112 // Do not add transitions to global objects. | 2085 // Do not add transitions to global objects. |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2385 ASSERT(target_inobject < inobject_properties()); | 2358 ASSERT(target_inobject < inobject_properties()); |
2386 if (target_number_of_fields <= target_inobject) { | 2359 if (target_number_of_fields <= target_inobject) { |
2387 ASSERT(target_number_of_fields + target_unused == target_inobject); | 2360 ASSERT(target_number_of_fields + target_unused == target_inobject); |
2388 return false; | 2361 return false; |
2389 } | 2362 } |
2390 // Otherwise, properties will need to be moved to the backing store. | 2363 // Otherwise, properties will need to be moved to the backing store. |
2391 return true; | 2364 return true; |
2392 } | 2365 } |
2393 | 2366 |
2394 | 2367 |
| 2368 Handle<TransitionArray> Map::SetElementsTransitionMap( |
| 2369 Handle<Map> map, Handle<Map> transitioned_map) { |
| 2370 Handle<TransitionArray> transitions = Map::AddTransition( |
| 2371 map, |
| 2372 map->GetIsolate()->factory()->elements_transition_symbol(), |
| 2373 transitioned_map, |
| 2374 FULL_TRANSITION); |
| 2375 map->set_transitions(*transitions); |
| 2376 return transitions; |
| 2377 } |
| 2378 |
| 2379 |
2395 // To migrate an instance to a map: | 2380 // To migrate an instance to a map: |
2396 // - First check whether the instance needs to be rewritten. If not, simply | 2381 // - First check whether the instance needs to be rewritten. If not, simply |
2397 // change the map. | 2382 // change the map. |
2398 // - Otherwise, allocate a fixed array large enough to hold all fields, in | 2383 // - Otherwise, allocate a fixed array large enough to hold all fields, in |
2399 // addition to unused space. | 2384 // addition to unused space. |
2400 // - Copy all existing properties in, in the following order: backing store | 2385 // - Copy all existing properties in, in the following order: backing store |
2401 // properties, unused fields, inobject properties. | 2386 // properties, unused fields, inobject properties. |
2402 // - If all allocation succeeded, commit the state atomically: | 2387 // - If all allocation succeeded, commit the state atomically: |
2403 // * Copy inobject properties from the backing store back into the object. | 2388 // * Copy inobject properties from the backing store back into the object. |
2404 // * Trim the difference in instance size of the object. This also cleanly | 2389 // * Trim the difference in instance size of the object. This also cleanly |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2509 // thread can not get confused with the filler creation. No synchronization | 2494 // thread can not get confused with the filler creation. No synchronization |
2510 // needed. | 2495 // needed. |
2511 object->set_map(*new_map); | 2496 object->set_map(*new_map); |
2512 } | 2497 } |
2513 | 2498 |
2514 | 2499 |
2515 Handle<TransitionArray> Map::AddTransition(Handle<Map> map, | 2500 Handle<TransitionArray> Map::AddTransition(Handle<Map> map, |
2516 Handle<Name> key, | 2501 Handle<Name> key, |
2517 Handle<Map> target, | 2502 Handle<Map> target, |
2518 SimpleTransitionFlag flag) { | 2503 SimpleTransitionFlag flag) { |
2519 CALL_HEAP_FUNCTION(map->GetIsolate(), | 2504 if (map->HasTransitionArray()) { |
2520 map->AddTransition(*key, *target, flag), | 2505 return TransitionArray::CopyInsert(map, key, target); |
2521 TransitionArray); | 2506 } |
| 2507 return TransitionArray::NewWith( |
| 2508 flag, key, target, handle(map->GetBackPointer(), map->GetIsolate())); |
2522 } | 2509 } |
2523 | 2510 |
2524 | 2511 |
2525 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, | 2512 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, |
2526 int modify_index, | 2513 int modify_index, |
2527 Representation new_representation, | 2514 Representation new_representation, |
2528 StoreMode store_mode) { | 2515 StoreMode store_mode) { |
2529 Handle<Map> new_map = Map::GeneralizeRepresentation( | 2516 Handle<Map> new_map = Map::GeneralizeRepresentation( |
2530 handle(object->map()), modify_index, new_representation, store_mode); | 2517 handle(object->map()), modify_index, new_representation, store_mode); |
2531 if (object->map() == *new_map) return; | 2518 if (object->map() == *new_map) return; |
(...skipping 17 matching lines...) Expand all Loading... |
2549 PropertyAttributes attributes, | 2536 PropertyAttributes attributes, |
2550 const char* reason) { | 2537 const char* reason) { |
2551 Handle<Map> new_map = Copy(map); | 2538 Handle<Map> new_map = Copy(map); |
2552 | 2539 |
2553 DescriptorArray* descriptors = new_map->instance_descriptors(); | 2540 DescriptorArray* descriptors = new_map->instance_descriptors(); |
2554 descriptors->InitializeRepresentations(Representation::Tagged()); | 2541 descriptors->InitializeRepresentations(Representation::Tagged()); |
2555 | 2542 |
2556 // Unless the instance is being migrated, ensure that modify_index is a field. | 2543 // Unless the instance is being migrated, ensure that modify_index is a field. |
2557 PropertyDetails details = descriptors->GetDetails(modify_index); | 2544 PropertyDetails details = descriptors->GetDetails(modify_index); |
2558 if (store_mode == FORCE_FIELD && details.type() != FIELD) { | 2545 if (store_mode == FORCE_FIELD && details.type() != FIELD) { |
2559 FieldDescriptor d(descriptors->GetKey(modify_index), | 2546 FieldDescriptor d(handle(descriptors->GetKey(modify_index), |
| 2547 map->GetIsolate()), |
2560 new_map->NumberOfFields(), | 2548 new_map->NumberOfFields(), |
2561 attributes, | 2549 attributes, |
2562 Representation::Tagged()); | 2550 Representation::Tagged()); |
2563 d.SetSortedKeyIndex(details.pointer()); | 2551 d.SetSortedKeyIndex(details.pointer()); |
2564 descriptors->Set(modify_index, &d); | 2552 descriptors->Set(modify_index, &d); |
2565 int unused_property_fields = new_map->unused_property_fields() - 1; | 2553 int unused_property_fields = new_map->unused_property_fields() - 1; |
2566 if (unused_property_fields < 0) { | 2554 if (unused_property_fields < 0) { |
2567 unused_property_fields += JSObject::kFieldsAdded; | 2555 unused_property_fields += JSObject::kFieldsAdded; |
2568 } | 2556 } |
2569 new_map->set_unused_property_fields(unused_property_fields); | 2557 new_map->set_unused_property_fields(unused_property_fields); |
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3165 Handle<String> key = | 3153 Handle<String> key = |
3166 isolate->factory()->InternalizeString( | 3154 isolate->factory()->InternalizeString( |
3167 Handle<String>(String::cast(entry->name()))); | 3155 Handle<String>(String::cast(entry->name()))); |
3168 entry->set_name(*key); | 3156 entry->set_name(*key); |
3169 } | 3157 } |
3170 | 3158 |
3171 // Fill in new callback descriptors. Process the callbacks from | 3159 // Fill in new callback descriptors. Process the callbacks from |
3172 // back to front so that the last callback with a given name takes | 3160 // back to front so that the last callback with a given name takes |
3173 // precedence over previously added callbacks with that name. | 3161 // precedence over previously added callbacks with that name. |
3174 for (int i = nof_callbacks - 1; i >= 0; i--) { | 3162 for (int i = nof_callbacks - 1; i >= 0; i--) { |
3175 AccessorInfo* entry = AccessorInfo::cast(callbacks->get(i)); | 3163 Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks->get(i))); |
3176 Name* key = Name::cast(entry->name()); | 3164 Handle<Name> key(Name::cast(entry->name())); |
3177 // Check if a descriptor with this name already exists before writing. | 3165 // Check if a descriptor with this name already exists before writing. |
3178 if (!T::Contains(key, entry, valid_descriptors, array)) { | 3166 if (!T::Contains(key, entry, valid_descriptors, array)) { |
3179 T::Insert(key, entry, valid_descriptors, array); | 3167 T::Insert(key, entry, valid_descriptors, array); |
3180 valid_descriptors++; | 3168 valid_descriptors++; |
3181 } | 3169 } |
3182 } | 3170 } |
3183 | 3171 |
3184 return valid_descriptors; | 3172 return valid_descriptors; |
3185 } | 3173 } |
3186 | 3174 |
3187 struct DescriptorArrayAppender { | 3175 struct DescriptorArrayAppender { |
3188 typedef DescriptorArray Array; | 3176 typedef DescriptorArray Array; |
3189 static bool Contains(Name* key, | 3177 static bool Contains(Handle<Name> key, |
3190 AccessorInfo* entry, | 3178 Handle<AccessorInfo> entry, |
3191 int valid_descriptors, | 3179 int valid_descriptors, |
3192 Handle<DescriptorArray> array) { | 3180 Handle<DescriptorArray> array) { |
3193 return array->Search(key, valid_descriptors) != DescriptorArray::kNotFound; | 3181 DisallowHeapAllocation no_gc; |
| 3182 return array->Search(*key, valid_descriptors) != DescriptorArray::kNotFound; |
3194 } | 3183 } |
3195 static void Insert(Name* key, | 3184 static void Insert(Handle<Name> key, |
3196 AccessorInfo* entry, | 3185 Handle<AccessorInfo> entry, |
3197 int valid_descriptors, | 3186 int valid_descriptors, |
3198 Handle<DescriptorArray> array) { | 3187 Handle<DescriptorArray> array) { |
| 3188 DisallowHeapAllocation no_gc; |
3199 CallbacksDescriptor desc(key, entry, entry->property_attributes()); | 3189 CallbacksDescriptor desc(key, entry, entry->property_attributes()); |
3200 array->Append(&desc); | 3190 array->Append(&desc); |
3201 } | 3191 } |
3202 }; | 3192 }; |
3203 | 3193 |
3204 | 3194 |
3205 struct FixedArrayAppender { | 3195 struct FixedArrayAppender { |
3206 typedef FixedArray Array; | 3196 typedef FixedArray Array; |
3207 static bool Contains(Name* key, | 3197 static bool Contains(Handle<Name> key, |
3208 AccessorInfo* entry, | 3198 Handle<AccessorInfo> entry, |
3209 int valid_descriptors, | 3199 int valid_descriptors, |
3210 Handle<FixedArray> array) { | 3200 Handle<FixedArray> array) { |
3211 for (int i = 0; i < valid_descriptors; i++) { | 3201 for (int i = 0; i < valid_descriptors; i++) { |
3212 if (key == AccessorInfo::cast(array->get(i))->name()) return true; | 3202 if (*key == AccessorInfo::cast(array->get(i))->name()) return true; |
3213 } | 3203 } |
3214 return false; | 3204 return false; |
3215 } | 3205 } |
3216 static void Insert(Name* key, | 3206 static void Insert(Handle<Name> key, |
3217 AccessorInfo* entry, | 3207 Handle<AccessorInfo> entry, |
3218 int valid_descriptors, | 3208 int valid_descriptors, |
3219 Handle<FixedArray> array) { | 3209 Handle<FixedArray> array) { |
3220 array->set(valid_descriptors, entry); | 3210 DisallowHeapAllocation no_gc; |
| 3211 array->set(valid_descriptors, *entry); |
3221 } | 3212 } |
3222 }; | 3213 }; |
3223 | 3214 |
3224 | 3215 |
3225 void Map::AppendCallbackDescriptors(Handle<Map> map, | 3216 void Map::AppendCallbackDescriptors(Handle<Map> map, |
3226 Handle<Object> descriptors) { | 3217 Handle<Object> descriptors) { |
3227 int nof = map->NumberOfOwnDescriptors(); | 3218 int nof = map->NumberOfOwnDescriptors(); |
3228 Handle<DescriptorArray> array(map->instance_descriptors()); | 3219 Handle<DescriptorArray> array(map->instance_descriptors()); |
3229 NeanderArray callbacks(descriptors); | 3220 NeanderArray callbacks(descriptors); |
3230 ASSERT(array->NumberOfSlackDescriptors() >= callbacks.length()); | 3221 ASSERT(array->NumberOfSlackDescriptors() >= callbacks.length()); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3328 } | 3319 } |
3329 | 3320 |
3330 if (isolate->initial_object_prototype()->map() == this) { | 3321 if (isolate->initial_object_prototype()->map() == this) { |
3331 return true; | 3322 return true; |
3332 } | 3323 } |
3333 | 3324 |
3334 return false; | 3325 return false; |
3335 } | 3326 } |
3336 | 3327 |
3337 | 3328 |
3338 static MaybeObject* AddMissingElementsTransitions(Map* map, | 3329 static Handle<Map> AddMissingElementsTransitions(Handle<Map> map, |
3339 ElementsKind to_kind) { | 3330 ElementsKind to_kind) { |
3340 ASSERT(IsTransitionElementsKind(map->elements_kind())); | 3331 ASSERT(IsTransitionElementsKind(map->elements_kind())); |
3341 | 3332 |
3342 Map* current_map = map; | 3333 Handle<Map> current_map = map; |
3343 | 3334 |
3344 ElementsKind kind = map->elements_kind(); | 3335 ElementsKind kind = map->elements_kind(); |
3345 while (kind != to_kind && !IsTerminalElementsKind(kind)) { | 3336 while (kind != to_kind && !IsTerminalElementsKind(kind)) { |
3346 kind = GetNextTransitionElementsKind(kind); | 3337 kind = GetNextTransitionElementsKind(kind); |
3347 MaybeObject* maybe_next_map = | 3338 current_map = Map::CopyAsElementsKind( |
3348 current_map->CopyAsElementsKind(kind, INSERT_TRANSITION); | 3339 current_map, kind, INSERT_TRANSITION); |
3349 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; | |
3350 } | 3340 } |
3351 | 3341 |
3352 // In case we are exiting the fast elements kind system, just add the map in | 3342 // In case we are exiting the fast elements kind system, just add the map in |
3353 // the end. | 3343 // the end. |
3354 if (kind != to_kind) { | 3344 if (kind != to_kind) { |
3355 MaybeObject* maybe_next_map = | 3345 current_map = Map::CopyAsElementsKind( |
3356 current_map->CopyAsElementsKind(to_kind, INSERT_TRANSITION); | 3346 current_map, to_kind, INSERT_TRANSITION); |
3357 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; | |
3358 } | 3347 } |
3359 | 3348 |
3360 ASSERT(current_map->elements_kind() == to_kind); | 3349 ASSERT(current_map->elements_kind() == to_kind); |
3361 return current_map; | 3350 return current_map; |
3362 } | 3351 } |
3363 | 3352 |
3364 | 3353 |
3365 Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object, | 3354 Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object, |
3366 ElementsKind to_kind) { | 3355 ElementsKind to_kind) { |
3367 Isolate* isolate = object->GetIsolate(); | 3356 Isolate* isolate = object->GetIsolate(); |
3368 CALL_HEAP_FUNCTION(isolate, | 3357 Handle<Map> current_map(object->map()); |
3369 object->GetElementsTransitionMap(isolate, to_kind), | 3358 ElementsKind from_kind = current_map->elements_kind(); |
3370 Map); | 3359 if (from_kind == to_kind) return current_map; |
| 3360 |
| 3361 Context* native_context = isolate->context()->native_context(); |
| 3362 Object* maybe_array_maps = native_context->js_array_maps(); |
| 3363 if (maybe_array_maps->IsFixedArray()) { |
| 3364 DisallowHeapAllocation no_gc; |
| 3365 FixedArray* array_maps = FixedArray::cast(maybe_array_maps); |
| 3366 if (array_maps->get(from_kind) == *current_map) { |
| 3367 Object* maybe_transitioned_map = array_maps->get(to_kind); |
| 3368 if (maybe_transitioned_map->IsMap()) { |
| 3369 return handle(Map::cast(maybe_transitioned_map)); |
| 3370 } |
| 3371 } |
| 3372 } |
| 3373 |
| 3374 return GetElementsTransitionMapSlow(object, to_kind); |
3371 } | 3375 } |
3372 | 3376 |
3373 | 3377 |
3374 MaybeObject* JSObject::GetElementsTransitionMapSlow(ElementsKind to_kind) { | 3378 Handle<Map> JSObject::GetElementsTransitionMapSlow(Handle<JSObject> object, |
3375 Map* start_map = map(); | 3379 ElementsKind to_kind) { |
| 3380 Handle<Map> start_map(object->map()); |
3376 ElementsKind from_kind = start_map->elements_kind(); | 3381 ElementsKind from_kind = start_map->elements_kind(); |
3377 | 3382 |
3378 if (from_kind == to_kind) { | 3383 if (from_kind == to_kind) { |
3379 return start_map; | 3384 return start_map; |
3380 } | 3385 } |
3381 | 3386 |
3382 bool allow_store_transition = | 3387 bool allow_store_transition = |
3383 // Only remember the map transition if there is not an already existing | 3388 // Only remember the map transition if there is not an already existing |
3384 // non-matching element transition. | 3389 // non-matching element transition. |
3385 !start_map->IsUndefined() && !start_map->is_shared() && | 3390 !start_map->IsUndefined() && !start_map->is_shared() && |
3386 IsTransitionElementsKind(from_kind); | 3391 IsTransitionElementsKind(from_kind); |
3387 | 3392 |
3388 // Only store fast element maps in ascending generality. | 3393 // Only store fast element maps in ascending generality. |
3389 if (IsFastElementsKind(to_kind)) { | 3394 if (IsFastElementsKind(to_kind)) { |
3390 allow_store_transition &= | 3395 allow_store_transition &= |
3391 IsTransitionableFastElementsKind(from_kind) && | 3396 IsTransitionableFastElementsKind(from_kind) && |
3392 IsMoreGeneralElementsKindTransition(from_kind, to_kind); | 3397 IsMoreGeneralElementsKindTransition(from_kind, to_kind); |
3393 } | 3398 } |
3394 | 3399 |
3395 if (!allow_store_transition) { | 3400 if (!allow_store_transition) { |
3396 return start_map->CopyAsElementsKind(to_kind, OMIT_TRANSITION); | 3401 return Map::CopyAsElementsKind(start_map, to_kind, OMIT_TRANSITION); |
3397 } | 3402 } |
3398 | 3403 |
3399 return start_map->AsElementsKind(to_kind); | 3404 return Map::AsElementsKind(start_map, to_kind); |
3400 } | 3405 } |
3401 | 3406 |
3402 | 3407 |
3403 // TODO(ishell): Temporary wrapper until handlified. | |
3404 // static | 3408 // static |
3405 Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) { | 3409 Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) { |
3406 CALL_HEAP_FUNCTION(map->GetIsolate(), | 3410 Handle<Map> closest_map(FindClosestElementsTransition(*map, kind)); |
3407 map->AsElementsKind(kind), | |
3408 Map); | |
3409 } | |
3410 | |
3411 | |
3412 MaybeObject* Map::AsElementsKind(ElementsKind kind) { | |
3413 Map* closest_map = FindClosestElementsTransition(this, kind); | |
3414 | 3411 |
3415 if (closest_map->elements_kind() == kind) { | 3412 if (closest_map->elements_kind() == kind) { |
3416 return closest_map; | 3413 return closest_map; |
3417 } | 3414 } |
3418 | 3415 |
3419 return AddMissingElementsTransitions(closest_map, kind); | 3416 return AddMissingElementsTransitions(closest_map, kind); |
3420 } | 3417 } |
3421 | 3418 |
3422 | 3419 |
3423 void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) { | 3420 void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) { |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3891 return isolate->Throw<Object>(error); | 3888 return isolate->Throw<Object>(error); |
3892 } | 3889 } |
3893 trap = Handle<Object>(derived); | 3890 trap = Handle<Object>(derived); |
3894 } | 3891 } |
3895 | 3892 |
3896 bool threw; | 3893 bool threw; |
3897 return Execution::Call(isolate, trap, handler, argc, argv, &threw); | 3894 return Execution::Call(isolate, trap, handler, argc, argv, &threw); |
3898 } | 3895 } |
3899 | 3896 |
3900 | 3897 |
3901 // TODO(mstarzinger): Temporary wrapper until handlified. | |
3902 static Handle<Map> MapAsElementsKind(Handle<Map> map, ElementsKind kind) { | |
3903 CALL_HEAP_FUNCTION(map->GetIsolate(), map->AsElementsKind(kind), Map); | |
3904 } | |
3905 | |
3906 | |
3907 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) { | 3898 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) { |
3908 ASSERT(object->map()->inobject_properties() == map->inobject_properties()); | 3899 ASSERT(object->map()->inobject_properties() == map->inobject_properties()); |
3909 ElementsKind obj_kind = object->map()->elements_kind(); | 3900 ElementsKind obj_kind = object->map()->elements_kind(); |
3910 ElementsKind map_kind = map->elements_kind(); | 3901 ElementsKind map_kind = map->elements_kind(); |
3911 if (map_kind != obj_kind) { | 3902 if (map_kind != obj_kind) { |
3912 ElementsKind to_kind = map_kind; | 3903 ElementsKind to_kind = map_kind; |
3913 if (IsMoreGeneralElementsKindTransition(map_kind, obj_kind) || | 3904 if (IsMoreGeneralElementsKindTransition(map_kind, obj_kind) || |
3914 IsDictionaryElementsKind(obj_kind)) { | 3905 IsDictionaryElementsKind(obj_kind)) { |
3915 to_kind = obj_kind; | 3906 to_kind = obj_kind; |
3916 } | 3907 } |
3917 if (IsDictionaryElementsKind(to_kind)) { | 3908 if (IsDictionaryElementsKind(to_kind)) { |
3918 NormalizeElements(object); | 3909 NormalizeElements(object); |
3919 } else { | 3910 } else { |
3920 TransitionElementsKind(object, to_kind); | 3911 TransitionElementsKind(object, to_kind); |
3921 } | 3912 } |
3922 map = MapAsElementsKind(map, to_kind); | 3913 map = Map::AsElementsKind(map, to_kind); |
3923 } | 3914 } |
3924 JSObject::MigrateToMap(object, map); | 3915 JSObject::MigrateToMap(object, map); |
3925 } | 3916 } |
3926 | 3917 |
3927 | 3918 |
3928 void JSObject::MigrateInstance(Handle<JSObject> object) { | 3919 void JSObject::MigrateInstance(Handle<JSObject> object) { |
3929 // Converting any field to the most specific type will cause the | 3920 // Converting any field to the most specific type will cause the |
3930 // GeneralizeFieldRepresentation algorithm to create the most general existing | 3921 // GeneralizeFieldRepresentation algorithm to create the most general existing |
3931 // transition that matches the object. This achieves what is needed. | 3922 // transition that matches the object. This achieves what is needed. |
3932 Handle<Map> original_map(object->map()); | 3923 Handle<Map> original_map(object->map()); |
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4751 if (object->HasFastProperties()) return; | 4742 if (object->HasFastProperties()) return; |
4752 ASSERT(!object->IsGlobalObject()); | 4743 ASSERT(!object->IsGlobalObject()); |
4753 CALL_HEAP_FUNCTION_VOID( | 4744 CALL_HEAP_FUNCTION_VOID( |
4754 object->GetIsolate(), | 4745 object->GetIsolate(), |
4755 object->property_dictionary()->TransformPropertiesToFastFor( | 4746 object->property_dictionary()->TransformPropertiesToFastFor( |
4756 *object, unused_property_fields)); | 4747 *object, unused_property_fields)); |
4757 } | 4748 } |
4758 | 4749 |
4759 | 4750 |
4760 void JSObject::ResetElements(Handle<JSObject> object) { | 4751 void JSObject::ResetElements(Handle<JSObject> object) { |
4761 CALL_HEAP_FUNCTION_VOID( | 4752 if (object->map()->is_observed()) { |
4762 object->GetIsolate(), | 4753 // Maintain invariant that observed elements are always in dictionary mode. |
4763 object->ResetElements()); | 4754 Factory* factory = object->GetIsolate()->factory(); |
| 4755 Handle<SeededNumberDictionary> dictionary = |
| 4756 factory->NewSeededNumberDictionary(0); |
| 4757 if (object->map() == *factory->sloppy_arguments_elements_map()) { |
| 4758 FixedArray::cast(object->elements())->set(1, *dictionary); |
| 4759 } else { |
| 4760 object->set_elements(*dictionary); |
| 4761 } |
| 4762 return; |
| 4763 } |
| 4764 |
| 4765 ElementsKind elements_kind = GetInitialFastElementsKind(); |
| 4766 if (!FLAG_smi_only_arrays) { |
| 4767 elements_kind = FastSmiToObjectElementsKind(elements_kind); |
| 4768 } |
| 4769 Handle<Map> map = JSObject::GetElementsTransitionMap(object, elements_kind); |
| 4770 DisallowHeapAllocation no_gc; |
| 4771 Handle<FixedArrayBase> elements(map->GetInitialElements()); |
| 4772 JSObject::SetMapAndElements(object, map, elements); |
4764 } | 4773 } |
4765 | 4774 |
4766 | 4775 |
4767 static Handle<SeededNumberDictionary> CopyFastElementsToDictionary( | 4776 static Handle<SeededNumberDictionary> CopyFastElementsToDictionary( |
4768 Handle<FixedArrayBase> array, | 4777 Handle<FixedArrayBase> array, |
4769 int length, | 4778 int length, |
4770 Handle<SeededNumberDictionary> dictionary) { | 4779 Handle<SeededNumberDictionary> dictionary) { |
4771 Isolate* isolate = array->GetIsolate(); | 4780 Isolate* isolate = array->GetIsolate(); |
4772 Factory* factory = isolate->factory(); | 4781 Factory* factory = isolate->factory(); |
4773 bool has_double_elements = array->IsFixedDoubleArray(); | 4782 bool has_double_elements = array->IsFixedDoubleArray(); |
(...skipping 1708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6482 JSObject::MigrateToMap(self, transitioned_map); | 6491 JSObject::MigrateToMap(self, transitioned_map); |
6483 return true; | 6492 return true; |
6484 } | 6493 } |
6485 | 6494 |
6486 // If either not the same accessor, or not the same attributes, fall back to | 6495 // If either not the same accessor, or not the same attributes, fall back to |
6487 // the slow case. | 6496 // the slow case. |
6488 return false; | 6497 return false; |
6489 } | 6498 } |
6490 | 6499 |
6491 | 6500 |
6492 static MaybeObject* CopyInsertDescriptor(Map* map, | |
6493 Name* name, | |
6494 AccessorPair* accessors, | |
6495 PropertyAttributes attributes) { | |
6496 CallbacksDescriptor new_accessors_desc(name, accessors, attributes); | |
6497 return map->CopyInsertDescriptor(&new_accessors_desc, INSERT_TRANSITION); | |
6498 } | |
6499 | |
6500 | |
6501 static Handle<Map> CopyInsertDescriptor(Handle<Map> map, | 6501 static Handle<Map> CopyInsertDescriptor(Handle<Map> map, |
6502 Handle<Name> name, | 6502 Handle<Name> name, |
6503 Handle<AccessorPair> accessors, | 6503 Handle<AccessorPair> accessors, |
6504 PropertyAttributes attributes) { | 6504 PropertyAttributes attributes) { |
6505 CALL_HEAP_FUNCTION(map->GetIsolate(), | 6505 CallbacksDescriptor new_accessors_desc(name, accessors, attributes); |
6506 CopyInsertDescriptor(*map, *name, *accessors, attributes), | 6506 return Map::CopyInsertDescriptor(map, &new_accessors_desc, INSERT_TRANSITION); |
6507 Map); | |
6508 } | 6507 } |
6509 | 6508 |
6510 | 6509 |
6511 bool JSObject::DefineFastAccessor(Handle<JSObject> object, | 6510 bool JSObject::DefineFastAccessor(Handle<JSObject> object, |
6512 Handle<Name> name, | 6511 Handle<Name> name, |
6513 AccessorComponent component, | 6512 AccessorComponent component, |
6514 Handle<Object> accessor, | 6513 Handle<Object> accessor, |
6515 PropertyAttributes attributes) { | 6514 PropertyAttributes attributes) { |
6516 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); | 6515 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); |
6517 Isolate* isolate = object->GetIsolate(); | 6516 Isolate* isolate = object->GetIsolate(); |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6824 result->set_unused_property_fields(unused_property_fields()); | 6823 result->set_unused_property_fields(unused_property_fields()); |
6825 | 6824 |
6826 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); | 6825 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); |
6827 result->set_is_shared(false); | 6826 result->set_is_shared(false); |
6828 result->ClearCodeCache(GetHeap()); | 6827 result->ClearCodeCache(GetHeap()); |
6829 NotifyLeafMapLayoutChange(); | 6828 NotifyLeafMapLayoutChange(); |
6830 return result; | 6829 return result; |
6831 } | 6830 } |
6832 | 6831 |
6833 | 6832 |
6834 MaybeObject* Map::ShareDescriptor(DescriptorArray* descriptors, | 6833 Handle<Map> Map::ShareDescriptor(Handle<Map> map, |
6835 Descriptor* descriptor) { | 6834 Handle<DescriptorArray> descriptors, |
| 6835 Descriptor* descriptor) { |
6836 // Sanity check. This path is only to be taken if the map owns its descriptor | 6836 // Sanity check. This path is only to be taken if the map owns its descriptor |
6837 // array, implying that its NumberOfOwnDescriptors equals the number of | 6837 // array, implying that its NumberOfOwnDescriptors equals the number of |
6838 // descriptors in the descriptor array. | 6838 // descriptors in the descriptor array. |
6839 ASSERT(NumberOfOwnDescriptors() == | 6839 ASSERT(map->NumberOfOwnDescriptors() == |
6840 instance_descriptors()->number_of_descriptors()); | 6840 map->instance_descriptors()->number_of_descriptors()); |
6841 Map* result; | 6841 Handle<Map> result = Map::CopyDropDescriptors(map); |
6842 MaybeObject* maybe_result = CopyDropDescriptors(); | |
6843 if (!maybe_result->To(&result)) return maybe_result; | |
6844 | 6842 |
6845 Name* name = descriptor->GetKey(); | 6843 Handle<Name> name = descriptor->GetKey(); |
6846 | 6844 |
6847 TransitionArray* transitions; | 6845 Handle<TransitionArray> transitions = |
6848 MaybeObject* maybe_transitions = | 6846 Map::AddTransition(map, name, result, SIMPLE_TRANSITION); |
6849 AddTransition(name, result, SIMPLE_TRANSITION); | |
6850 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | |
6851 | |
6852 int old_size = descriptors->number_of_descriptors(); | |
6853 | |
6854 DescriptorArray* new_descriptors; | |
6855 | 6847 |
6856 if (descriptors->NumberOfSlackDescriptors() > 0) { | 6848 if (descriptors->NumberOfSlackDescriptors() > 0) { |
6857 new_descriptors = descriptors; | 6849 descriptors->Append(descriptor); |
6858 new_descriptors->Append(descriptor); | 6850 result->SetBackPointer(*map); |
| 6851 result->InitializeDescriptors(*descriptors); |
6859 } else { | 6852 } else { |
| 6853 int old_size = descriptors->number_of_descriptors(); |
6860 // Descriptor arrays grow by 50%. | 6854 // Descriptor arrays grow by 50%. |
6861 MaybeObject* maybe_descriptors = DescriptorArray::Allocate( | 6855 Handle<DescriptorArray> new_descriptors = |
6862 GetIsolate(), old_size, old_size < 4 ? 1 : old_size / 2); | 6856 map->GetIsolate()->factory()->NewDescriptorArray( |
6863 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; | 6857 old_size, old_size < 4 ? 1 : old_size / 2); |
6864 | 6858 |
6865 DescriptorArray::WhitenessWitness witness(new_descriptors); | 6859 DisallowHeapAllocation no_gc; |
| 6860 DescriptorArray::WhitenessWitness witness(*new_descriptors); |
6866 | 6861 |
6867 // Copy the descriptors, inserting a descriptor. | 6862 // Copy the descriptors, inserting a descriptor. |
6868 for (int i = 0; i < old_size; ++i) { | 6863 for (int i = 0; i < old_size; ++i) { |
6869 new_descriptors->CopyFrom(i, descriptors, i, witness); | 6864 new_descriptors->CopyFrom(i, *descriptors, i, witness); |
6870 } | 6865 } |
6871 | 6866 |
6872 new_descriptors->Append(descriptor, witness); | 6867 new_descriptors->Append(descriptor, witness); |
6873 | 6868 |
6874 if (old_size > 0) { | 6869 if (old_size > 0) { |
6875 // If the source descriptors had an enum cache we copy it. This ensures | 6870 // If the source descriptors had an enum cache we copy it. This ensures |
6876 // that the maps to which we push the new descriptor array back can rely | 6871 // that the maps to which we push the new descriptor array back can rely |
6877 // on a cache always being available once it is set. If the map has more | 6872 // on a cache always being available once it is set. If the map has more |
6878 // enumerated descriptors than available in the original cache, the cache | 6873 // enumerated descriptors than available in the original cache, the cache |
6879 // will be lazily replaced by the extended cache when needed. | 6874 // will be lazily replaced by the extended cache when needed. |
6880 if (descriptors->HasEnumCache()) { | 6875 if (descriptors->HasEnumCache()) { |
6881 new_descriptors->CopyEnumCacheFrom(descriptors); | 6876 new_descriptors->CopyEnumCacheFrom(*descriptors); |
6882 } | 6877 } |
6883 | 6878 |
6884 Map* map; | 6879 Map* walk_map; |
6885 // Replace descriptors by new_descriptors in all maps that share it. | 6880 // Replace descriptors by new_descriptors in all maps that share it. |
6886 | 6881 |
6887 GetHeap()->incremental_marking()->RecordWrites(descriptors); | 6882 map->GetHeap()->incremental_marking()->RecordWrites(*descriptors); |
6888 for (Object* current = GetBackPointer(); | 6883 for (Object* current = map->GetBackPointer(); |
6889 !current->IsUndefined(); | 6884 !current->IsUndefined(); |
6890 current = map->GetBackPointer()) { | 6885 current = walk_map->GetBackPointer()) { |
6891 map = Map::cast(current); | 6886 walk_map = Map::cast(current); |
6892 if (map->instance_descriptors() != descriptors) break; | 6887 if (walk_map->instance_descriptors() != *descriptors) break; |
6893 map->set_instance_descriptors(new_descriptors); | 6888 walk_map->set_instance_descriptors(*new_descriptors); |
6894 } | 6889 } |
6895 | 6890 |
6896 set_instance_descriptors(new_descriptors); | 6891 map->set_instance_descriptors(*new_descriptors); |
6897 } | 6892 } |
| 6893 |
| 6894 result->SetBackPointer(*map); |
| 6895 result->InitializeDescriptors(*new_descriptors); |
6898 } | 6896 } |
6899 | 6897 |
6900 result->SetBackPointer(this); | 6898 ASSERT(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); |
6901 result->InitializeDescriptors(new_descriptors); | |
6902 ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1); | |
6903 | 6899 |
6904 set_transitions(transitions); | 6900 map->set_transitions(*transitions); |
6905 set_owns_descriptors(false); | 6901 map->set_owns_descriptors(false); |
6906 | 6902 |
6907 return result; | 6903 return result; |
6908 } | 6904 } |
6909 | 6905 |
6910 | 6906 |
6911 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, | 6907 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, |
6912 Handle<DescriptorArray> descriptors, | 6908 Handle<DescriptorArray> descriptors, |
6913 TransitionFlag flag, | 6909 TransitionFlag flag, |
6914 Handle<Name> name) { | 6910 SimpleTransitionFlag simple_flag) { |
6915 CALL_HEAP_FUNCTION(map->GetIsolate(), | 6911 return Map::CopyReplaceDescriptors( |
6916 map->CopyReplaceDescriptors(*descriptors, flag, *name), | 6912 map, descriptors, flag, Handle<Name>::null(), simple_flag); |
6917 Map); | |
6918 } | 6913 } |
6919 | 6914 |
6920 | 6915 |
6921 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, | 6916 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, |
6922 TransitionFlag flag, | 6917 Handle<DescriptorArray> descriptors, |
6923 Name* name, | 6918 TransitionFlag flag, |
6924 SimpleTransitionFlag simple_flag) { | 6919 Handle<Name> name, |
| 6920 SimpleTransitionFlag simple_flag) { |
6925 ASSERT(descriptors->IsSortedNoDuplicates()); | 6921 ASSERT(descriptors->IsSortedNoDuplicates()); |
6926 | 6922 |
6927 Map* result; | 6923 Handle<Map> result = CopyDropDescriptors(map); |
6928 MaybeObject* maybe_result = CopyDropDescriptors(); | 6924 result->InitializeDescriptors(*descriptors); |
6929 if (!maybe_result->To(&result)) return maybe_result; | |
6930 | 6925 |
6931 result->InitializeDescriptors(descriptors); | 6926 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { |
6932 | 6927 Handle<TransitionArray> transitions = Map::AddTransition( |
6933 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) { | 6928 map, name, result, simple_flag); |
6934 TransitionArray* transitions; | 6929 map->set_transitions(*transitions); |
6935 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag); | 6930 result->SetBackPointer(*map); |
6936 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | |
6937 set_transitions(transitions); | |
6938 result->SetBackPointer(this); | |
6939 } else { | 6931 } else { |
6940 descriptors->InitializeRepresentations(Representation::Tagged()); | 6932 descriptors->InitializeRepresentations(Representation::Tagged()); |
6941 } | 6933 } |
6942 | 6934 |
6943 return result; | 6935 return result; |
6944 } | 6936 } |
6945 | 6937 |
6946 | 6938 |
6947 // Since this method is used to rewrite an existing transition tree, it can | 6939 // Since this method is used to rewrite an existing transition tree, it can |
6948 // always insert transitions without checking. | 6940 // always insert transitions without checking. |
(...skipping 22 matching lines...) Expand all Loading... |
6971 Handle<TransitionArray> transitions = Map::AddTransition(map, name, result, | 6963 Handle<TransitionArray> transitions = Map::AddTransition(map, name, result, |
6972 SIMPLE_TRANSITION); | 6964 SIMPLE_TRANSITION); |
6973 | 6965 |
6974 map->set_transitions(*transitions); | 6966 map->set_transitions(*transitions); |
6975 result->SetBackPointer(*map); | 6967 result->SetBackPointer(*map); |
6976 | 6968 |
6977 return result; | 6969 return result; |
6978 } | 6970 } |
6979 | 6971 |
6980 | 6972 |
6981 MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) { | 6973 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, |
| 6974 TransitionFlag flag) { |
6982 if (flag == INSERT_TRANSITION) { | 6975 if (flag == INSERT_TRANSITION) { |
6983 ASSERT(!HasElementsTransition() || | 6976 ASSERT(!map->HasElementsTransition() || |
6984 ((elements_transition_map()->elements_kind() == DICTIONARY_ELEMENTS || | 6977 ((map->elements_transition_map()->elements_kind() == |
| 6978 DICTIONARY_ELEMENTS || |
6985 IsExternalArrayElementsKind( | 6979 IsExternalArrayElementsKind( |
6986 elements_transition_map()->elements_kind())) && | 6980 map->elements_transition_map()->elements_kind())) && |
6987 (kind == DICTIONARY_ELEMENTS || | 6981 (kind == DICTIONARY_ELEMENTS || |
6988 IsExternalArrayElementsKind(kind)))); | 6982 IsExternalArrayElementsKind(kind)))); |
6989 ASSERT(!IsFastElementsKind(kind) || | 6983 ASSERT(!IsFastElementsKind(kind) || |
6990 IsMoreGeneralElementsKindTransition(elements_kind(), kind)); | 6984 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind)); |
6991 ASSERT(kind != elements_kind()); | 6985 ASSERT(kind != map->elements_kind()); |
6992 } | 6986 } |
6993 | 6987 |
6994 bool insert_transition = | 6988 bool insert_transition = |
6995 flag == INSERT_TRANSITION && !HasElementsTransition(); | 6989 flag == INSERT_TRANSITION && !map->HasElementsTransition(); |
6996 | 6990 |
6997 if (insert_transition && owns_descriptors()) { | 6991 if (insert_transition && map->owns_descriptors()) { |
6998 // In case the map owned its own descriptors, share the descriptors and | 6992 // In case the map owned its own descriptors, share the descriptors and |
6999 // transfer ownership to the new map. | 6993 // transfer ownership to the new map. |
7000 Map* new_map; | 6994 Handle<Map> new_map = Map::CopyDropDescriptors(map); |
7001 MaybeObject* maybe_new_map = CopyDropDescriptors(); | |
7002 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | |
7003 | 6995 |
7004 MaybeObject* added_elements = set_elements_transition_map(new_map); | 6996 SetElementsTransitionMap(map, new_map); |
7005 if (added_elements->IsFailure()) return added_elements; | |
7006 | 6997 |
7007 new_map->set_elements_kind(kind); | 6998 new_map->set_elements_kind(kind); |
7008 new_map->InitializeDescriptors(instance_descriptors()); | 6999 new_map->InitializeDescriptors(map->instance_descriptors()); |
7009 new_map->SetBackPointer(this); | 7000 new_map->SetBackPointer(*map); |
7010 set_owns_descriptors(false); | 7001 map->set_owns_descriptors(false); |
7011 return new_map; | 7002 return new_map; |
7012 } | 7003 } |
7013 | 7004 |
7014 // In case the map did not own its own descriptors, a split is forced by | 7005 // In case the map did not own its own descriptors, a split is forced by |
7015 // copying the map; creating a new descriptor array cell. | 7006 // copying the map; creating a new descriptor array cell. |
7016 // Create a new free-floating map only if we are not allowed to store it. | 7007 // Create a new free-floating map only if we are not allowed to store it. |
7017 Map* new_map; | 7008 Handle<Map> new_map = Map::Copy(map); |
7018 MaybeObject* maybe_new_map = Copy(); | |
7019 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | |
7020 | 7009 |
7021 new_map->set_elements_kind(kind); | 7010 new_map->set_elements_kind(kind); |
7022 | 7011 |
7023 if (insert_transition) { | 7012 if (insert_transition) { |
7024 MaybeObject* added_elements = set_elements_transition_map(new_map); | 7013 SetElementsTransitionMap(map, new_map); |
7025 if (added_elements->IsFailure()) return added_elements; | 7014 new_map->SetBackPointer(*map); |
7026 new_map->SetBackPointer(this); | |
7027 } | 7015 } |
7028 | 7016 |
7029 return new_map; | 7017 return new_map; |
7030 } | 7018 } |
7031 | 7019 |
7032 | 7020 |
7033 Handle<Map> Map::CopyForObserved(Handle<Map> map) { | 7021 Handle<Map> Map::CopyForObserved(Handle<Map> map) { |
7034 ASSERT(!map->is_observed()); | 7022 ASSERT(!map->is_observed()); |
7035 | 7023 |
7036 Isolate* isolate = map->GetIsolate(); | 7024 Isolate* isolate = map->GetIsolate(); |
(...skipping 19 matching lines...) Expand all Loading... |
7056 new_map->InitializeDescriptors(map->instance_descriptors()); | 7044 new_map->InitializeDescriptors(map->instance_descriptors()); |
7057 map->set_owns_descriptors(false); | 7045 map->set_owns_descriptors(false); |
7058 } | 7046 } |
7059 | 7047 |
7060 new_map->SetBackPointer(*map); | 7048 new_map->SetBackPointer(*map); |
7061 return new_map; | 7049 return new_map; |
7062 } | 7050 } |
7063 | 7051 |
7064 | 7052 |
7065 Handle<Map> Map::Copy(Handle<Map> map) { | 7053 Handle<Map> Map::Copy(Handle<Map> map) { |
7066 CALL_HEAP_FUNCTION(map->GetIsolate(), map->Copy(), Map); | 7054 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
| 7055 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
| 7056 Handle<DescriptorArray> new_descriptors = |
| 7057 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); |
| 7058 return Map::CopyReplaceDescriptors(map, new_descriptors, OMIT_TRANSITION); |
7067 } | 7059 } |
7068 | 7060 |
7069 | 7061 |
7070 MaybeObject* Map::Copy() { | |
7071 DescriptorArray* descriptors = instance_descriptors(); | |
7072 DescriptorArray* new_descriptors; | |
7073 int number_of_own_descriptors = NumberOfOwnDescriptors(); | |
7074 MaybeObject* maybe_descriptors = | |
7075 descriptors->CopyUpTo(number_of_own_descriptors); | |
7076 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; | |
7077 | |
7078 return CopyReplaceDescriptors(new_descriptors, OMIT_TRANSITION); | |
7079 } | |
7080 | |
7081 | |
7082 Handle<Map> Map::Create(Handle<JSFunction> constructor, | 7062 Handle<Map> Map::Create(Handle<JSFunction> constructor, |
7083 int extra_inobject_properties) { | 7063 int extra_inobject_properties) { |
7084 Handle<Map> copy = Copy(handle(constructor->initial_map())); | 7064 Handle<Map> copy = Copy(handle(constructor->initial_map())); |
7085 | 7065 |
7086 // Check that we do not overflow the instance size when adding the | 7066 // Check that we do not overflow the instance size when adding the |
7087 // extra inobject properties. | 7067 // extra inobject properties. |
7088 int instance_size_delta = extra_inobject_properties * kPointerSize; | 7068 int instance_size_delta = extra_inobject_properties * kPointerSize; |
7089 int max_instance_size_delta = | 7069 int max_instance_size_delta = |
7090 JSObject::kMaxInstanceSize - copy->instance_size(); | 7070 JSObject::kMaxInstanceSize - copy->instance_size(); |
7091 int max_extra_properties = max_instance_size_delta >> kPointerSizeLog2; | 7071 int max_extra_properties = max_instance_size_delta >> kPointerSizeLog2; |
7092 | 7072 |
7093 // If the instance size overflows, we allocate as many properties as we can as | 7073 // If the instance size overflows, we allocate as many properties as we can as |
7094 // inobject properties. | 7074 // inobject properties. |
7095 if (extra_inobject_properties > max_extra_properties) { | 7075 if (extra_inobject_properties > max_extra_properties) { |
7096 instance_size_delta = max_instance_size_delta; | 7076 instance_size_delta = max_instance_size_delta; |
7097 extra_inobject_properties = max_extra_properties; | 7077 extra_inobject_properties = max_extra_properties; |
7098 } | 7078 } |
7099 | 7079 |
7100 // Adjust the map with the extra inobject properties. | 7080 // Adjust the map with the extra inobject properties. |
7101 int inobject_properties = | 7081 int inobject_properties = |
7102 copy->inobject_properties() + extra_inobject_properties; | 7082 copy->inobject_properties() + extra_inobject_properties; |
7103 copy->set_inobject_properties(inobject_properties); | 7083 copy->set_inobject_properties(inobject_properties); |
7104 copy->set_unused_property_fields(inobject_properties); | 7084 copy->set_unused_property_fields(inobject_properties); |
7105 copy->set_instance_size(copy->instance_size() + instance_size_delta); | 7085 copy->set_instance_size(copy->instance_size() + instance_size_delta); |
7106 copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy)); | 7086 copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy)); |
7107 return copy; | 7087 return copy; |
7108 } | 7088 } |
7109 | 7089 |
7110 | 7090 |
7111 MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor, | 7091 Handle<Map> Map::CopyAddDescriptor(Handle<Map> map, |
7112 TransitionFlag flag) { | 7092 Descriptor* descriptor, |
7113 DescriptorArray* descriptors = instance_descriptors(); | 7093 TransitionFlag flag) { |
| 7094 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
7114 | 7095 |
7115 // Ensure the key is unique. | 7096 // Ensure the key is unique. |
7116 MaybeObject* maybe_failure = descriptor->KeyToUniqueName(); | 7097 descriptor->KeyToUniqueName(); |
7117 if (maybe_failure->IsFailure()) return maybe_failure; | |
7118 | 7098 |
7119 int old_size = NumberOfOwnDescriptors(); | 7099 int old_size = map->NumberOfOwnDescriptors(); |
7120 int new_size = old_size + 1; | 7100 int new_size = old_size + 1; |
7121 | 7101 |
7122 if (flag == INSERT_TRANSITION && | 7102 if (flag == INSERT_TRANSITION && |
7123 owns_descriptors() && | 7103 map->owns_descriptors() && |
7124 CanHaveMoreTransitions()) { | 7104 map->CanHaveMoreTransitions()) { |
7125 return ShareDescriptor(descriptors, descriptor); | 7105 return Map::ShareDescriptor(map, descriptors, descriptor); |
7126 } | 7106 } |
7127 | 7107 |
7128 DescriptorArray* new_descriptors; | 7108 Handle<DescriptorArray> new_descriptors = |
7129 MaybeObject* maybe_descriptors = | 7109 map->GetIsolate()->factory()->NewDescriptorArray(old_size, 1); |
7130 DescriptorArray::Allocate(GetIsolate(), old_size, 1); | |
7131 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; | |
7132 | 7110 |
7133 DescriptorArray::WhitenessWitness witness(new_descriptors); | 7111 DescriptorArray::WhitenessWitness witness(*new_descriptors); |
7134 | 7112 |
7135 // Copy the descriptors, inserting a descriptor. | 7113 // Copy the descriptors, inserting a descriptor. |
7136 for (int i = 0; i < old_size; ++i) { | 7114 for (int i = 0; i < old_size; ++i) { |
7137 new_descriptors->CopyFrom(i, descriptors, i, witness); | 7115 new_descriptors->CopyFrom(i, *descriptors, i, witness); |
7138 } | 7116 } |
7139 | 7117 |
7140 if (old_size != descriptors->number_of_descriptors()) { | 7118 if (old_size != descriptors->number_of_descriptors()) { |
7141 new_descriptors->SetNumberOfDescriptors(new_size); | 7119 new_descriptors->SetNumberOfDescriptors(new_size); |
7142 new_descriptors->Set(old_size, descriptor, witness); | 7120 new_descriptors->Set(old_size, descriptor, witness); |
7143 new_descriptors->Sort(); | 7121 new_descriptors->Sort(); |
7144 } else { | 7122 } else { |
7145 new_descriptors->Append(descriptor, witness); | 7123 new_descriptors->Append(descriptor, witness); |
7146 } | 7124 } |
7147 | 7125 |
7148 Name* key = descriptor->GetKey(); | 7126 Handle<Name> key = descriptor->GetKey(); |
7149 return CopyReplaceDescriptors(new_descriptors, flag, key, SIMPLE_TRANSITION); | 7127 return Map::CopyReplaceDescriptors( |
| 7128 map, new_descriptors, flag, key, SIMPLE_TRANSITION); |
7150 } | 7129 } |
7151 | 7130 |
7152 | 7131 |
7153 MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor, | 7132 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map, |
7154 TransitionFlag flag) { | 7133 Descriptor* descriptor, |
7155 DescriptorArray* old_descriptors = instance_descriptors(); | 7134 TransitionFlag flag) { |
| 7135 Handle<DescriptorArray> old_descriptors(map->instance_descriptors()); |
7156 | 7136 |
7157 // Ensure the key is unique. | 7137 // Ensure the key is unique. |
7158 MaybeObject* maybe_result = descriptor->KeyToUniqueName(); | 7138 descriptor->KeyToUniqueName(); |
7159 if (maybe_result->IsFailure()) return maybe_result; | |
7160 | 7139 |
7161 // We replace the key if it is already present. | 7140 // We replace the key if it is already present. |
7162 int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this); | 7141 int index = old_descriptors->SearchWithCache(*descriptor->GetKey(), *map); |
7163 if (index != DescriptorArray::kNotFound) { | 7142 if (index != DescriptorArray::kNotFound) { |
7164 return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag); | 7143 return Map::CopyReplaceDescriptor( |
| 7144 map, old_descriptors, descriptor, index, flag); |
7165 } | 7145 } |
7166 return CopyAddDescriptor(descriptor, flag); | 7146 return Map::CopyAddDescriptor(map, descriptor, flag); |
| 7147 } |
| 7148 |
| 7149 |
| 7150 Handle<DescriptorArray> DescriptorArray::CopyUpTo( |
| 7151 Handle<DescriptorArray> desc, |
| 7152 int enumeration_index) { |
| 7153 return DescriptorArray::CopyUpToAddAttributes(desc, |
| 7154 enumeration_index, |
| 7155 NONE); |
7167 } | 7156 } |
7168 | 7157 |
7169 | 7158 |
7170 Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes( | 7159 Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes( |
7171 Handle<DescriptorArray> desc, | 7160 Handle<DescriptorArray> desc, |
7172 int enumeration_index, | 7161 int enumeration_index, |
7173 PropertyAttributes attributes) { | 7162 PropertyAttributes attributes) { |
7174 CALL_HEAP_FUNCTION(desc->GetIsolate(), | 7163 if (enumeration_index == 0) { |
7175 desc->CopyUpToAddAttributes(enumeration_index, attributes), | 7164 return desc->GetIsolate()->factory()->empty_descriptor_array(); |
7176 DescriptorArray); | 7165 } |
7177 } | |
7178 | |
7179 | |
7180 MaybeObject* DescriptorArray::CopyUpToAddAttributes( | |
7181 int enumeration_index, PropertyAttributes attributes) { | |
7182 if (enumeration_index == 0) return GetHeap()->empty_descriptor_array(); | |
7183 | 7166 |
7184 int size = enumeration_index; | 7167 int size = enumeration_index; |
7185 | 7168 |
7186 DescriptorArray* descriptors; | 7169 Handle<DescriptorArray> descriptors = |
7187 MaybeObject* maybe_descriptors = Allocate(GetIsolate(), size); | 7170 desc->GetIsolate()->factory()->NewDescriptorArray(size); |
7188 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; | 7171 DescriptorArray::WhitenessWitness witness(*descriptors); |
7189 DescriptorArray::WhitenessWitness witness(descriptors); | |
7190 | 7172 |
7191 if (attributes != NONE) { | 7173 if (attributes != NONE) { |
7192 for (int i = 0; i < size; ++i) { | 7174 for (int i = 0; i < size; ++i) { |
7193 Object* value = GetValue(i); | 7175 Object* value = desc->GetValue(i); |
7194 PropertyDetails details = GetDetails(i); | 7176 PropertyDetails details = desc->GetDetails(i); |
7195 int mask = DONT_DELETE | DONT_ENUM; | 7177 int mask = DONT_DELETE | DONT_ENUM; |
7196 // READ_ONLY is an invalid attribute for JS setters/getters. | 7178 // READ_ONLY is an invalid attribute for JS setters/getters. |
7197 if (details.type() != CALLBACKS || !value->IsAccessorPair()) { | 7179 if (details.type() != CALLBACKS || !value->IsAccessorPair()) { |
7198 mask |= READ_ONLY; | 7180 mask |= READ_ONLY; |
7199 } | 7181 } |
7200 details = details.CopyAddAttributes( | 7182 details = details.CopyAddAttributes( |
7201 static_cast<PropertyAttributes>(attributes & mask)); | 7183 static_cast<PropertyAttributes>(attributes & mask)); |
7202 Descriptor desc(GetKey(i), value, details); | 7184 Descriptor inner_desc(handle(desc->GetKey(i)), |
7203 descriptors->Set(i, &desc, witness); | 7185 handle(value, desc->GetIsolate()), |
| 7186 details); |
| 7187 descriptors->Set(i, &inner_desc, witness); |
7204 } | 7188 } |
7205 } else { | 7189 } else { |
7206 for (int i = 0; i < size; ++i) { | 7190 for (int i = 0; i < size; ++i) { |
7207 descriptors->CopyFrom(i, this, i, witness); | 7191 descriptors->CopyFrom(i, *desc, i, witness); |
7208 } | 7192 } |
7209 } | 7193 } |
7210 | 7194 |
7211 if (number_of_descriptors() != enumeration_index) descriptors->Sort(); | 7195 if (desc->number_of_descriptors() != enumeration_index) descriptors->Sort(); |
7212 | 7196 |
7213 return descriptors; | 7197 return descriptors; |
7214 } | 7198 } |
7215 | 7199 |
7216 | 7200 |
7217 MaybeObject* Map::CopyReplaceDescriptor(DescriptorArray* descriptors, | 7201 Handle<Map> Map::CopyReplaceDescriptor(Handle<Map> map, |
7218 Descriptor* descriptor, | 7202 Handle<DescriptorArray> descriptors, |
7219 int insertion_index, | 7203 Descriptor* descriptor, |
7220 TransitionFlag flag) { | 7204 int insertion_index, |
| 7205 TransitionFlag flag) { |
7221 // Ensure the key is unique. | 7206 // Ensure the key is unique. |
7222 MaybeObject* maybe_failure = descriptor->KeyToUniqueName(); | 7207 descriptor->KeyToUniqueName(); |
7223 if (maybe_failure->IsFailure()) return maybe_failure; | |
7224 | 7208 |
7225 Name* key = descriptor->GetKey(); | 7209 Handle<Name> key = descriptor->GetKey(); |
7226 ASSERT(key == descriptors->GetKey(insertion_index)); | 7210 ASSERT(*key == descriptors->GetKey(insertion_index)); |
7227 | 7211 |
7228 int new_size = NumberOfOwnDescriptors(); | 7212 int new_size = map->NumberOfOwnDescriptors(); |
7229 ASSERT(0 <= insertion_index && insertion_index < new_size); | 7213 ASSERT(0 <= insertion_index && insertion_index < new_size); |
7230 | 7214 |
7231 ASSERT_LT(insertion_index, new_size); | 7215 ASSERT_LT(insertion_index, new_size); |
7232 | 7216 |
7233 DescriptorArray* new_descriptors; | 7217 Handle<DescriptorArray> new_descriptors = |
7234 MaybeObject* maybe_descriptors = | 7218 map->GetIsolate()->factory()->NewDescriptorArray(new_size); |
7235 DescriptorArray::Allocate(GetIsolate(), new_size); | 7219 DescriptorArray::WhitenessWitness witness(*new_descriptors); |
7236 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; | |
7237 DescriptorArray::WhitenessWitness witness(new_descriptors); | |
7238 | 7220 |
7239 for (int i = 0; i < new_size; ++i) { | 7221 for (int i = 0; i < new_size; ++i) { |
7240 if (i == insertion_index) { | 7222 if (i == insertion_index) { |
7241 new_descriptors->Set(i, descriptor, witness); | 7223 new_descriptors->Set(i, descriptor, witness); |
7242 } else { | 7224 } else { |
7243 new_descriptors->CopyFrom(i, descriptors, i, witness); | 7225 new_descriptors->CopyFrom(i, *descriptors, i, witness); |
7244 } | 7226 } |
7245 } | 7227 } |
7246 | 7228 |
7247 // Re-sort if descriptors were removed. | 7229 new_descriptors->Sort(); |
7248 if (new_size != descriptors->length()) new_descriptors->Sort(); | |
7249 | 7230 |
7250 SimpleTransitionFlag simple_flag = | 7231 SimpleTransitionFlag simple_flag = |
7251 (insertion_index == descriptors->number_of_descriptors() - 1) | 7232 (insertion_index == descriptors->number_of_descriptors() - 1) |
7252 ? SIMPLE_TRANSITION | 7233 ? SIMPLE_TRANSITION |
7253 : FULL_TRANSITION; | 7234 : FULL_TRANSITION; |
7254 return CopyReplaceDescriptors(new_descriptors, flag, key, simple_flag); | 7235 return Map::CopyReplaceDescriptors( |
| 7236 map, new_descriptors, flag, key, simple_flag); |
7255 } | 7237 } |
7256 | 7238 |
7257 | 7239 |
7258 void Map::UpdateCodeCache(Handle<Map> map, | 7240 void Map::UpdateCodeCache(Handle<Map> map, |
7259 Handle<Name> name, | 7241 Handle<Name> name, |
7260 Handle<Code> code) { | 7242 Handle<Code> code) { |
7261 Isolate* isolate = map->GetIsolate(); | 7243 Isolate* isolate = map->GetIsolate(); |
7262 CALL_HEAP_FUNCTION_VOID(isolate, | 7244 CALL_HEAP_FUNCTION_VOID(isolate, |
7263 map->UpdateCodeCache(*name, *code)); | 7245 map->UpdateCodeCache(*name, *code)); |
7264 } | 7246 } |
(...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8088 set(kEnumCacheIndex, bridge_storage); | 8070 set(kEnumCacheIndex, bridge_storage); |
8089 } | 8071 } |
8090 | 8072 |
8091 | 8073 |
8092 void DescriptorArray::CopyFrom(int dst_index, | 8074 void DescriptorArray::CopyFrom(int dst_index, |
8093 DescriptorArray* src, | 8075 DescriptorArray* src, |
8094 int src_index, | 8076 int src_index, |
8095 const WhitenessWitness& witness) { | 8077 const WhitenessWitness& witness) { |
8096 Object* value = src->GetValue(src_index); | 8078 Object* value = src->GetValue(src_index); |
8097 PropertyDetails details = src->GetDetails(src_index); | 8079 PropertyDetails details = src->GetDetails(src_index); |
8098 Descriptor desc(src->GetKey(src_index), value, details); | 8080 Descriptor desc(handle(src->GetKey(src_index)), |
| 8081 handle(value, src->GetIsolate()), |
| 8082 details); |
8099 Set(dst_index, &desc, witness); | 8083 Set(dst_index, &desc, witness); |
8100 } | 8084 } |
8101 | 8085 |
8102 | 8086 |
8103 // Creates a new descriptor array by merging the descriptor array of |right_map| | 8087 // Creates a new descriptor array by merging the descriptor array of |right_map| |
8104 // into the (at least partly) updated descriptor array of |left_map|. | 8088 // into the (at least partly) updated descriptor array of |left_map|. |
8105 // The method merges two descriptor array in three parts. Both descriptor arrays | 8089 // The method merges two descriptor array in three parts. Both descriptor arrays |
8106 // are identical up to |verbatim|. They also overlap in keys up to |valid|. | 8090 // are identical up to |verbatim|. They also overlap in keys up to |valid|. |
8107 // Between |verbatim| and |valid|, the resulting descriptor type as well as the | 8091 // Between |verbatim| and |valid|, the resulting descriptor type as well as the |
8108 // representation are generalized from both |left_map| and |right_map|. Beyond | 8092 // representation are generalized from both |left_map| and |right_map|. Beyond |
(...skipping 22 matching lines...) Expand all Loading... |
8131 result->NumberOfSlackDescriptors() > 0 || | 8115 result->NumberOfSlackDescriptors() > 0 || |
8132 result->number_of_descriptors() == right->number_of_descriptors()); | 8116 result->number_of_descriptors() == right->number_of_descriptors()); |
8133 ASSERT(result->number_of_descriptors() == new_size); | 8117 ASSERT(result->number_of_descriptors() == new_size); |
8134 | 8118 |
8135 int descriptor; | 8119 int descriptor; |
8136 | 8120 |
8137 // 0 -> |verbatim| | 8121 // 0 -> |verbatim| |
8138 int current_offset = 0; | 8122 int current_offset = 0; |
8139 for (descriptor = 0; descriptor < verbatim; descriptor++) { | 8123 for (descriptor = 0; descriptor < verbatim; descriptor++) { |
8140 if (left->GetDetails(descriptor).type() == FIELD) current_offset++; | 8124 if (left->GetDetails(descriptor).type() == FIELD) current_offset++; |
8141 Descriptor d(right->GetKey(descriptor), | 8125 Descriptor d(handle(right->GetKey(descriptor)), |
8142 right->GetValue(descriptor), | 8126 handle(right->GetValue(descriptor), right->GetIsolate()), |
8143 right->GetDetails(descriptor)); | 8127 right->GetDetails(descriptor)); |
8144 result->Set(descriptor, &d); | 8128 result->Set(descriptor, &d); |
8145 } | 8129 } |
8146 | 8130 |
8147 // |verbatim| -> |valid| | 8131 // |verbatim| -> |valid| |
8148 for (; descriptor < valid; descriptor++) { | 8132 for (; descriptor < valid; descriptor++) { |
8149 PropertyDetails left_details = left->GetDetails(descriptor); | 8133 PropertyDetails left_details = left->GetDetails(descriptor); |
8150 PropertyDetails right_details = right->GetDetails(descriptor); | 8134 PropertyDetails right_details = right->GetDetails(descriptor); |
8151 if (left_details.type() == FIELD || right_details.type() == FIELD || | 8135 if (left_details.type() == FIELD || right_details.type() == FIELD || |
8152 (store_mode == FORCE_FIELD && descriptor == modify_index) || | 8136 (store_mode == FORCE_FIELD && descriptor == modify_index) || |
8153 (left_details.type() == CONSTANT && | 8137 (left_details.type() == CONSTANT && |
8154 right_details.type() == CONSTANT && | 8138 right_details.type() == CONSTANT && |
8155 left->GetValue(descriptor) != right->GetValue(descriptor))) { | 8139 left->GetValue(descriptor) != right->GetValue(descriptor))) { |
8156 Representation representation = left_details.representation().generalize( | 8140 Representation representation = left_details.representation().generalize( |
8157 right_details.representation()); | 8141 right_details.representation()); |
8158 FieldDescriptor d(left->GetKey(descriptor), | 8142 FieldDescriptor d(handle(left->GetKey(descriptor)), |
8159 current_offset++, | 8143 current_offset++, |
8160 right_details.attributes(), | 8144 right_details.attributes(), |
8161 representation); | 8145 representation); |
8162 result->Set(descriptor, &d); | 8146 result->Set(descriptor, &d); |
8163 } else { | 8147 } else { |
8164 Descriptor d(right->GetKey(descriptor), | 8148 Descriptor d(handle(right->GetKey(descriptor)), |
8165 right->GetValue(descriptor), | 8149 handle(right->GetValue(descriptor), right->GetIsolate()), |
8166 right_details); | 8150 right_details); |
8167 result->Set(descriptor, &d); | 8151 result->Set(descriptor, &d); |
8168 } | 8152 } |
8169 } | 8153 } |
8170 | 8154 |
8171 // |valid| -> |new_size| | 8155 // |valid| -> |new_size| |
8172 for (; descriptor < new_size; descriptor++) { | 8156 for (; descriptor < new_size; descriptor++) { |
8173 PropertyDetails right_details = right->GetDetails(descriptor); | 8157 PropertyDetails right_details = right->GetDetails(descriptor); |
8174 if (right_details.type() == FIELD || | 8158 if (right_details.type() == FIELD || |
8175 (store_mode == FORCE_FIELD && descriptor == modify_index)) { | 8159 (store_mode == FORCE_FIELD && descriptor == modify_index)) { |
8176 FieldDescriptor d(right->GetKey(descriptor), | 8160 FieldDescriptor d(handle(right->GetKey(descriptor)), |
8177 current_offset++, | 8161 current_offset++, |
8178 right_details.attributes(), | 8162 right_details.attributes(), |
8179 right_details.representation()); | 8163 right_details.representation()); |
8180 result->Set(descriptor, &d); | 8164 result->Set(descriptor, &d); |
8181 } else { | 8165 } else { |
8182 Descriptor d(right->GetKey(descriptor), | 8166 Descriptor d(handle(right->GetKey(descriptor)), |
8183 right->GetValue(descriptor), | 8167 handle(right->GetValue(descriptor), right->GetIsolate()), |
8184 right_details); | 8168 right_details); |
8185 result->Set(descriptor, &d); | 8169 result->Set(descriptor, &d); |
8186 } | 8170 } |
8187 } | 8171 } |
8188 | 8172 |
8189 result->Sort(); | 8173 result->Sort(); |
8190 return result; | 8174 return result; |
8191 } | 8175 } |
8192 | 8176 |
8193 | 8177 |
(...skipping 1583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9777 if (object->IsGlobalObject()) return; | 9761 if (object->IsGlobalObject()) return; |
9778 | 9762 |
9779 // Make sure prototypes are fast objects and their maps have the bit set | 9763 // Make sure prototypes are fast objects and their maps have the bit set |
9780 // so they remain fast. | 9764 // so they remain fast. |
9781 if (!object->HasFastProperties()) { | 9765 if (!object->HasFastProperties()) { |
9782 TransformToFastProperties(object, 0); | 9766 TransformToFastProperties(object, 0); |
9783 } | 9767 } |
9784 } | 9768 } |
9785 | 9769 |
9786 | 9770 |
9787 static MUST_USE_RESULT MaybeObject* CacheInitialJSArrayMaps( | 9771 Handle<Object> CacheInitialJSArrayMaps( |
9788 Context* native_context, Map* initial_map) { | 9772 Handle<Context> native_context, Handle<Map> initial_map) { |
9789 // Replace all of the cached initial array maps in the native context with | 9773 // Replace all of the cached initial array maps in the native context with |
9790 // the appropriate transitioned elements kind maps. | 9774 // the appropriate transitioned elements kind maps. |
9791 Heap* heap = native_context->GetHeap(); | 9775 Factory* factory = native_context->GetIsolate()->factory(); |
9792 MaybeObject* maybe_maps = | 9776 Handle<FixedArray> maps = factory->NewFixedArrayWithHoles( |
9793 heap->AllocateFixedArrayWithHoles(kElementsKindCount, TENURED); | 9777 kElementsKindCount, TENURED); |
9794 FixedArray* maps; | |
9795 if (!maybe_maps->To(&maps)) return maybe_maps; | |
9796 | 9778 |
9797 Map* current_map = initial_map; | 9779 Handle<Map> current_map = initial_map; |
9798 ElementsKind kind = current_map->elements_kind(); | 9780 ElementsKind kind = current_map->elements_kind(); |
9799 ASSERT(kind == GetInitialFastElementsKind()); | 9781 ASSERT(kind == GetInitialFastElementsKind()); |
9800 maps->set(kind, current_map); | 9782 maps->set(kind, *current_map); |
9801 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1; | 9783 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1; |
9802 i < kFastElementsKindCount; ++i) { | 9784 i < kFastElementsKindCount; ++i) { |
9803 Map* new_map; | 9785 Handle<Map> new_map; |
9804 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i); | 9786 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i); |
9805 if (current_map->HasElementsTransition()) { | 9787 if (current_map->HasElementsTransition()) { |
9806 new_map = current_map->elements_transition_map(); | 9788 new_map = handle(current_map->elements_transition_map()); |
9807 ASSERT(new_map->elements_kind() == next_kind); | 9789 ASSERT(new_map->elements_kind() == next_kind); |
9808 } else { | 9790 } else { |
9809 MaybeObject* maybe_new_map = | 9791 new_map = Map::CopyAsElementsKind( |
9810 current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION); | 9792 current_map, next_kind, INSERT_TRANSITION); |
9811 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | |
9812 } | 9793 } |
9813 maps->set(next_kind, new_map); | 9794 maps->set(next_kind, *new_map); |
9814 current_map = new_map; | 9795 current_map = new_map; |
9815 } | 9796 } |
9816 native_context->set_js_array_maps(maps); | 9797 native_context->set_js_array_maps(*maps); |
9817 return initial_map; | 9798 return initial_map; |
9818 } | 9799 } |
9819 | 9800 |
9820 | 9801 |
9821 Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context, | |
9822 Handle<Map> initial_map) { | |
9823 CALL_HEAP_FUNCTION(native_context->GetIsolate(), | |
9824 CacheInitialJSArrayMaps(*native_context, *initial_map), | |
9825 Object); | |
9826 } | |
9827 | |
9828 | |
9829 void JSFunction::SetInstancePrototype(Handle<JSFunction> function, | 9802 void JSFunction::SetInstancePrototype(Handle<JSFunction> function, |
9830 Handle<Object> value) { | 9803 Handle<Object> value) { |
9831 ASSERT(value->IsJSReceiver()); | 9804 ASSERT(value->IsJSReceiver()); |
9832 | 9805 |
9833 // First some logic for the map of the prototype to make sure it is in fast | 9806 // First some logic for the map of the prototype to make sure it is in fast |
9834 // mode. | 9807 // mode. |
9835 if (value->IsJSObject()) { | 9808 if (value->IsJSObject()) { |
9836 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); | 9809 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); |
9837 } | 9810 } |
9838 | 9811 |
(...skipping 5870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15709 // instance descriptor. | 15682 // instance descriptor. |
15710 MaybeObject* maybe_key = heap->InternalizeString(String::cast(k)); | 15683 MaybeObject* maybe_key = heap->InternalizeString(String::cast(k)); |
15711 if (!maybe_key->To(&key)) return maybe_key; | 15684 if (!maybe_key->To(&key)) return maybe_key; |
15712 } | 15685 } |
15713 | 15686 |
15714 PropertyDetails details = DetailsAt(i); | 15687 PropertyDetails details = DetailsAt(i); |
15715 int enumeration_index = details.dictionary_index(); | 15688 int enumeration_index = details.dictionary_index(); |
15716 PropertyType type = details.type(); | 15689 PropertyType type = details.type(); |
15717 | 15690 |
15718 if (value->IsJSFunction()) { | 15691 if (value->IsJSFunction()) { |
15719 ConstantDescriptor d(key, value, details.attributes()); | 15692 ConstantDescriptor d(handle(key), |
| 15693 handle(value, GetIsolate()), |
| 15694 details.attributes()); |
15720 descriptors->Set(enumeration_index - 1, &d, witness); | 15695 descriptors->Set(enumeration_index - 1, &d, witness); |
15721 } else if (type == NORMAL) { | 15696 } else if (type == NORMAL) { |
15722 if (current_offset < inobject_props) { | 15697 if (current_offset < inobject_props) { |
15723 obj->InObjectPropertyAtPut(current_offset, | 15698 obj->InObjectPropertyAtPut(current_offset, |
15724 value, | 15699 value, |
15725 UPDATE_WRITE_BARRIER); | 15700 UPDATE_WRITE_BARRIER); |
15726 } else { | 15701 } else { |
15727 int offset = current_offset - inobject_props; | 15702 int offset = current_offset - inobject_props; |
15728 fields->set(offset, value); | 15703 fields->set(offset, value); |
15729 } | 15704 } |
15730 FieldDescriptor d(key, | 15705 FieldDescriptor d(handle(key), |
15731 current_offset++, | 15706 current_offset++, |
15732 details.attributes(), | 15707 details.attributes(), |
15733 // TODO(verwaest): value->OptimalRepresentation(); | 15708 // TODO(verwaest): value->OptimalRepresentation(); |
15734 Representation::Tagged()); | 15709 Representation::Tagged()); |
15735 descriptors->Set(enumeration_index - 1, &d, witness); | 15710 descriptors->Set(enumeration_index - 1, &d, witness); |
15736 } else if (type == CALLBACKS) { | 15711 } else if (type == CALLBACKS) { |
15737 CallbacksDescriptor d(key, | 15712 CallbacksDescriptor d(handle(key), |
15738 value, | 15713 handle(value, GetIsolate()), |
15739 details.attributes()); | 15714 details.attributes()); |
15740 descriptors->Set(enumeration_index - 1, &d, witness); | 15715 descriptors->Set(enumeration_index - 1, &d, witness); |
15741 } else { | 15716 } else { |
15742 UNREACHABLE(); | 15717 UNREACHABLE(); |
15743 } | 15718 } |
15744 } | 15719 } |
15745 } | 15720 } |
15746 ASSERT(current_offset == number_of_fields); | 15721 ASSERT(current_offset == number_of_fields); |
15747 | 15722 |
15748 descriptors->Sort(); | 15723 descriptors->Sort(); |
(...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16656 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16631 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16657 static const char* error_messages_[] = { | 16632 static const char* error_messages_[] = { |
16658 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16633 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16659 }; | 16634 }; |
16660 #undef ERROR_MESSAGES_TEXTS | 16635 #undef ERROR_MESSAGES_TEXTS |
16661 return error_messages_[reason]; | 16636 return error_messages_[reason]; |
16662 } | 16637 } |
16663 | 16638 |
16664 | 16639 |
16665 } } // namespace v8::internal | 16640 } } // namespace v8::internal |
OLD | NEW |