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

Side by Side Diff: src/objects.cc

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

Powered by Google App Engine
This is Rietveld 408576698