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

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: Last comments. 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
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 = 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
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(&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(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(&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 = 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
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 = 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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698