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 = handle(AccessorInfo::cast(callbacks->get(i))); |
Toon Verwaest
2014/04/09 13:49:24
Handle<AccessorInfo> entry(AccessorInfo::cast(...)
mvstanton
2014/04/09 14:26:06
Done.
| |
3176 Name* key = Name::cast(entry->name()); | 3164 Handle<Name> key = handle(Name::cast(entry->name())); |
Toon Verwaest
2014/04/09 13:49:24
Same.
mvstanton
2014/04/09 14:26:06
Done.
| |
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(current_map, kind, |
3348 current_map->CopyAsElementsKind(kind, INSERT_TRANSITION); | 3339 INSERT_TRANSITION); |
mvstanton
2014/04/09 14:26:06
Put arguments all on a new line.
| |
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(current_map, to_kind, |
3356 current_map->CopyAsElementsKind(to_kind, INSERT_TRANSITION); | 3346 INSERT_TRANSITION); |
mvstanton
2014/04/09 14:26:06
Put arguments all on a new line.
| |
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 = handle(object->map()); |
mvstanton
2014/04/09 14:26:06
Fixed here to current_map(object->map), and other
| |
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 = handle(object->map()); | |
Toon Verwaest
2014/04/09 13:49:24
Handle<Map> start_map(object->map());
mvstanton
2014/04/09 14:26:06
Done.
| |
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 = handle(FindClosestElementsTransition(*map, kind)); |
Toon Verwaest
2014/04/09 13:49:24
closest_map(FindClosest...);
mvstanton
2014/04/09 14:26:06
Done.
| |
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 = handle(map->GetInitialElements()); | |
Toon Verwaest
2014/04/09 13:49:24
elements(map->GetInitial...)
mvstanton
2014/04/09 14:26:06
Done.
| |
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 1707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6481 JSObject::MigrateToMap(self, transitioned_map); | 6490 JSObject::MigrateToMap(self, transitioned_map); |
6482 return true; | 6491 return true; |
6483 } | 6492 } |
6484 | 6493 |
6485 // If either not the same accessor, or not the same attributes, fall back to | 6494 // If either not the same accessor, or not the same attributes, fall back to |
6486 // the slow case. | 6495 // the slow case. |
6487 return false; | 6496 return false; |
6488 } | 6497 } |
6489 | 6498 |
6490 | 6499 |
6491 static MaybeObject* CopyInsertDescriptor(Map* map, | |
6492 Name* name, | |
6493 AccessorPair* accessors, | |
6494 PropertyAttributes attributes) { | |
6495 CallbacksDescriptor new_accessors_desc(name, accessors, attributes); | |
6496 return map->CopyInsertDescriptor(&new_accessors_desc, INSERT_TRANSITION); | |
6497 } | |
6498 | |
6499 | |
6500 static Handle<Map> CopyInsertDescriptor(Handle<Map> map, | 6500 static Handle<Map> CopyInsertDescriptor(Handle<Map> map, |
6501 Handle<Name> name, | 6501 Handle<Name> name, |
6502 Handle<AccessorPair> accessors, | 6502 Handle<AccessorPair> accessors, |
6503 PropertyAttributes attributes) { | 6503 PropertyAttributes attributes) { |
6504 CALL_HEAP_FUNCTION(map->GetIsolate(), | 6504 CallbacksDescriptor new_accessors_desc(name, accessors, attributes); |
6505 CopyInsertDescriptor(*map, *name, *accessors, attributes), | 6505 return Map::CopyInsertDescriptor(map, &new_accessors_desc, INSERT_TRANSITION); |
6506 Map); | |
6507 } | 6506 } |
6508 | 6507 |
6509 | 6508 |
6510 bool JSObject::DefineFastAccessor(Handle<JSObject> object, | 6509 bool JSObject::DefineFastAccessor(Handle<JSObject> object, |
6511 Handle<Name> name, | 6510 Handle<Name> name, |
6512 AccessorComponent component, | 6511 AccessorComponent component, |
6513 Handle<Object> accessor, | 6512 Handle<Object> accessor, |
6514 PropertyAttributes attributes) { | 6513 PropertyAttributes attributes) { |
6515 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); | 6514 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); |
6516 Isolate* isolate = object->GetIsolate(); | 6515 Isolate* isolate = object->GetIsolate(); |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6823 result->set_unused_property_fields(unused_property_fields()); | 6822 result->set_unused_property_fields(unused_property_fields()); |
6824 | 6823 |
6825 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); | 6824 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); |
6826 result->set_is_shared(false); | 6825 result->set_is_shared(false); |
6827 result->ClearCodeCache(GetHeap()); | 6826 result->ClearCodeCache(GetHeap()); |
6828 NotifyLeafMapLayoutChange(); | 6827 NotifyLeafMapLayoutChange(); |
6829 return result; | 6828 return result; |
6830 } | 6829 } |
6831 | 6830 |
6832 | 6831 |
6833 MaybeObject* Map::ShareDescriptor(DescriptorArray* descriptors, | 6832 Handle<Map> Map::ShareDescriptor(Handle<Map> map, |
6834 Descriptor* descriptor) { | 6833 Handle<DescriptorArray> descriptors, |
6834 Descriptor* descriptor) { | |
6835 // Sanity check. This path is only to be taken if the map owns its descriptor | 6835 // Sanity check. This path is only to be taken if the map owns its descriptor |
6836 // array, implying that its NumberOfOwnDescriptors equals the number of | 6836 // array, implying that its NumberOfOwnDescriptors equals the number of |
6837 // descriptors in the descriptor array. | 6837 // descriptors in the descriptor array. |
6838 ASSERT(NumberOfOwnDescriptors() == | 6838 ASSERT(map->NumberOfOwnDescriptors() == |
6839 instance_descriptors()->number_of_descriptors()); | 6839 map->instance_descriptors()->number_of_descriptors()); |
6840 Map* result; | 6840 Handle<Map> result = Map::CopyDropDescriptors(map); |
6841 MaybeObject* maybe_result = CopyDropDescriptors(); | |
6842 if (!maybe_result->To(&result)) return maybe_result; | |
6843 | 6841 |
6844 Name* name = descriptor->GetKey(); | 6842 Handle<Name> name = descriptor->GetKey(); |
6845 | 6843 |
6846 TransitionArray* transitions; | 6844 Handle<TransitionArray> transitions = |
6847 MaybeObject* maybe_transitions = | 6845 Map::AddTransition(map, name, result, SIMPLE_TRANSITION); |
6848 AddTransition(name, result, SIMPLE_TRANSITION); | |
6849 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | |
6850 | 6846 |
6851 int old_size = descriptors->number_of_descriptors(); | 6847 int old_size = descriptors->number_of_descriptors(); |
6852 | 6848 |
6853 DescriptorArray* new_descriptors; | 6849 Handle<DescriptorArray> new_descriptors; |
6854 | 6850 bool needs_initialization = false; |
6855 if (descriptors->NumberOfSlackDescriptors() > 0) { | 6851 if (descriptors->NumberOfSlackDescriptors() > 0) { |
6856 new_descriptors = descriptors; | 6852 new_descriptors = descriptors; |
6857 new_descriptors->Append(descriptor); | 6853 new_descriptors->Append(descriptor); |
6858 } else { | 6854 } else { |
6859 // Descriptor arrays grow by 50%. | 6855 // Descriptor arrays grow by 50%. |
6860 MaybeObject* maybe_descriptors = DescriptorArray::Allocate( | 6856 new_descriptors = map->GetIsolate()->factory()->NewDescriptorArray( |
6861 GetIsolate(), old_size, old_size < 4 ? 1 : old_size / 2); | 6857 old_size, old_size < 4 ? 1 : old_size / 2); |
6862 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; | 6858 needs_initialization = true; |
6859 } | |
6863 | 6860 |
6864 DescriptorArray::WhitenessWitness witness(new_descriptors); | 6861 // Disallow gc until after result->InitializeDescriptors() is called. |
Toon Verwaest
2014/04/09 13:49:24
Splitting this up isn't necessary (doesn't help).
mvstanton
2014/04/09 14:26:06
Sounds good, done.
| |
6862 DisallowHeapAllocation no_gc; | |
6863 if (needs_initialization) { | |
6864 DescriptorArray::WhitenessWitness witness(*new_descriptors); | |
6865 | 6865 |
6866 // Copy the descriptors, inserting a descriptor. | 6866 // Copy the descriptors, inserting a descriptor. |
6867 for (int i = 0; i < old_size; ++i) { | 6867 for (int i = 0; i < old_size; ++i) { |
6868 new_descriptors->CopyFrom(i, descriptors, i, witness); | 6868 new_descriptors->CopyFrom(i, *descriptors, i, witness); |
6869 } | 6869 } |
6870 | 6870 |
6871 new_descriptors->Append(descriptor, witness); | 6871 new_descriptors->Append(descriptor, witness); |
6872 | 6872 |
6873 if (old_size > 0) { | 6873 if (old_size > 0) { |
6874 // If the source descriptors had an enum cache we copy it. This ensures | 6874 // If the source descriptors had an enum cache we copy it. This ensures |
6875 // that the maps to which we push the new descriptor array back can rely | 6875 // that the maps to which we push the new descriptor array back can rely |
6876 // on a cache always being available once it is set. If the map has more | 6876 // on a cache always being available once it is set. If the map has more |
6877 // enumerated descriptors than available in the original cache, the cache | 6877 // enumerated descriptors than available in the original cache, the cache |
6878 // will be lazily replaced by the extended cache when needed. | 6878 // will be lazily replaced by the extended cache when needed. |
6879 if (descriptors->HasEnumCache()) { | 6879 if (descriptors->HasEnumCache()) { |
6880 new_descriptors->CopyEnumCacheFrom(descriptors); | 6880 new_descriptors->CopyEnumCacheFrom(*descriptors); |
6881 } | 6881 } |
6882 | 6882 |
6883 Map* map; | 6883 Map* walk_map; |
6884 // Replace descriptors by new_descriptors in all maps that share it. | 6884 // Replace descriptors by new_descriptors in all maps that share it. |
6885 | 6885 |
6886 GetHeap()->incremental_marking()->RecordWrites(descriptors); | 6886 map->GetHeap()->incremental_marking()->RecordWrites(*descriptors); |
6887 for (Object* current = GetBackPointer(); | 6887 for (Object* current = map->GetBackPointer(); |
6888 !current->IsUndefined(); | 6888 !current->IsUndefined(); |
6889 current = map->GetBackPointer()) { | 6889 current = walk_map->GetBackPointer()) { |
6890 map = Map::cast(current); | 6890 walk_map = Map::cast(current); |
6891 if (map->instance_descriptors() != descriptors) break; | 6891 if (walk_map->instance_descriptors() != *descriptors) break; |
6892 map->set_instance_descriptors(new_descriptors); | 6892 walk_map->set_instance_descriptors(*new_descriptors); |
6893 } | 6893 } |
6894 | 6894 |
6895 set_instance_descriptors(new_descriptors); | 6895 map->set_instance_descriptors(*new_descriptors); |
6896 } | 6896 } |
6897 } | 6897 } |
6898 | 6898 |
6899 result->SetBackPointer(this); | 6899 result->SetBackPointer(*map); |
6900 result->InitializeDescriptors(new_descriptors); | 6900 result->InitializeDescriptors(*new_descriptors); |
6901 ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1); | 6901 ASSERT(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); |
6902 | 6902 |
6903 set_transitions(transitions); | 6903 map->set_transitions(*transitions); |
6904 set_owns_descriptors(false); | 6904 map->set_owns_descriptors(false); |
6905 | 6905 |
6906 return result; | 6906 return result; |
6907 } | 6907 } |
6908 | 6908 |
6909 | 6909 |
6910 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, | 6910 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, |
6911 Handle<DescriptorArray> descriptors, | 6911 Handle<DescriptorArray> descriptors, |
6912 TransitionFlag flag, | 6912 TransitionFlag flag, |
6913 Handle<Name> name) { | 6913 SimpleTransitionFlag simple_flag) { |
6914 CALL_HEAP_FUNCTION(map->GetIsolate(), | 6914 return Map::CopyReplaceDescriptors(map, descriptors, flag, |
mvstanton
2014/04/09 14:26:06
Put all args on a new line.
| |
6915 map->CopyReplaceDescriptors(*descriptors, flag, *name), | 6915 Handle<Name>::null(), simple_flag); |
6916 Map); | |
6917 } | 6916 } |
6918 | 6917 |
6919 | 6918 |
6920 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, | 6919 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, |
6921 TransitionFlag flag, | 6920 Handle<DescriptorArray> descriptors, |
6922 Name* name, | 6921 TransitionFlag flag, |
6923 SimpleTransitionFlag simple_flag) { | 6922 Handle<Name> name, |
6923 SimpleTransitionFlag simple_flag) { | |
6924 ASSERT(descriptors->IsSortedNoDuplicates()); | 6924 ASSERT(descriptors->IsSortedNoDuplicates()); |
6925 | 6925 |
6926 Map* result; | 6926 Handle<Map> result = CopyDropDescriptors(map); |
6927 MaybeObject* maybe_result = CopyDropDescriptors(); | 6927 result->InitializeDescriptors(*descriptors); |
6928 if (!maybe_result->To(&result)) return maybe_result; | |
6929 | 6928 |
6930 result->InitializeDescriptors(descriptors); | 6929 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { |
6931 | 6930 Handle<TransitionArray> transitions = Map::AddTransition( |
6932 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) { | 6931 map, name, result, simple_flag); |
6933 TransitionArray* transitions; | 6932 map->set_transitions(*transitions); |
6934 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag); | 6933 result->SetBackPointer(*map); |
6935 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | |
6936 set_transitions(transitions); | |
6937 result->SetBackPointer(this); | |
6938 } else { | 6934 } else { |
6939 descriptors->InitializeRepresentations(Representation::Tagged()); | 6935 descriptors->InitializeRepresentations(Representation::Tagged()); |
6940 } | 6936 } |
6941 | 6937 |
6942 return result; | 6938 return result; |
6943 } | 6939 } |
6944 | 6940 |
6945 | 6941 |
6946 // Since this method is used to rewrite an existing transition tree, it can | 6942 // Since this method is used to rewrite an existing transition tree, it can |
6947 // always insert transitions without checking. | 6943 // always insert transitions without checking. |
(...skipping 22 matching lines...) Expand all Loading... | |
6970 Handle<TransitionArray> transitions = Map::AddTransition(map, name, result, | 6966 Handle<TransitionArray> transitions = Map::AddTransition(map, name, result, |
6971 SIMPLE_TRANSITION); | 6967 SIMPLE_TRANSITION); |
6972 | 6968 |
6973 map->set_transitions(*transitions); | 6969 map->set_transitions(*transitions); |
6974 result->SetBackPointer(*map); | 6970 result->SetBackPointer(*map); |
6975 | 6971 |
6976 return result; | 6972 return result; |
6977 } | 6973 } |
6978 | 6974 |
6979 | 6975 |
6980 MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) { | 6976 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, |
6977 TransitionFlag flag) { | |
6981 if (flag == INSERT_TRANSITION) { | 6978 if (flag == INSERT_TRANSITION) { |
6982 ASSERT(!HasElementsTransition() || | 6979 ASSERT(!map->HasElementsTransition() || |
6983 ((elements_transition_map()->elements_kind() == DICTIONARY_ELEMENTS || | 6980 ((map->elements_transition_map()->elements_kind() == |
6981 DICTIONARY_ELEMENTS || | |
6984 IsExternalArrayElementsKind( | 6982 IsExternalArrayElementsKind( |
6985 elements_transition_map()->elements_kind())) && | 6983 map->elements_transition_map()->elements_kind())) && |
6986 (kind == DICTIONARY_ELEMENTS || | 6984 (kind == DICTIONARY_ELEMENTS || |
6987 IsExternalArrayElementsKind(kind)))); | 6985 IsExternalArrayElementsKind(kind)))); |
6988 ASSERT(!IsFastElementsKind(kind) || | 6986 ASSERT(!IsFastElementsKind(kind) || |
6989 IsMoreGeneralElementsKindTransition(elements_kind(), kind)); | 6987 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind)); |
6990 ASSERT(kind != elements_kind()); | 6988 ASSERT(kind != map->elements_kind()); |
6991 } | 6989 } |
6992 | 6990 |
6993 bool insert_transition = | 6991 bool insert_transition = |
6994 flag == INSERT_TRANSITION && !HasElementsTransition(); | 6992 flag == INSERT_TRANSITION && !map->HasElementsTransition(); |
6995 | 6993 |
6996 if (insert_transition && owns_descriptors()) { | 6994 if (insert_transition && map->owns_descriptors()) { |
6997 // In case the map owned its own descriptors, share the descriptors and | 6995 // In case the map owned its own descriptors, share the descriptors and |
6998 // transfer ownership to the new map. | 6996 // transfer ownership to the new map. |
6999 Map* new_map; | 6997 Handle<Map> new_map = Map::CopyDropDescriptors(map); |
7000 MaybeObject* maybe_new_map = CopyDropDescriptors(); | |
7001 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | |
7002 | 6998 |
7003 MaybeObject* added_elements = set_elements_transition_map(new_map); | 6999 SetElementsTransitionMap(map, new_map); |
7004 if (added_elements->IsFailure()) return added_elements; | |
7005 | 7000 |
7006 new_map->set_elements_kind(kind); | 7001 new_map->set_elements_kind(kind); |
7007 new_map->InitializeDescriptors(instance_descriptors()); | 7002 new_map->InitializeDescriptors(map->instance_descriptors()); |
7008 new_map->SetBackPointer(this); | 7003 new_map->SetBackPointer(*map); |
7009 set_owns_descriptors(false); | 7004 map->set_owns_descriptors(false); |
7010 return new_map; | 7005 return new_map; |
7011 } | 7006 } |
7012 | 7007 |
7013 // In case the map did not own its own descriptors, a split is forced by | 7008 // In case the map did not own its own descriptors, a split is forced by |
7014 // copying the map; creating a new descriptor array cell. | 7009 // copying the map; creating a new descriptor array cell. |
7015 // Create a new free-floating map only if we are not allowed to store it. | 7010 // Create a new free-floating map only if we are not allowed to store it. |
7016 Map* new_map; | 7011 Handle<Map> new_map = Map::Copy(map); |
7017 MaybeObject* maybe_new_map = Copy(); | |
7018 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | |
7019 | 7012 |
7020 new_map->set_elements_kind(kind); | 7013 new_map->set_elements_kind(kind); |
7021 | 7014 |
7022 if (insert_transition) { | 7015 if (insert_transition) { |
7023 MaybeObject* added_elements = set_elements_transition_map(new_map); | 7016 SetElementsTransitionMap(map, new_map); |
7024 if (added_elements->IsFailure()) return added_elements; | 7017 new_map->SetBackPointer(*map); |
7025 new_map->SetBackPointer(this); | |
7026 } | 7018 } |
7027 | 7019 |
7028 return new_map; | 7020 return new_map; |
7029 } | 7021 } |
7030 | 7022 |
7031 | 7023 |
7032 Handle<Map> Map::CopyForObserved(Handle<Map> map) { | 7024 Handle<Map> Map::CopyForObserved(Handle<Map> map) { |
7033 ASSERT(!map->is_observed()); | 7025 ASSERT(!map->is_observed()); |
7034 | 7026 |
7035 Isolate* isolate = map->GetIsolate(); | 7027 Isolate* isolate = map->GetIsolate(); |
(...skipping 19 matching lines...) Expand all Loading... | |
7055 new_map->InitializeDescriptors(map->instance_descriptors()); | 7047 new_map->InitializeDescriptors(map->instance_descriptors()); |
7056 map->set_owns_descriptors(false); | 7048 map->set_owns_descriptors(false); |
7057 } | 7049 } |
7058 | 7050 |
7059 new_map->SetBackPointer(*map); | 7051 new_map->SetBackPointer(*map); |
7060 return new_map; | 7052 return new_map; |
7061 } | 7053 } |
7062 | 7054 |
7063 | 7055 |
7064 Handle<Map> Map::Copy(Handle<Map> map) { | 7056 Handle<Map> Map::Copy(Handle<Map> map) { |
7065 CALL_HEAP_FUNCTION(map->GetIsolate(), map->Copy(), Map); | 7057 Handle<DescriptorArray> descriptors = handle(map->instance_descriptors()); |
Toon Verwaest
2014/04/09 13:49:24
descriptors(map->instance..);
mvstanton
2014/04/09 14:26:06
Done.
| |
7058 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | |
7059 Handle<DescriptorArray> new_descriptors = | |
7060 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); | |
7061 return Map::CopyReplaceDescriptors(map, new_descriptors, OMIT_TRANSITION); | |
7066 } | 7062 } |
7067 | 7063 |
7068 | 7064 |
7069 MaybeObject* Map::Copy() { | |
7070 DescriptorArray* descriptors = instance_descriptors(); | |
7071 DescriptorArray* new_descriptors; | |
7072 int number_of_own_descriptors = NumberOfOwnDescriptors(); | |
7073 MaybeObject* maybe_descriptors = | |
7074 descriptors->CopyUpTo(number_of_own_descriptors); | |
7075 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; | |
7076 | |
7077 return CopyReplaceDescriptors(new_descriptors, OMIT_TRANSITION); | |
7078 } | |
7079 | |
7080 | |
7081 Handle<Map> Map::Create(Handle<JSFunction> constructor, | 7065 Handle<Map> Map::Create(Handle<JSFunction> constructor, |
7082 int extra_inobject_properties) { | 7066 int extra_inobject_properties) { |
7083 Handle<Map> copy = Copy(handle(constructor->initial_map())); | 7067 Handle<Map> copy = Copy(handle(constructor->initial_map())); |
7084 | 7068 |
7085 // Check that we do not overflow the instance size when adding the | 7069 // Check that we do not overflow the instance size when adding the |
7086 // extra inobject properties. | 7070 // extra inobject properties. |
7087 int instance_size_delta = extra_inobject_properties * kPointerSize; | 7071 int instance_size_delta = extra_inobject_properties * kPointerSize; |
7088 int max_instance_size_delta = | 7072 int max_instance_size_delta = |
7089 JSObject::kMaxInstanceSize - copy->instance_size(); | 7073 JSObject::kMaxInstanceSize - copy->instance_size(); |
7090 int max_extra_properties = max_instance_size_delta >> kPointerSizeLog2; | 7074 int max_extra_properties = max_instance_size_delta >> kPointerSizeLog2; |
7091 | 7075 |
7092 // If the instance size overflows, we allocate as many properties as we can as | 7076 // If the instance size overflows, we allocate as many properties as we can as |
7093 // inobject properties. | 7077 // inobject properties. |
7094 if (extra_inobject_properties > max_extra_properties) { | 7078 if (extra_inobject_properties > max_extra_properties) { |
7095 instance_size_delta = max_instance_size_delta; | 7079 instance_size_delta = max_instance_size_delta; |
7096 extra_inobject_properties = max_extra_properties; | 7080 extra_inobject_properties = max_extra_properties; |
7097 } | 7081 } |
7098 | 7082 |
7099 // Adjust the map with the extra inobject properties. | 7083 // Adjust the map with the extra inobject properties. |
7100 int inobject_properties = | 7084 int inobject_properties = |
7101 copy->inobject_properties() + extra_inobject_properties; | 7085 copy->inobject_properties() + extra_inobject_properties; |
7102 copy->set_inobject_properties(inobject_properties); | 7086 copy->set_inobject_properties(inobject_properties); |
7103 copy->set_unused_property_fields(inobject_properties); | 7087 copy->set_unused_property_fields(inobject_properties); |
7104 copy->set_instance_size(copy->instance_size() + instance_size_delta); | 7088 copy->set_instance_size(copy->instance_size() + instance_size_delta); |
7105 copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy)); | 7089 copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy)); |
7106 return copy; | 7090 return copy; |
7107 } | 7091 } |
7108 | 7092 |
7109 | 7093 |
7110 MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor, | 7094 Handle<Map> Map::CopyAddDescriptor(Handle<Map> map, |
7111 TransitionFlag flag) { | 7095 Descriptor* descriptor, |
7112 DescriptorArray* descriptors = instance_descriptors(); | 7096 TransitionFlag flag) { |
7097 Handle<DescriptorArray> descriptors = handle(map->instance_descriptors()); | |
Toon Verwaest
2014/04/09 13:49:24
descriptors(map->...)
mvstanton
2014/04/09 14:26:06
Done.
| |
7113 | 7098 |
7114 // Ensure the key is unique. | 7099 // Ensure the key is unique. |
7115 MaybeObject* maybe_failure = descriptor->KeyToUniqueName(); | 7100 descriptor->KeyToUniqueName(); |
7116 if (maybe_failure->IsFailure()) return maybe_failure; | |
7117 | 7101 |
7118 int old_size = NumberOfOwnDescriptors(); | 7102 int old_size = map->NumberOfOwnDescriptors(); |
7119 int new_size = old_size + 1; | 7103 int new_size = old_size + 1; |
7120 | 7104 |
7121 if (flag == INSERT_TRANSITION && | 7105 if (flag == INSERT_TRANSITION && |
7122 owns_descriptors() && | 7106 map->owns_descriptors() && |
7123 CanHaveMoreTransitions()) { | 7107 map->CanHaveMoreTransitions()) { |
7124 return ShareDescriptor(descriptors, descriptor); | 7108 return Map::ShareDescriptor(map, descriptors, descriptor); |
7125 } | 7109 } |
7126 | 7110 |
7127 DescriptorArray* new_descriptors; | 7111 Handle<DescriptorArray> new_descriptors = |
7128 MaybeObject* maybe_descriptors = | 7112 map->GetIsolate()->factory()->NewDescriptorArray(old_size, 1); |
7129 DescriptorArray::Allocate(GetIsolate(), old_size, 1); | |
7130 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; | |
7131 | 7113 |
7132 DescriptorArray::WhitenessWitness witness(new_descriptors); | 7114 DescriptorArray::WhitenessWitness witness(*new_descriptors); |
7133 | 7115 |
7134 // Copy the descriptors, inserting a descriptor. | 7116 // Copy the descriptors, inserting a descriptor. |
7135 for (int i = 0; i < old_size; ++i) { | 7117 for (int i = 0; i < old_size; ++i) { |
7136 new_descriptors->CopyFrom(i, descriptors, i, witness); | 7118 new_descriptors->CopyFrom(i, *descriptors, i, witness); |
7137 } | 7119 } |
7138 | 7120 |
7139 if (old_size != descriptors->number_of_descriptors()) { | 7121 if (old_size != descriptors->number_of_descriptors()) { |
7140 new_descriptors->SetNumberOfDescriptors(new_size); | 7122 new_descriptors->SetNumberOfDescriptors(new_size); |
7141 new_descriptors->Set(old_size, descriptor, witness); | 7123 new_descriptors->Set(old_size, descriptor, witness); |
7142 new_descriptors->Sort(); | 7124 new_descriptors->Sort(); |
7143 } else { | 7125 } else { |
7144 new_descriptors->Append(descriptor, witness); | 7126 new_descriptors->Append(descriptor, witness); |
7145 } | 7127 } |
7146 | 7128 |
7147 Name* key = descriptor->GetKey(); | 7129 Handle<Name> key = descriptor->GetKey(); |
7148 return CopyReplaceDescriptors(new_descriptors, flag, key, SIMPLE_TRANSITION); | 7130 return Map::CopyReplaceDescriptors(map, new_descriptors, flag, |
7131 key, SIMPLE_TRANSITION); | |
mvstanton
2014/04/09 14:26:06
Args all on a new line.
| |
7149 } | 7132 } |
7150 | 7133 |
7151 | 7134 |
7152 MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor, | 7135 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map, |
7153 TransitionFlag flag) { | 7136 Descriptor* descriptor, |
7154 DescriptorArray* old_descriptors = instance_descriptors(); | 7137 TransitionFlag flag) { |
7138 Handle<DescriptorArray> old_descriptors = handle(map->instance_descriptors()); | |
Toon Verwaest
2014/04/09 13:49:24
old_descriptors(map->...)
mvstanton
2014/04/09 14:26:06
Done.
| |
7155 | 7139 |
7156 // Ensure the key is unique. | 7140 // Ensure the key is unique. |
7157 MaybeObject* maybe_result = descriptor->KeyToUniqueName(); | 7141 descriptor->KeyToUniqueName(); |
7158 if (maybe_result->IsFailure()) return maybe_result; | |
7159 | 7142 |
7160 // We replace the key if it is already present. | 7143 // We replace the key if it is already present. |
7161 int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this); | 7144 int index = old_descriptors->SearchWithCache(*descriptor->GetKey(), *map); |
7162 if (index != DescriptorArray::kNotFound) { | 7145 if (index != DescriptorArray::kNotFound) { |
7163 return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag); | 7146 return Map::CopyReplaceDescriptor(map, old_descriptors, descriptor, |
Toon Verwaest
2014/04/09 13:49:24
nit: In general, whenever arguments overflow, eith
mvstanton
2014/04/09 14:26:06
Done.
| |
7147 index, flag); | |
7164 } | 7148 } |
7165 return CopyAddDescriptor(descriptor, flag); | 7149 return Map::CopyAddDescriptor(map, descriptor, flag); |
7150 } | |
7151 | |
7152 | |
7153 Handle<DescriptorArray> DescriptorArray::CopyUpTo( | |
7154 Handle<DescriptorArray> desc, | |
7155 int enumeration_index) { | |
7156 return DescriptorArray::CopyUpToAddAttributes(desc, | |
7157 enumeration_index, | |
7158 NONE); | |
7166 } | 7159 } |
7167 | 7160 |
7168 | 7161 |
7169 Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes( | 7162 Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes( |
7170 Handle<DescriptorArray> desc, | 7163 Handle<DescriptorArray> desc, |
7171 int enumeration_index, | 7164 int enumeration_index, |
7172 PropertyAttributes attributes) { | 7165 PropertyAttributes attributes) { |
7173 CALL_HEAP_FUNCTION(desc->GetIsolate(), | 7166 if (enumeration_index == 0) { |
7174 desc->CopyUpToAddAttributes(enumeration_index, attributes), | 7167 return desc->GetIsolate()->factory()->empty_descriptor_array(); |
7175 DescriptorArray); | 7168 } |
7176 } | |
7177 | |
7178 | |
7179 MaybeObject* DescriptorArray::CopyUpToAddAttributes( | |
7180 int enumeration_index, PropertyAttributes attributes) { | |
7181 if (enumeration_index == 0) return GetHeap()->empty_descriptor_array(); | |
7182 | 7169 |
7183 int size = enumeration_index; | 7170 int size = enumeration_index; |
7184 | 7171 |
7185 DescriptorArray* descriptors; | 7172 Handle<DescriptorArray> descriptors = |
7186 MaybeObject* maybe_descriptors = Allocate(GetIsolate(), size); | 7173 desc->GetIsolate()->factory()->NewDescriptorArray(size); |
7187 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; | 7174 DescriptorArray::WhitenessWitness witness(*descriptors); |
7188 DescriptorArray::WhitenessWitness witness(descriptors); | |
7189 | 7175 |
7190 if (attributes != NONE) { | 7176 if (attributes != NONE) { |
7191 for (int i = 0; i < size; ++i) { | 7177 for (int i = 0; i < size; ++i) { |
7192 Object* value = GetValue(i); | 7178 Object* value = desc->GetValue(i); |
7193 PropertyDetails details = GetDetails(i); | 7179 PropertyDetails details = desc->GetDetails(i); |
7194 int mask = DONT_DELETE | DONT_ENUM; | 7180 int mask = DONT_DELETE | DONT_ENUM; |
7195 // READ_ONLY is an invalid attribute for JS setters/getters. | 7181 // READ_ONLY is an invalid attribute for JS setters/getters. |
7196 if (details.type() != CALLBACKS || !value->IsAccessorPair()) { | 7182 if (details.type() != CALLBACKS || !value->IsAccessorPair()) { |
7197 mask |= READ_ONLY; | 7183 mask |= READ_ONLY; |
7198 } | 7184 } |
7199 details = details.CopyAddAttributes( | 7185 details = details.CopyAddAttributes( |
7200 static_cast<PropertyAttributes>(attributes & mask)); | 7186 static_cast<PropertyAttributes>(attributes & mask)); |
7201 Descriptor desc(GetKey(i), value, details); | 7187 Descriptor inner_desc(handle(desc->GetKey(i)), |
7202 descriptors->Set(i, &desc, witness); | 7188 handle(value, desc->GetIsolate()), |
7189 details); | |
7190 descriptors->Set(i, &inner_desc, witness); | |
7203 } | 7191 } |
7204 } else { | 7192 } else { |
7205 for (int i = 0; i < size; ++i) { | 7193 for (int i = 0; i < size; ++i) { |
7206 descriptors->CopyFrom(i, this, i, witness); | 7194 descriptors->CopyFrom(i, *desc, i, witness); |
7207 } | 7195 } |
7208 } | 7196 } |
7209 | 7197 |
7210 if (number_of_descriptors() != enumeration_index) descriptors->Sort(); | 7198 if (desc->number_of_descriptors() != enumeration_index) descriptors->Sort(); |
7211 | 7199 |
7212 return descriptors; | 7200 return descriptors; |
7213 } | 7201 } |
7214 | 7202 |
7215 | 7203 |
7216 MaybeObject* Map::CopyReplaceDescriptor(DescriptorArray* descriptors, | 7204 Handle<Map> Map::CopyReplaceDescriptor(Handle<Map> map, |
7217 Descriptor* descriptor, | 7205 Handle<DescriptorArray> descriptors, |
7218 int insertion_index, | 7206 Descriptor* descriptor, |
7219 TransitionFlag flag) { | 7207 int insertion_index, |
7208 TransitionFlag flag) { | |
7220 // Ensure the key is unique. | 7209 // Ensure the key is unique. |
7221 MaybeObject* maybe_failure = descriptor->KeyToUniqueName(); | 7210 descriptor->KeyToUniqueName(); |
7222 if (maybe_failure->IsFailure()) return maybe_failure; | |
7223 | 7211 |
7224 Name* key = descriptor->GetKey(); | 7212 Handle<Name> key = descriptor->GetKey(); |
7225 ASSERT(key == descriptors->GetKey(insertion_index)); | 7213 ASSERT(*key == descriptors->GetKey(insertion_index)); |
7226 | 7214 |
7227 int new_size = NumberOfOwnDescriptors(); | 7215 int new_size = map->NumberOfOwnDescriptors(); |
7228 ASSERT(0 <= insertion_index && insertion_index < new_size); | 7216 ASSERT(0 <= insertion_index && insertion_index < new_size); |
7229 | 7217 |
7230 ASSERT_LT(insertion_index, new_size); | 7218 ASSERT_LT(insertion_index, new_size); |
7231 | 7219 |
7232 DescriptorArray* new_descriptors; | 7220 Handle<DescriptorArray> new_descriptors = |
7233 MaybeObject* maybe_descriptors = | 7221 map->GetIsolate()->factory()->NewDescriptorArray(new_size); |
7234 DescriptorArray::Allocate(GetIsolate(), new_size); | 7222 DescriptorArray::WhitenessWitness witness(*new_descriptors); |
7235 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; | |
7236 DescriptorArray::WhitenessWitness witness(new_descriptors); | |
7237 | 7223 |
7238 for (int i = 0; i < new_size; ++i) { | 7224 for (int i = 0; i < new_size; ++i) { |
7239 if (i == insertion_index) { | 7225 if (i == insertion_index) { |
7240 new_descriptors->Set(i, descriptor, witness); | 7226 new_descriptors->Set(i, descriptor, witness); |
7241 } else { | 7227 } else { |
7242 new_descriptors->CopyFrom(i, descriptors, i, witness); | 7228 new_descriptors->CopyFrom(i, *descriptors, i, witness); |
7243 } | 7229 } |
7244 } | 7230 } |
7245 | 7231 |
7246 // Re-sort if descriptors were removed. | 7232 new_descriptors->Sort(); |
7247 if (new_size != descriptors->length()) new_descriptors->Sort(); | |
7248 | 7233 |
7249 SimpleTransitionFlag simple_flag = | 7234 SimpleTransitionFlag simple_flag = |
7250 (insertion_index == descriptors->number_of_descriptors() - 1) | 7235 (insertion_index == descriptors->number_of_descriptors() - 1) |
7251 ? SIMPLE_TRANSITION | 7236 ? SIMPLE_TRANSITION |
7252 : FULL_TRANSITION; | 7237 : FULL_TRANSITION; |
7253 return CopyReplaceDescriptors(new_descriptors, flag, key, simple_flag); | 7238 return Map::CopyReplaceDescriptors(map, new_descriptors, flag, key, |
7239 simple_flag); | |
mvstanton
2014/04/09 14:26:06
All args on a new line.
| |
7254 } | 7240 } |
7255 | 7241 |
7256 | 7242 |
7257 void Map::UpdateCodeCache(Handle<Map> map, | 7243 void Map::UpdateCodeCache(Handle<Map> map, |
7258 Handle<Name> name, | 7244 Handle<Name> name, |
7259 Handle<Code> code) { | 7245 Handle<Code> code) { |
7260 Isolate* isolate = map->GetIsolate(); | 7246 Isolate* isolate = map->GetIsolate(); |
7261 CALL_HEAP_FUNCTION_VOID(isolate, | 7247 CALL_HEAP_FUNCTION_VOID(isolate, |
7262 map->UpdateCodeCache(*name, *code)); | 7248 map->UpdateCodeCache(*name, *code)); |
7263 } | 7249 } |
(...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8087 set(kEnumCacheIndex, bridge_storage); | 8073 set(kEnumCacheIndex, bridge_storage); |
8088 } | 8074 } |
8089 | 8075 |
8090 | 8076 |
8091 void DescriptorArray::CopyFrom(int dst_index, | 8077 void DescriptorArray::CopyFrom(int dst_index, |
8092 DescriptorArray* src, | 8078 DescriptorArray* src, |
8093 int src_index, | 8079 int src_index, |
8094 const WhitenessWitness& witness) { | 8080 const WhitenessWitness& witness) { |
8095 Object* value = src->GetValue(src_index); | 8081 Object* value = src->GetValue(src_index); |
8096 PropertyDetails details = src->GetDetails(src_index); | 8082 PropertyDetails details = src->GetDetails(src_index); |
8097 Descriptor desc(src->GetKey(src_index), value, details); | 8083 Descriptor desc(handle(src->GetKey(src_index)), |
8084 handle(value, src->GetIsolate()), | |
8085 details); | |
8098 Set(dst_index, &desc, witness); | 8086 Set(dst_index, &desc, witness); |
8099 } | 8087 } |
8100 | 8088 |
8101 | 8089 |
8102 // Creates a new descriptor array by merging the descriptor array of |right_map| | 8090 // Creates a new descriptor array by merging the descriptor array of |right_map| |
8103 // into the (at least partly) updated descriptor array of |left_map|. | 8091 // into the (at least partly) updated descriptor array of |left_map|. |
8104 // The method merges two descriptor array in three parts. Both descriptor arrays | 8092 // The method merges two descriptor array in three parts. Both descriptor arrays |
8105 // are identical up to |verbatim|. They also overlap in keys up to |valid|. | 8093 // are identical up to |verbatim|. They also overlap in keys up to |valid|. |
8106 // Between |verbatim| and |valid|, the resulting descriptor type as well as the | 8094 // Between |verbatim| and |valid|, the resulting descriptor type as well as the |
8107 // representation are generalized from both |left_map| and |right_map|. Beyond | 8095 // representation are generalized from both |left_map| and |right_map|. Beyond |
(...skipping 22 matching lines...) Expand all Loading... | |
8130 result->NumberOfSlackDescriptors() > 0 || | 8118 result->NumberOfSlackDescriptors() > 0 || |
8131 result->number_of_descriptors() == right->number_of_descriptors()); | 8119 result->number_of_descriptors() == right->number_of_descriptors()); |
8132 ASSERT(result->number_of_descriptors() == new_size); | 8120 ASSERT(result->number_of_descriptors() == new_size); |
8133 | 8121 |
8134 int descriptor; | 8122 int descriptor; |
8135 | 8123 |
8136 // 0 -> |verbatim| | 8124 // 0 -> |verbatim| |
8137 int current_offset = 0; | 8125 int current_offset = 0; |
8138 for (descriptor = 0; descriptor < verbatim; descriptor++) { | 8126 for (descriptor = 0; descriptor < verbatim; descriptor++) { |
8139 if (left->GetDetails(descriptor).type() == FIELD) current_offset++; | 8127 if (left->GetDetails(descriptor).type() == FIELD) current_offset++; |
8140 Descriptor d(right->GetKey(descriptor), | 8128 Descriptor d(handle(right->GetKey(descriptor)), |
8141 right->GetValue(descriptor), | 8129 handle(right->GetValue(descriptor), right->GetIsolate()), |
8142 right->GetDetails(descriptor)); | 8130 right->GetDetails(descriptor)); |
8143 result->Set(descriptor, &d); | 8131 result->Set(descriptor, &d); |
8144 } | 8132 } |
8145 | 8133 |
8146 // |verbatim| -> |valid| | 8134 // |verbatim| -> |valid| |
8147 for (; descriptor < valid; descriptor++) { | 8135 for (; descriptor < valid; descriptor++) { |
8148 PropertyDetails left_details = left->GetDetails(descriptor); | 8136 PropertyDetails left_details = left->GetDetails(descriptor); |
8149 PropertyDetails right_details = right->GetDetails(descriptor); | 8137 PropertyDetails right_details = right->GetDetails(descriptor); |
8150 if (left_details.type() == FIELD || right_details.type() == FIELD || | 8138 if (left_details.type() == FIELD || right_details.type() == FIELD || |
8151 (store_mode == FORCE_FIELD && descriptor == modify_index) || | 8139 (store_mode == FORCE_FIELD && descriptor == modify_index) || |
8152 (left_details.type() == CONSTANT && | 8140 (left_details.type() == CONSTANT && |
8153 right_details.type() == CONSTANT && | 8141 right_details.type() == CONSTANT && |
8154 left->GetValue(descriptor) != right->GetValue(descriptor))) { | 8142 left->GetValue(descriptor) != right->GetValue(descriptor))) { |
8155 Representation representation = left_details.representation().generalize( | 8143 Representation representation = left_details.representation().generalize( |
8156 right_details.representation()); | 8144 right_details.representation()); |
8157 FieldDescriptor d(left->GetKey(descriptor), | 8145 FieldDescriptor d(handle(left->GetKey(descriptor)), |
8158 current_offset++, | 8146 current_offset++, |
8159 right_details.attributes(), | 8147 right_details.attributes(), |
8160 representation); | 8148 representation); |
8161 result->Set(descriptor, &d); | 8149 result->Set(descriptor, &d); |
8162 } else { | 8150 } else { |
8163 Descriptor d(right->GetKey(descriptor), | 8151 Descriptor d(handle(right->GetKey(descriptor)), |
8164 right->GetValue(descriptor), | 8152 handle(right->GetValue(descriptor), right->GetIsolate()), |
8165 right_details); | 8153 right_details); |
8166 result->Set(descriptor, &d); | 8154 result->Set(descriptor, &d); |
8167 } | 8155 } |
8168 } | 8156 } |
8169 | 8157 |
8170 // |valid| -> |new_size| | 8158 // |valid| -> |new_size| |
8171 for (; descriptor < new_size; descriptor++) { | 8159 for (; descriptor < new_size; descriptor++) { |
8172 PropertyDetails right_details = right->GetDetails(descriptor); | 8160 PropertyDetails right_details = right->GetDetails(descriptor); |
8173 if (right_details.type() == FIELD || | 8161 if (right_details.type() == FIELD || |
8174 (store_mode == FORCE_FIELD && descriptor == modify_index)) { | 8162 (store_mode == FORCE_FIELD && descriptor == modify_index)) { |
8175 FieldDescriptor d(right->GetKey(descriptor), | 8163 FieldDescriptor d(handle(right->GetKey(descriptor)), |
8176 current_offset++, | 8164 current_offset++, |
8177 right_details.attributes(), | 8165 right_details.attributes(), |
8178 right_details.representation()); | 8166 right_details.representation()); |
8179 result->Set(descriptor, &d); | 8167 result->Set(descriptor, &d); |
8180 } else { | 8168 } else { |
8181 Descriptor d(right->GetKey(descriptor), | 8169 Descriptor d(handle(right->GetKey(descriptor)), |
8182 right->GetValue(descriptor), | 8170 handle(right->GetValue(descriptor), right->GetIsolate()), |
8183 right_details); | 8171 right_details); |
8184 result->Set(descriptor, &d); | 8172 result->Set(descriptor, &d); |
8185 } | 8173 } |
8186 } | 8174 } |
8187 | 8175 |
8188 result->Sort(); | 8176 result->Sort(); |
8189 return result; | 8177 return result; |
8190 } | 8178 } |
8191 | 8179 |
8192 | 8180 |
(...skipping 1583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9776 if (object->IsGlobalObject()) return; | 9764 if (object->IsGlobalObject()) return; |
9777 | 9765 |
9778 // Make sure prototypes are fast objects and their maps have the bit set | 9766 // Make sure prototypes are fast objects and their maps have the bit set |
9779 // so they remain fast. | 9767 // so they remain fast. |
9780 if (!object->HasFastProperties()) { | 9768 if (!object->HasFastProperties()) { |
9781 TransformToFastProperties(object, 0); | 9769 TransformToFastProperties(object, 0); |
9782 } | 9770 } |
9783 } | 9771 } |
9784 | 9772 |
9785 | 9773 |
9786 static MUST_USE_RESULT MaybeObject* CacheInitialJSArrayMaps( | 9774 Handle<Object> CacheInitialJSArrayMaps( |
9787 Context* native_context, Map* initial_map) { | 9775 Handle<Context> native_context, Handle<Map> initial_map) { |
9788 // Replace all of the cached initial array maps in the native context with | 9776 // Replace all of the cached initial array maps in the native context with |
9789 // the appropriate transitioned elements kind maps. | 9777 // the appropriate transitioned elements kind maps. |
9790 Heap* heap = native_context->GetHeap(); | 9778 Factory* factory = native_context->GetIsolate()->factory(); |
9791 MaybeObject* maybe_maps = | 9779 Handle<FixedArray> maps = factory->NewFixedArrayWithHoles( |
9792 heap->AllocateFixedArrayWithHoles(kElementsKindCount, TENURED); | 9780 kElementsKindCount, TENURED); |
9793 FixedArray* maps; | |
9794 if (!maybe_maps->To(&maps)) return maybe_maps; | |
9795 | 9781 |
9796 Map* current_map = initial_map; | 9782 Handle<Map> current_map = initial_map; |
9797 ElementsKind kind = current_map->elements_kind(); | 9783 ElementsKind kind = current_map->elements_kind(); |
9798 ASSERT(kind == GetInitialFastElementsKind()); | 9784 ASSERT(kind == GetInitialFastElementsKind()); |
9799 maps->set(kind, current_map); | 9785 maps->set(kind, *current_map); |
9800 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1; | 9786 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1; |
9801 i < kFastElementsKindCount; ++i) { | 9787 i < kFastElementsKindCount; ++i) { |
9802 Map* new_map; | 9788 Handle<Map> new_map; |
9803 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i); | 9789 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i); |
9804 if (current_map->HasElementsTransition()) { | 9790 if (current_map->HasElementsTransition()) { |
9805 new_map = current_map->elements_transition_map(); | 9791 new_map = handle(current_map->elements_transition_map()); |
9806 ASSERT(new_map->elements_kind() == next_kind); | 9792 ASSERT(new_map->elements_kind() == next_kind); |
9807 } else { | 9793 } else { |
9808 MaybeObject* maybe_new_map = | 9794 new_map = Map::CopyAsElementsKind(current_map, next_kind, |
9809 current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION); | 9795 INSERT_TRANSITION); |
mvstanton
2014/04/09 14:26:06
Args all on new line.
| |
9810 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | |
9811 } | 9796 } |
9812 maps->set(next_kind, new_map); | 9797 maps->set(next_kind, *new_map); |
9813 current_map = new_map; | 9798 current_map = new_map; |
9814 } | 9799 } |
9815 native_context->set_js_array_maps(maps); | 9800 native_context->set_js_array_maps(*maps); |
9816 return initial_map; | 9801 return initial_map; |
9817 } | 9802 } |
9818 | 9803 |
9819 | 9804 |
9820 Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context, | |
9821 Handle<Map> initial_map) { | |
9822 CALL_HEAP_FUNCTION(native_context->GetIsolate(), | |
9823 CacheInitialJSArrayMaps(*native_context, *initial_map), | |
9824 Object); | |
9825 } | |
9826 | |
9827 | |
9828 void JSFunction::SetInstancePrototype(Handle<JSFunction> function, | 9805 void JSFunction::SetInstancePrototype(Handle<JSFunction> function, |
9829 Handle<Object> value) { | 9806 Handle<Object> value) { |
9830 ASSERT(value->IsJSReceiver()); | 9807 ASSERT(value->IsJSReceiver()); |
9831 | 9808 |
9832 // First some logic for the map of the prototype to make sure it is in fast | 9809 // First some logic for the map of the prototype to make sure it is in fast |
9833 // mode. | 9810 // mode. |
9834 if (value->IsJSObject()) { | 9811 if (value->IsJSObject()) { |
9835 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); | 9812 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); |
9836 } | 9813 } |
9837 | 9814 |
(...skipping 5879 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15717 // instance descriptor. | 15694 // instance descriptor. |
15718 MaybeObject* maybe_key = heap->InternalizeString(String::cast(k)); | 15695 MaybeObject* maybe_key = heap->InternalizeString(String::cast(k)); |
15719 if (!maybe_key->To(&key)) return maybe_key; | 15696 if (!maybe_key->To(&key)) return maybe_key; |
15720 } | 15697 } |
15721 | 15698 |
15722 PropertyDetails details = DetailsAt(i); | 15699 PropertyDetails details = DetailsAt(i); |
15723 int enumeration_index = details.dictionary_index(); | 15700 int enumeration_index = details.dictionary_index(); |
15724 PropertyType type = details.type(); | 15701 PropertyType type = details.type(); |
15725 | 15702 |
15726 if (value->IsJSFunction()) { | 15703 if (value->IsJSFunction()) { |
15727 ConstantDescriptor d(key, value, details.attributes()); | 15704 ConstantDescriptor d(handle(key), |
15705 handle(value, GetIsolate()), | |
15706 details.attributes()); | |
15728 descriptors->Set(enumeration_index - 1, &d, witness); | 15707 descriptors->Set(enumeration_index - 1, &d, witness); |
15729 } else if (type == NORMAL) { | 15708 } else if (type == NORMAL) { |
15730 if (current_offset < inobject_props) { | 15709 if (current_offset < inobject_props) { |
15731 obj->InObjectPropertyAtPut(current_offset, | 15710 obj->InObjectPropertyAtPut(current_offset, |
15732 value, | 15711 value, |
15733 UPDATE_WRITE_BARRIER); | 15712 UPDATE_WRITE_BARRIER); |
15734 } else { | 15713 } else { |
15735 int offset = current_offset - inobject_props; | 15714 int offset = current_offset - inobject_props; |
15736 fields->set(offset, value); | 15715 fields->set(offset, value); |
15737 } | 15716 } |
15738 FieldDescriptor d(key, | 15717 FieldDescriptor d(handle(key), |
15739 current_offset++, | 15718 current_offset++, |
15740 details.attributes(), | 15719 details.attributes(), |
15741 // TODO(verwaest): value->OptimalRepresentation(); | 15720 // TODO(verwaest): value->OptimalRepresentation(); |
15742 Representation::Tagged()); | 15721 Representation::Tagged()); |
15743 descriptors->Set(enumeration_index - 1, &d, witness); | 15722 descriptors->Set(enumeration_index - 1, &d, witness); |
15744 } else if (type == CALLBACKS) { | 15723 } else if (type == CALLBACKS) { |
15745 CallbacksDescriptor d(key, | 15724 CallbacksDescriptor d(handle(key), |
15746 value, | 15725 handle(value, GetIsolate()), |
15747 details.attributes()); | 15726 details.attributes()); |
15748 descriptors->Set(enumeration_index - 1, &d, witness); | 15727 descriptors->Set(enumeration_index - 1, &d, witness); |
15749 } else { | 15728 } else { |
15750 UNREACHABLE(); | 15729 UNREACHABLE(); |
15751 } | 15730 } |
15752 } | 15731 } |
15753 } | 15732 } |
15754 ASSERT(current_offset == number_of_fields); | 15733 ASSERT(current_offset == number_of_fields); |
15755 | 15734 |
15756 descriptors->Sort(); | 15735 descriptors->Sort(); |
(...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16739 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16718 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16740 static const char* error_messages_[] = { | 16719 static const char* error_messages_[] = { |
16741 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16720 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16742 }; | 16721 }; |
16743 #undef ERROR_MESSAGES_TEXTS | 16722 #undef ERROR_MESSAGES_TEXTS |
16744 return error_messages_[reason]; | 16723 return error_messages_[reason]; |
16745 } | 16724 } |
16746 | 16725 |
16747 | 16726 |
16748 } } // namespace v8::internal | 16727 } } // namespace v8::internal |
OLD | NEW |