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

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: 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 1954 matching lines...) Expand 10 before | Expand all | Expand 10 after
1965 static Handle<Object> NewStorageFor(Isolate* isolate, 1965 static Handle<Object> NewStorageFor(Isolate* isolate,
1966 Handle<Object> object, 1966 Handle<Object> object,
1967 Representation representation) { 1967 Representation representation) {
1968 Heap* heap = isolate->heap(); 1968 Heap* heap = isolate->heap();
1969 CALL_HEAP_FUNCTION(isolate, 1969 CALL_HEAP_FUNCTION(isolate,
1970 object->AllocateNewStorageFor(heap, representation), 1970 object->AllocateNewStorageFor(heap, representation),
1971 Object); 1971 Object);
1972 } 1972 }
1973 1973
1974 1974
1975 static MaybeObject* CopyAddFieldDescriptor(Map* map, 1975 static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map,
1976 Name* name, 1976 Handle<Name> name,
1977 int index, 1977 int index,
1978 PropertyAttributes attributes, 1978 PropertyAttributes attributes,
1979 Representation representation, 1979 Representation representation,
1980 TransitionFlag flag) { 1980 TransitionFlag flag) {
1981 Map* new_map;
1982 FieldDescriptor new_field_desc(name, index, attributes, representation); 1981 FieldDescriptor new_field_desc(name, index, attributes, representation);
1983 MaybeObject* maybe_map = map->CopyAddDescriptor(&new_field_desc, flag); 1982 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag);
1984 if (!maybe_map->To(&new_map)) return maybe_map;
1985 int unused_property_fields = map->unused_property_fields() - 1; 1983 int unused_property_fields = map->unused_property_fields() - 1;
1986 if (unused_property_fields < 0) { 1984 if (unused_property_fields < 0) {
1987 unused_property_fields += JSObject::kFieldsAdded; 1985 unused_property_fields += JSObject::kFieldsAdded;
1988 } 1986 }
1989 new_map->set_unused_property_fields(unused_property_fields); 1987 new_map->set_unused_property_fields(unused_property_fields);
1990 return new_map; 1988 return new_map;
1991 } 1989 }
1992 1990
1993 1991
1994 static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map,
1995 Handle<Name> name,
1996 int index,
1997 PropertyAttributes attributes,
1998 Representation representation,
1999 TransitionFlag flag) {
2000 CALL_HEAP_FUNCTION(map->GetIsolate(),
2001 CopyAddFieldDescriptor(
2002 *map, *name, index, attributes, representation, flag),
2003 Map);
2004 }
2005
2006
2007 void JSObject::AddFastProperty(Handle<JSObject> object, 1992 void JSObject::AddFastProperty(Handle<JSObject> object,
2008 Handle<Name> name, 1993 Handle<Name> name,
2009 Handle<Object> value, 1994 Handle<Object> value,
2010 PropertyAttributes attributes, 1995 PropertyAttributes attributes,
2011 StoreFromKeyed store_mode, 1996 StoreFromKeyed store_mode,
2012 ValueType value_type, 1997 ValueType value_type,
2013 TransitionFlag flag) { 1998 TransitionFlag flag) {
2014 ASSERT(!object->IsJSGlobalProxy()); 1999 ASSERT(!object->IsJSGlobalProxy());
2015 ASSERT(DescriptorArray::kNotFound == 2000 ASSERT(DescriptorArray::kNotFound ==
2016 object->map()->instance_descriptors()->Search( 2001 object->map()->instance_descriptors()->Search(
(...skipping 25 matching lines...) Expand all
2042 // Nothing more to be done. 2027 // Nothing more to be done.
2043 if (value->IsUninitialized()) return; 2028 if (value->IsUninitialized()) return;
2044 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index)); 2029 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index));
2045 box->set_value(value->Number()); 2030 box->set_value(value->Number());
2046 } else { 2031 } else {
2047 object->FastPropertyAtPut(index, *value); 2032 object->FastPropertyAtPut(index, *value);
2048 } 2033 }
2049 } 2034 }
2050 2035
2051 2036
2052 static MaybeObject* CopyAddConstantDescriptor(Map* map,
2053 Name* name,
2054 Object* value,
2055 PropertyAttributes attributes,
2056 TransitionFlag flag) {
2057 ConstantDescriptor new_constant_desc(name, value, attributes);
2058 return map->CopyAddDescriptor(&new_constant_desc, flag);
2059 }
2060
2061
2062 static Handle<Map> CopyAddConstantDescriptor(Handle<Map> map, 2037 static Handle<Map> CopyAddConstantDescriptor(Handle<Map> map,
2063 Handle<Name> name, 2038 Handle<Name> name,
2064 Handle<Object> value, 2039 Handle<Object> value,
2065 PropertyAttributes attributes, 2040 PropertyAttributes attributes,
2066 TransitionFlag flag) { 2041 TransitionFlag flag) {
2067 CALL_HEAP_FUNCTION(map->GetIsolate(), 2042 ConstantDescriptor new_constant_desc(name, value, attributes);
2068 CopyAddConstantDescriptor( 2043 return Map::CopyAddDescriptor(map, &new_constant_desc, flag);
2069 *map, *name, *value, attributes, flag),
2070 Map);
2071 } 2044 }
2072 2045
2073 2046
2074 void JSObject::AddConstantProperty(Handle<JSObject> object, 2047 void JSObject::AddConstantProperty(Handle<JSObject> object,
2075 Handle<Name> name, 2048 Handle<Name> name,
2076 Handle<Object> constant, 2049 Handle<Object> constant,
2077 PropertyAttributes attributes, 2050 PropertyAttributes attributes,
2078 TransitionFlag initial_flag) { 2051 TransitionFlag initial_flag) {
2079 TransitionFlag flag = 2052 TransitionFlag flag =
2080 // Do not add transitions to global objects. 2053 // Do not add transitions to global objects.
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
2353 ASSERT(target_inobject < inobject_properties()); 2326 ASSERT(target_inobject < inobject_properties());
2354 if (target_number_of_fields <= target_inobject) { 2327 if (target_number_of_fields <= target_inobject) {
2355 ASSERT(target_number_of_fields + target_unused == target_inobject); 2328 ASSERT(target_number_of_fields + target_unused == target_inobject);
2356 return false; 2329 return false;
2357 } 2330 }
2358 // Otherwise, properties will need to be moved to the backing store. 2331 // Otherwise, properties will need to be moved to the backing store.
2359 return true; 2332 return true;
2360 } 2333 }
2361 2334
2362 2335
2336 Handle<TransitionArray> Map::SetElementsTransitionMap(
2337 Handle<Map> map, Handle<Map> transitioned_map) {
2338 Handle<TransitionArray> transitions = map->AddTransition(
2339 map,
2340 map->GetIsolate()->factory()->elements_transition_symbol(),
2341 transitioned_map,
2342 FULL_TRANSITION);
2343 map->set_transitions(*transitions);
2344 return transitions;
2345 }
2346
2347
2363 // To migrate an instance to a map: 2348 // To migrate an instance to a map:
2364 // - First check whether the instance needs to be rewritten. If not, simply 2349 // - First check whether the instance needs to be rewritten. If not, simply
2365 // change the map. 2350 // change the map.
2366 // - Otherwise, allocate a fixed array large enough to hold all fields, in 2351 // - Otherwise, allocate a fixed array large enough to hold all fields, in
2367 // addition to unused space. 2352 // addition to unused space.
2368 // - Copy all existing properties in, in the following order: backing store 2353 // - Copy all existing properties in, in the following order: backing store
2369 // properties, unused fields, inobject properties. 2354 // properties, unused fields, inobject properties.
2370 // - If all allocation succeeded, commit the state atomically: 2355 // - If all allocation succeeded, commit the state atomically:
2371 // * Copy inobject properties from the backing store back into the object. 2356 // * Copy inobject properties from the backing store back into the object.
2372 // * Trim the difference in instance size of the object. This also cleanly 2357 // * Trim the difference in instance size of the object. This also cleanly
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2477 // thread can not get confused with the filler creation. No synchronization 2462 // thread can not get confused with the filler creation. No synchronization
2478 // needed. 2463 // needed.
2479 object->set_map(*new_map); 2464 object->set_map(*new_map);
2480 } 2465 }
2481 2466
2482 2467
2483 Handle<TransitionArray> Map::AddTransition(Handle<Map> map, 2468 Handle<TransitionArray> Map::AddTransition(Handle<Map> map,
2484 Handle<Name> key, 2469 Handle<Name> key,
2485 Handle<Map> target, 2470 Handle<Map> target,
2486 SimpleTransitionFlag flag) { 2471 SimpleTransitionFlag flag) {
2487 CALL_HEAP_FUNCTION(map->GetIsolate(), 2472 if (map->HasTransitionArray()) {
2488 map->AddTransition(*key, *target, flag), 2473 Handle<TransitionArray> transitions = handle(map->transitions());
2489 TransitionArray); 2474 return TransitionArray::CopyInsert(transitions, key, target);
2475 }
2476 return TransitionArray::NewWithHandle(flag, key, target,
2477 handle(map->GetBackPointer(),
2478 map->GetIsolate()));
2490 } 2479 }
2491 2480
2492 2481
2493 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, 2482 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object,
2494 int modify_index, 2483 int modify_index,
2495 Representation new_representation, 2484 Representation new_representation,
2496 StoreMode store_mode) { 2485 StoreMode store_mode) {
2497 Handle<Map> new_map = Map::GeneralizeRepresentation( 2486 Handle<Map> new_map = Map::GeneralizeRepresentation(
2498 handle(object->map()), modify_index, new_representation, store_mode); 2487 handle(object->map()), modify_index, new_representation, store_mode);
2499 if (object->map() == *new_map) return; 2488 if (object->map() == *new_map) return;
(...skipping 17 matching lines...) Expand all
2517 PropertyAttributes attributes, 2506 PropertyAttributes attributes,
2518 const char* reason) { 2507 const char* reason) {
2519 Handle<Map> new_map = Copy(map); 2508 Handle<Map> new_map = Copy(map);
2520 2509
2521 DescriptorArray* descriptors = new_map->instance_descriptors(); 2510 DescriptorArray* descriptors = new_map->instance_descriptors();
2522 descriptors->InitializeRepresentations(Representation::Tagged()); 2511 descriptors->InitializeRepresentations(Representation::Tagged());
2523 2512
2524 // Unless the instance is being migrated, ensure that modify_index is a field. 2513 // Unless the instance is being migrated, ensure that modify_index is a field.
2525 PropertyDetails details = descriptors->GetDetails(modify_index); 2514 PropertyDetails details = descriptors->GetDetails(modify_index);
2526 if (store_mode == FORCE_FIELD && details.type() != FIELD) { 2515 if (store_mode == FORCE_FIELD && details.type() != FIELD) {
2527 FieldDescriptor d(descriptors->GetKey(modify_index), 2516 FieldDescriptor d(handle(descriptors->GetKey(modify_index),
2517 map->GetIsolate()),
2528 new_map->NumberOfFields(), 2518 new_map->NumberOfFields(),
2529 attributes, 2519 attributes,
2530 Representation::Tagged()); 2520 Representation::Tagged());
2531 d.SetSortedKeyIndex(details.pointer()); 2521 d.SetSortedKeyIndex(details.pointer());
2532 descriptors->Set(modify_index, &d); 2522 descriptors->Set(modify_index, &d);
2533 int unused_property_fields = new_map->unused_property_fields() - 1; 2523 int unused_property_fields = new_map->unused_property_fields() - 1;
2534 if (unused_property_fields < 0) { 2524 if (unused_property_fields < 0) {
2535 unused_property_fields += JSObject::kFieldsAdded; 2525 unused_property_fields += JSObject::kFieldsAdded;
2536 } 2526 }
2537 new_map->set_unused_property_fields(unused_property_fields); 2527 new_map->set_unused_property_fields(unused_property_fields);
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
3153 } 3143 }
3154 3144
3155 struct DescriptorArrayAppender { 3145 struct DescriptorArrayAppender {
3156 typedef DescriptorArray Array; 3146 typedef DescriptorArray Array;
3157 static bool Contains(Name* key, 3147 static bool Contains(Name* key,
3158 AccessorInfo* entry, 3148 AccessorInfo* entry,
3159 int valid_descriptors, 3149 int valid_descriptors,
3160 Handle<DescriptorArray> array) { 3150 Handle<DescriptorArray> array) {
3161 return array->Search(key, valid_descriptors) != DescriptorArray::kNotFound; 3151 return array->Search(key, valid_descriptors) != DescriptorArray::kNotFound;
3162 } 3152 }
3163 static void Insert(Name* key, 3153 static void Insert(Name* key,
Toon Verwaest 2014/04/08 12:58:55 Can't call from unhandlified into handlified code!
mvstanton 2014/04/09 09:43:20 Fixed.
3164 AccessorInfo* entry, 3154 AccessorInfo* entry,
3165 int valid_descriptors, 3155 int valid_descriptors,
3166 Handle<DescriptorArray> array) { 3156 Handle<DescriptorArray> array) {
3167 CallbacksDescriptor desc(key, entry, entry->property_attributes()); 3157 CallbacksDescriptor desc(handle(key, array->GetIsolate()),
3158 handle(entry, array->GetIsolate()),
3159 entry->property_attributes());
3168 array->Append(&desc); 3160 array->Append(&desc);
3169 } 3161 }
3170 }; 3162 };
3171 3163
3172 3164
3173 struct FixedArrayAppender { 3165 struct FixedArrayAppender {
3174 typedef FixedArray Array; 3166 typedef FixedArray Array;
3175 static bool Contains(Name* key, 3167 static bool Contains(Name* key,
3176 AccessorInfo* entry, 3168 AccessorInfo* entry,
3177 int valid_descriptors, 3169 int valid_descriptors,
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
3296 } 3288 }
3297 3289
3298 if (isolate->initial_object_prototype()->map() == this) { 3290 if (isolate->initial_object_prototype()->map() == this) {
3299 return true; 3291 return true;
3300 } 3292 }
3301 3293
3302 return false; 3294 return false;
3303 } 3295 }
3304 3296
3305 3297
3306 static MaybeObject* AddMissingElementsTransitions(Map* map, 3298 static Handle<Map> AddMissingElementsTransitions(Handle<Map> map,
3307 ElementsKind to_kind) { 3299 ElementsKind to_kind) {
3308 ASSERT(IsTransitionElementsKind(map->elements_kind())); 3300 ASSERT(IsTransitionElementsKind(map->elements_kind()));
3309 3301
3310 Map* current_map = map; 3302 Handle<Map> current_map = map;
3311 3303
3312 ElementsKind kind = map->elements_kind(); 3304 ElementsKind kind = map->elements_kind();
3313 while (kind != to_kind && !IsTerminalElementsKind(kind)) { 3305 while (kind != to_kind && !IsTerminalElementsKind(kind)) {
3314 kind = GetNextTransitionElementsKind(kind); 3306 kind = GetNextTransitionElementsKind(kind);
3315 MaybeObject* maybe_next_map = 3307 current_map = Map::CopyAsElementsKind(current_map, kind,
3316 current_map->CopyAsElementsKind(kind, INSERT_TRANSITION); 3308 INSERT_TRANSITION);
3317 if (!maybe_next_map->To(&current_map)) return maybe_next_map;
3318 } 3309 }
3319 3310
3320 // In case we are exiting the fast elements kind system, just add the map in 3311 // In case we are exiting the fast elements kind system, just add the map in
3321 // the end. 3312 // the end.
3322 if (kind != to_kind) { 3313 if (kind != to_kind) {
3323 MaybeObject* maybe_next_map = 3314 current_map = Map::CopyAsElementsKind(current_map, to_kind,
3324 current_map->CopyAsElementsKind(to_kind, INSERT_TRANSITION); 3315 INSERT_TRANSITION);
3325 if (!maybe_next_map->To(&current_map)) return maybe_next_map;
3326 } 3316 }
3327 3317
3328 ASSERT(current_map->elements_kind() == to_kind); 3318 ASSERT(current_map->elements_kind() == to_kind);
3329 return current_map; 3319 return current_map;
3330 } 3320 }
3331 3321
3332 3322
3333 Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object, 3323 Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
3334 ElementsKind to_kind) { 3324 ElementsKind to_kind) {
3335 Isolate* isolate = object->GetIsolate(); 3325 Isolate* isolate = object->GetIsolate();
3336 CALL_HEAP_FUNCTION(isolate, 3326 Handle<Map> current_map = handle(object->map());
3337 object->GetElementsTransitionMap(isolate, to_kind), 3327 ElementsKind from_kind = current_map->elements_kind();
3338 Map); 3328 if (from_kind == to_kind) return current_map;
3329
Toon Verwaest 2014/04/08 12:58:55 DisallowHeapAllocation?
mvstanton 2014/04/09 09:43:20 Done.
3330 Context* native_context = isolate->context()->native_context();
3331 Object* maybe_array_maps = native_context->js_array_maps();
3332 if (maybe_array_maps->IsFixedArray()) {
3333 FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
3334 if (array_maps->get(from_kind) == *current_map) {
3335 Object* maybe_transitioned_map = array_maps->get(to_kind);
3336 if (maybe_transitioned_map->IsMap()) {
3337 return handle(Map::cast(maybe_transitioned_map));
3338 }
3339 }
3340 }
3341
3342 return GetElementsTransitionMapSlow(object, to_kind);
3339 } 3343 }
3340 3344
3341 3345
3342 MaybeObject* JSObject::GetElementsTransitionMapSlow(ElementsKind to_kind) { 3346 Handle<Map> JSObject::GetElementsTransitionMapSlow(Handle<JSObject> object,
3343 Map* start_map = map(); 3347 ElementsKind to_kind) {
3348 Handle<Map> start_map = handle(object->map());
3344 ElementsKind from_kind = start_map->elements_kind(); 3349 ElementsKind from_kind = start_map->elements_kind();
3345 3350
3346 if (from_kind == to_kind) { 3351 if (from_kind == to_kind) {
3347 return start_map; 3352 return start_map;
3348 } 3353 }
3349 3354
3350 bool allow_store_transition = 3355 bool allow_store_transition =
3351 // Only remember the map transition if there is not an already existing 3356 // Only remember the map transition if there is not an already existing
3352 // non-matching element transition. 3357 // non-matching element transition.
3353 !start_map->IsUndefined() && !start_map->is_shared() && 3358 !start_map->IsUndefined() && !start_map->is_shared() &&
3354 IsTransitionElementsKind(from_kind); 3359 IsTransitionElementsKind(from_kind);
3355 3360
3356 // Only store fast element maps in ascending generality. 3361 // Only store fast element maps in ascending generality.
3357 if (IsFastElementsKind(to_kind)) { 3362 if (IsFastElementsKind(to_kind)) {
3358 allow_store_transition &= 3363 allow_store_transition &=
3359 IsTransitionableFastElementsKind(from_kind) && 3364 IsTransitionableFastElementsKind(from_kind) &&
3360 IsMoreGeneralElementsKindTransition(from_kind, to_kind); 3365 IsMoreGeneralElementsKindTransition(from_kind, to_kind);
3361 } 3366 }
3362 3367
3363 if (!allow_store_transition) { 3368 if (!allow_store_transition) {
3364 return start_map->CopyAsElementsKind(to_kind, OMIT_TRANSITION); 3369 return Map::CopyAsElementsKind(start_map, to_kind, OMIT_TRANSITION);
3365 } 3370 }
3366 3371
3367 return start_map->AsElementsKind(to_kind); 3372 return Map::AsElementsKind(start_map, to_kind);
3368 } 3373 }
3369 3374
3370 3375
3371 // TODO(ishell): Temporary wrapper until handlified.
3372 // static 3376 // static
3373 Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) { 3377 Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) {
3374 CALL_HEAP_FUNCTION(map->GetIsolate(), 3378 Handle<Map> closest_map = handle(FindClosestElementsTransition(*map, kind));
3375 map->AsElementsKind(kind),
3376 Map);
3377 }
3378
3379
3380 MaybeObject* Map::AsElementsKind(ElementsKind kind) {
3381 Map* closest_map = FindClosestElementsTransition(this, kind);
3382 3379
3383 if (closest_map->elements_kind() == kind) { 3380 if (closest_map->elements_kind() == kind) {
3384 return closest_map; 3381 return closest_map;
3385 } 3382 }
3386 3383
3387 return AddMissingElementsTransitions(closest_map, kind); 3384 return AddMissingElementsTransitions(closest_map, kind);
3388 } 3385 }
3389 3386
3390 3387
3391 void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) { 3388 void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) {
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
3832 return Handle<Object>(); 3829 return Handle<Object>();
3833 } 3830 }
3834 trap = Handle<Object>(derived); 3831 trap = Handle<Object>(derived);
3835 } 3832 }
3836 3833
3837 bool threw; 3834 bool threw;
3838 return Execution::Call(isolate, trap, handler, argc, argv, &threw); 3835 return Execution::Call(isolate, trap, handler, argc, argv, &threw);
3839 } 3836 }
3840 3837
3841 3838
3842 // TODO(mstarzinger): Temporary wrapper until handlified.
3843 static Handle<Map> MapAsElementsKind(Handle<Map> map, ElementsKind kind) {
3844 CALL_HEAP_FUNCTION(map->GetIsolate(), map->AsElementsKind(kind), Map);
3845 }
3846
3847
3848 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) { 3839 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
3849 ASSERT(object->map()->inobject_properties() == map->inobject_properties()); 3840 ASSERT(object->map()->inobject_properties() == map->inobject_properties());
3850 ElementsKind obj_kind = object->map()->elements_kind(); 3841 ElementsKind obj_kind = object->map()->elements_kind();
3851 ElementsKind map_kind = map->elements_kind(); 3842 ElementsKind map_kind = map->elements_kind();
3852 if (map_kind != obj_kind) { 3843 if (map_kind != obj_kind) {
3853 ElementsKind to_kind = map_kind; 3844 ElementsKind to_kind = map_kind;
3854 if (IsMoreGeneralElementsKindTransition(map_kind, obj_kind) || 3845 if (IsMoreGeneralElementsKindTransition(map_kind, obj_kind) ||
3855 IsDictionaryElementsKind(obj_kind)) { 3846 IsDictionaryElementsKind(obj_kind)) {
3856 to_kind = obj_kind; 3847 to_kind = obj_kind;
3857 } 3848 }
3858 if (IsDictionaryElementsKind(to_kind)) { 3849 if (IsDictionaryElementsKind(to_kind)) {
3859 NormalizeElements(object); 3850 NormalizeElements(object);
3860 } else { 3851 } else {
3861 TransitionElementsKind(object, to_kind); 3852 TransitionElementsKind(object, to_kind);
3862 } 3853 }
3863 map = MapAsElementsKind(map, to_kind); 3854 map = Map::AsElementsKind(map, to_kind);
3864 } 3855 }
3865 JSObject::MigrateToMap(object, map); 3856 JSObject::MigrateToMap(object, map);
3866 } 3857 }
3867 3858
3868 3859
3869 void JSObject::MigrateInstance(Handle<JSObject> object) { 3860 void JSObject::MigrateInstance(Handle<JSObject> object) {
3870 // Converting any field to the most specific type will cause the 3861 // Converting any field to the most specific type will cause the
3871 // GeneralizeFieldRepresentation algorithm to create the most general existing 3862 // GeneralizeFieldRepresentation algorithm to create the most general existing
3872 // transition that matches the object. This achieves what is needed. 3863 // transition that matches the object. This achieves what is needed.
3873 Handle<Map> original_map(object->map()); 3864 Handle<Map> original_map(object->map());
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after
4692 if (object->HasFastProperties()) return; 4683 if (object->HasFastProperties()) return;
4693 ASSERT(!object->IsGlobalObject()); 4684 ASSERT(!object->IsGlobalObject());
4694 CALL_HEAP_FUNCTION_VOID( 4685 CALL_HEAP_FUNCTION_VOID(
4695 object->GetIsolate(), 4686 object->GetIsolate(),
4696 object->property_dictionary()->TransformPropertiesToFastFor( 4687 object->property_dictionary()->TransformPropertiesToFastFor(
4697 *object, unused_property_fields)); 4688 *object, unused_property_fields));
4698 } 4689 }
4699 4690
4700 4691
4701 void JSObject::ResetElements(Handle<JSObject> object) { 4692 void JSObject::ResetElements(Handle<JSObject> object) {
4702 CALL_HEAP_FUNCTION_VOID( 4693 if (object->map()->is_observed()) {
4703 object->GetIsolate(), 4694 // Maintain invariant that observed elements are always in dictionary mode.
4704 object->ResetElements()); 4695 Factory* factory = object->GetIsolate()->factory();
4696 Handle<SeededNumberDictionary> dictionary =
4697 factory->NewSeededNumberDictionary(0);
4698 if (object->map() == *factory->sloppy_arguments_elements_map()) {
4699 FixedArray::cast(object->elements())->set(1, *dictionary);
4700 } else {
4701 object->set_elements(*dictionary);
4702 }
4703 return;
4704 }
4705
4706 ElementsKind elements_kind = GetInitialFastElementsKind();
4707 if (!FLAG_smi_only_arrays) {
4708 elements_kind = FastSmiToObjectElementsKind(elements_kind);
4709 }
4710 Handle<Map> map = JSObject::GetElementsTransitionMap(object, elements_kind);
4711 object->set_map(*map);
Toon Verwaest 2014/04/08 12:58:55 JSObject::SetMapAndElements
mvstanton 2014/04/09 09:43:20 But initialize_elements() contains detailed logic
4712 object->initialize_elements();
4705 } 4713 }
4706 4714
4707 4715
4708 static Handle<SeededNumberDictionary> CopyFastElementsToDictionary( 4716 static Handle<SeededNumberDictionary> CopyFastElementsToDictionary(
4709 Handle<FixedArrayBase> array, 4717 Handle<FixedArrayBase> array,
4710 int length, 4718 int length,
4711 Handle<SeededNumberDictionary> dictionary) { 4719 Handle<SeededNumberDictionary> dictionary) {
4712 Isolate* isolate = array->GetIsolate(); 4720 Isolate* isolate = array->GetIsolate();
4713 Factory* factory = isolate->factory(); 4721 Factory* factory = isolate->factory();
4714 bool has_double_elements = array->IsFixedDoubleArray(); 4722 bool has_double_elements = array->IsFixedDoubleArray();
(...skipping 1707 matching lines...) Expand 10 before | Expand all | Expand 10 after
6422 JSObject::MigrateToMap(self, transitioned_map); 6430 JSObject::MigrateToMap(self, transitioned_map);
6423 return true; 6431 return true;
6424 } 6432 }
6425 6433
6426 // If either not the same accessor, or not the same attributes, fall back to 6434 // If either not the same accessor, or not the same attributes, fall back to
6427 // the slow case. 6435 // the slow case.
6428 return false; 6436 return false;
6429 } 6437 }
6430 6438
6431 6439
6432 static MaybeObject* CopyInsertDescriptor(Map* map,
6433 Name* name,
6434 AccessorPair* accessors,
6435 PropertyAttributes attributes) {
6436 CallbacksDescriptor new_accessors_desc(name, accessors, attributes);
6437 return map->CopyInsertDescriptor(&new_accessors_desc, INSERT_TRANSITION);
6438 }
6439
6440
6441 static Handle<Map> CopyInsertDescriptor(Handle<Map> map, 6440 static Handle<Map> CopyInsertDescriptor(Handle<Map> map,
6442 Handle<Name> name, 6441 Handle<Name> name,
6443 Handle<AccessorPair> accessors, 6442 Handle<AccessorPair> accessors,
6444 PropertyAttributes attributes) { 6443 PropertyAttributes attributes) {
6445 CALL_HEAP_FUNCTION(map->GetIsolate(), 6444 CallbacksDescriptor new_accessors_desc(name, accessors, attributes);
6446 CopyInsertDescriptor(*map, *name, *accessors, attributes), 6445 return Map::CopyInsertDescriptor(map, &new_accessors_desc, INSERT_TRANSITION);
6447 Map);
6448 } 6446 }
6449 6447
6450 6448
6451 bool JSObject::DefineFastAccessor(Handle<JSObject> object, 6449 bool JSObject::DefineFastAccessor(Handle<JSObject> object,
6452 Handle<Name> name, 6450 Handle<Name> name,
6453 AccessorComponent component, 6451 AccessorComponent component,
6454 Handle<Object> accessor, 6452 Handle<Object> accessor,
6455 PropertyAttributes attributes) { 6453 PropertyAttributes attributes) {
6456 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); 6454 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined());
6457 Isolate* isolate = object->GetIsolate(); 6455 Isolate* isolate = object->GetIsolate();
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
6764 result->set_unused_property_fields(unused_property_fields()); 6762 result->set_unused_property_fields(unused_property_fields());
6765 6763
6766 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); 6764 result->set_pre_allocated_property_fields(pre_allocated_property_fields());
6767 result->set_is_shared(false); 6765 result->set_is_shared(false);
6768 result->ClearCodeCache(GetHeap()); 6766 result->ClearCodeCache(GetHeap());
6769 NotifyLeafMapLayoutChange(); 6767 NotifyLeafMapLayoutChange();
6770 return result; 6768 return result;
6771 } 6769 }
6772 6770
6773 6771
6774 MaybeObject* Map::ShareDescriptor(DescriptorArray* descriptors, 6772 Handle<Map> Map::ShareDescriptor(Handle<Map> map,
6775 Descriptor* descriptor) { 6773 Handle<DescriptorArray> descriptors,
6774 Descriptor* descriptor) {
6776 // Sanity check. This path is only to be taken if the map owns its descriptor 6775 // Sanity check. This path is only to be taken if the map owns its descriptor
6777 // array, implying that its NumberOfOwnDescriptors equals the number of 6776 // array, implying that its NumberOfOwnDescriptors equals the number of
6778 // descriptors in the descriptor array. 6777 // descriptors in the descriptor array.
6779 ASSERT(NumberOfOwnDescriptors() == 6778 ASSERT(map->NumberOfOwnDescriptors() ==
6780 instance_descriptors()->number_of_descriptors()); 6779 map->instance_descriptors()->number_of_descriptors());
6781 Map* result; 6780 Handle<Map> result = Map::CopyDropDescriptors(map);
6782 MaybeObject* maybe_result = CopyDropDescriptors();
6783 if (!maybe_result->To(&result)) return maybe_result;
6784 6781
6785 Name* name = descriptor->GetKey(); 6782 Handle<Name> name = descriptor->GetKey();
6786 6783
6787 TransitionArray* transitions; 6784 Handle<TransitionArray> transitions =
6788 MaybeObject* maybe_transitions = 6785 Map::AddTransition(map, name, result, SIMPLE_TRANSITION);
6789 AddTransition(name, result, SIMPLE_TRANSITION);
6790 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
6791 6786
6792 int old_size = descriptors->number_of_descriptors(); 6787 int old_size = descriptors->number_of_descriptors();
6793 6788
6794 DescriptorArray* new_descriptors; 6789 Handle<DescriptorArray> new_descriptors;
6795 6790
6796 if (descriptors->NumberOfSlackDescriptors() > 0) { 6791 if (descriptors->NumberOfSlackDescriptors() > 0) {
6797 new_descriptors = descriptors; 6792 new_descriptors = descriptors;
6798 new_descriptors->Append(descriptor); 6793 new_descriptors->Append(descriptor);
Toon Verwaest 2014/04/08 12:58:55 We cannot GC anymore after this has happened. Othe
mvstanton 2014/04/09 09:43:20 Okay, I re-ordered things for the desired effect.
6799 } else { 6794 } else {
6800 // Descriptor arrays grow by 50%. 6795 // Descriptor arrays grow by 50%.
6801 MaybeObject* maybe_descriptors = DescriptorArray::Allocate( 6796 new_descriptors = map->GetIsolate()->factory()->NewDescriptorArray(
6802 GetIsolate(), old_size, old_size < 4 ? 1 : old_size / 2); 6797 old_size, old_size < 4 ? 1 : old_size / 2);
6803 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
6804 6798
6805 DescriptorArray::WhitenessWitness witness(new_descriptors); 6799 DescriptorArray::WhitenessWitness witness(*new_descriptors);
6806 6800
6807 // Copy the descriptors, inserting a descriptor. 6801 // Copy the descriptors, inserting a descriptor.
6808 for (int i = 0; i < old_size; ++i) { 6802 for (int i = 0; i < old_size; ++i) {
6809 new_descriptors->CopyFrom(i, descriptors, i, witness); 6803 new_descriptors->CopyFrom(i, *descriptors, i, witness);
6810 } 6804 }
6811 6805
6812 new_descriptors->Append(descriptor, witness); 6806 new_descriptors->Append(descriptor, witness);
6813 6807
6814 if (old_size > 0) { 6808 if (old_size > 0) {
6815 // If the source descriptors had an enum cache we copy it. This ensures 6809 // If the source descriptors had an enum cache we copy it. This ensures
6816 // that the maps to which we push the new descriptor array back can rely 6810 // that the maps to which we push the new descriptor array back can rely
6817 // on a cache always being available once it is set. If the map has more 6811 // on a cache always being available once it is set. If the map has more
6818 // enumerated descriptors than available in the original cache, the cache 6812 // enumerated descriptors than available in the original cache, the cache
6819 // will be lazily replaced by the extended cache when needed. 6813 // will be lazily replaced by the extended cache when needed.
6820 if (descriptors->HasEnumCache()) { 6814 if (descriptors->HasEnumCache()) {
6821 new_descriptors->CopyEnumCacheFrom(descriptors); 6815 new_descriptors->CopyEnumCacheFrom(*descriptors);
6822 } 6816 }
6823 6817
6824 Map* map; 6818 Map* walk_map;
Toon Verwaest 2014/04/08 12:58:55 DisallowHeapAllocation no_gc from here down.
mvstanton 2014/04/09 09:43:20 I've got it above now, I think that is fine?
6825 // Replace descriptors by new_descriptors in all maps that share it. 6819 // Replace descriptors by new_descriptors in all maps that share it.
6826 6820
6827 GetHeap()->incremental_marking()->RecordWrites(descriptors); 6821 map->GetHeap()->incremental_marking()->RecordWrites(*descriptors);
6828 for (Object* current = GetBackPointer(); 6822 for (Object* current = map->GetBackPointer();
6829 !current->IsUndefined(); 6823 !current->IsUndefined();
6830 current = map->GetBackPointer()) { 6824 current = walk_map->GetBackPointer()) {
6831 map = Map::cast(current); 6825 walk_map = Map::cast(current);
6832 if (map->instance_descriptors() != descriptors) break; 6826 if (walk_map->instance_descriptors() != *descriptors) break;
6833 map->set_instance_descriptors(new_descriptors); 6827 walk_map->set_instance_descriptors(*new_descriptors);
6834 } 6828 }
6835 6829
6836 set_instance_descriptors(new_descriptors); 6830 map->set_instance_descriptors(*new_descriptors);
6837 } 6831 }
6838 } 6832 }
6839 6833
6840 result->SetBackPointer(this); 6834 result->SetBackPointer(*map);
6841 result->InitializeDescriptors(new_descriptors); 6835 result->InitializeDescriptors(*new_descriptors);
6842 ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1); 6836 ASSERT(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1);
6843 6837
6844 set_transitions(transitions); 6838 map->set_transitions(*transitions);
6845 set_owns_descriptors(false); 6839 map->set_owns_descriptors(false);
6846 6840
6847 return result; 6841 return result;
6848 } 6842 }
6849 6843
6850 6844
6851 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, 6845 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map,
6852 Handle<DescriptorArray> descriptors, 6846 Handle<DescriptorArray> descriptors,
6853 TransitionFlag flag, 6847 TransitionFlag flag,
6854 Handle<Name> name) { 6848 Handle<Name> name) {
6855 CALL_HEAP_FUNCTION(map->GetIsolate(), 6849 CALL_HEAP_FUNCTION(map->GetIsolate(),
6856 map->CopyReplaceDescriptors(*descriptors, flag, *name), 6850 map->CopyReplaceDescriptorsFull(*descriptors, flag, *name),
6857 Map); 6851 Map);
6858 } 6852 }
6859 6853
6860 6854
6861 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, 6855 // TODO(mvstanton): Get rid of this method.
6856 MaybeObject* Map::CopyReplaceDescriptorsFull(DescriptorArray* descriptors,
Toon Verwaest 2014/04/08 12:58:55 This name doesn't really make sense.
mvstanton 2014/04/09 09:43:20 Already gone.
6862 TransitionFlag flag, 6857 TransitionFlag flag,
6863 Name* name, 6858 Name* name,
6864 SimpleTransitionFlag simple_flag) { 6859 SimpleTransitionFlag simple_flag) {
6865 ASSERT(descriptors->IsSortedNoDuplicates()); 6860 ASSERT(descriptors->IsSortedNoDuplicates());
6866 6861
6867 Map* result; 6862 Map* result;
6868 MaybeObject* maybe_result = CopyDropDescriptors(); 6863 MaybeObject* maybe_result = CopyDropDescriptors();
6869 if (!maybe_result->To(&result)) return maybe_result; 6864 if (!maybe_result->To(&result)) return maybe_result;
6870 6865
6871 result->InitializeDescriptors(descriptors); 6866 result->InitializeDescriptors(descriptors);
6872 6867
6873 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) { 6868 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) {
6874 TransitionArray* transitions; 6869 TransitionArray* transitions;
6875 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag); 6870 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag);
6876 if (!maybe_transitions->To(&transitions)) return maybe_transitions; 6871 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
6877 set_transitions(transitions); 6872 set_transitions(transitions);
6878 result->SetBackPointer(this); 6873 result->SetBackPointer(this);
6879 } else { 6874 } else {
6880 descriptors->InitializeRepresentations(Representation::Tagged()); 6875 descriptors->InitializeRepresentations(Representation::Tagged());
6881 } 6876 }
6882 6877
6883 return result; 6878 return result;
6884 } 6879 }
6885 6880
6886 6881
6882 Handle<Map> Map::CopyReplaceDescriptorsFull(Handle<Map> map,
Toon Verwaest 2014/04/08 12:58:55 Can we get rid of this version of the method? Kind
mvstanton 2014/04/09 09:43:20 Already gone.
6883 Handle<DescriptorArray> descriptors,
6884 TransitionFlag flag,
6885 SimpleTransitionFlag simple_flag) {
6886 return Map::CopyReplaceDescriptorsFull(map, descriptors, flag,
6887 Handle<Name>::null(), simple_flag);
6888 }
6889
6890
6891 Handle<Map> Map::CopyReplaceDescriptorsFull(Handle<Map> map,
6892 Handle<DescriptorArray> descriptors,
6893 TransitionFlag flag,
6894 Handle<Name> name,
6895 SimpleTransitionFlag simple_flag) {
6896 ASSERT(descriptors->IsSortedNoDuplicates());
6897
6898 Handle<Map> result = CopyDropDescriptors(map);
6899 result->InitializeDescriptors(*descriptors);
6900
6901 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) {
6902 Handle<TransitionArray> transitions = Map::AddTransition(
6903 map, name, result, simple_flag);
6904 map->set_transitions(*transitions);
6905 result->SetBackPointer(*map);
6906 } else {
6907 descriptors->InitializeRepresentations(Representation::Tagged());
6908 }
6909
6910 return result;
6911 }
6912
6913
6887 // Since this method is used to rewrite an existing transition tree, it can 6914 // Since this method is used to rewrite an existing transition tree, it can
6888 // always insert transitions without checking. 6915 // always insert transitions without checking.
6889 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, 6916 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
6890 int new_descriptor, 6917 int new_descriptor,
6891 Handle<DescriptorArray> descriptors) { 6918 Handle<DescriptorArray> descriptors) {
6892 ASSERT(descriptors->IsSortedNoDuplicates()); 6919 ASSERT(descriptors->IsSortedNoDuplicates());
6893 6920
6894 Handle<Map> result = Map::CopyDropDescriptors(map); 6921 Handle<Map> result = Map::CopyDropDescriptors(map);
6895 6922
6896 result->InitializeDescriptors(*descriptors); 6923 result->InitializeDescriptors(*descriptors);
(...skipping 14 matching lines...) Expand all
6911 Handle<TransitionArray> transitions = Map::AddTransition(map, name, result, 6938 Handle<TransitionArray> transitions = Map::AddTransition(map, name, result,
6912 SIMPLE_TRANSITION); 6939 SIMPLE_TRANSITION);
6913 6940
6914 map->set_transitions(*transitions); 6941 map->set_transitions(*transitions);
6915 result->SetBackPointer(*map); 6942 result->SetBackPointer(*map);
6916 6943
6917 return result; 6944 return result;
6918 } 6945 }
6919 6946
6920 6947
6921 MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) { 6948 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind,
6949 TransitionFlag flag) {
6922 if (flag == INSERT_TRANSITION) { 6950 if (flag == INSERT_TRANSITION) {
6923 ASSERT(!HasElementsTransition() || 6951 ASSERT(!map->HasElementsTransition() ||
6924 ((elements_transition_map()->elements_kind() == DICTIONARY_ELEMENTS || 6952 ((map->elements_transition_map()->elements_kind() ==
6953 DICTIONARY_ELEMENTS ||
6925 IsExternalArrayElementsKind( 6954 IsExternalArrayElementsKind(
6926 elements_transition_map()->elements_kind())) && 6955 map->elements_transition_map()->elements_kind())) &&
6927 (kind == DICTIONARY_ELEMENTS || 6956 (kind == DICTIONARY_ELEMENTS ||
6928 IsExternalArrayElementsKind(kind)))); 6957 IsExternalArrayElementsKind(kind))));
6929 ASSERT(!IsFastElementsKind(kind) || 6958 ASSERT(!IsFastElementsKind(kind) ||
6930 IsMoreGeneralElementsKindTransition(elements_kind(), kind)); 6959 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind));
6931 ASSERT(kind != elements_kind()); 6960 ASSERT(kind != map->elements_kind());
6932 } 6961 }
6933 6962
6934 bool insert_transition = 6963 bool insert_transition =
6935 flag == INSERT_TRANSITION && !HasElementsTransition(); 6964 flag == INSERT_TRANSITION && !map->HasElementsTransition();
6936 6965
6937 if (insert_transition && owns_descriptors()) { 6966 if (insert_transition && map->owns_descriptors()) {
6938 // In case the map owned its own descriptors, share the descriptors and 6967 // In case the map owned its own descriptors, share the descriptors and
6939 // transfer ownership to the new map. 6968 // transfer ownership to the new map.
6940 Map* new_map; 6969 Handle<Map> new_map = Map::CopyDropDescriptors(map);
6941 MaybeObject* maybe_new_map = CopyDropDescriptors();
6942 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
6943 6970
6944 MaybeObject* added_elements = set_elements_transition_map(new_map); 6971 SetElementsTransitionMap(map, new_map);
6945 if (added_elements->IsFailure()) return added_elements;
6946 6972
6947 new_map->set_elements_kind(kind); 6973 new_map->set_elements_kind(kind);
6948 new_map->InitializeDescriptors(instance_descriptors()); 6974 new_map->InitializeDescriptors(map->instance_descriptors());
6949 new_map->SetBackPointer(this); 6975 new_map->SetBackPointer(*map);
6950 set_owns_descriptors(false); 6976 map->set_owns_descriptors(false);
6951 return new_map; 6977 return new_map;
6952 } 6978 }
6953 6979
6954 // In case the map did not own its own descriptors, a split is forced by 6980 // In case the map did not own its own descriptors, a split is forced by
6955 // copying the map; creating a new descriptor array cell. 6981 // copying the map; creating a new descriptor array cell.
6956 // Create a new free-floating map only if we are not allowed to store it. 6982 // Create a new free-floating map only if we are not allowed to store it.
6957 Map* new_map; 6983 Handle<Map> new_map = Map::Copy(map);
6958 MaybeObject* maybe_new_map = Copy();
6959 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
6960 6984
6961 new_map->set_elements_kind(kind); 6985 new_map->set_elements_kind(kind);
6962 6986
6963 if (insert_transition) { 6987 if (insert_transition) {
6964 MaybeObject* added_elements = set_elements_transition_map(new_map); 6988 SetElementsTransitionMap(map, new_map);
6965 if (added_elements->IsFailure()) return added_elements; 6989 new_map->SetBackPointer(*map);
6966 new_map->SetBackPointer(this);
6967 } 6990 }
6968 6991
6969 return new_map; 6992 return new_map;
6970 } 6993 }
6971 6994
6972 6995
6973 Handle<Map> Map::CopyForObserved(Handle<Map> map) { 6996 Handle<Map> Map::CopyForObserved(Handle<Map> map) {
6974 ASSERT(!map->is_observed()); 6997 ASSERT(!map->is_observed());
6975 6998
6976 Isolate* isolate = map->GetIsolate(); 6999 Isolate* isolate = map->GetIsolate();
(...skipping 19 matching lines...) Expand all
6996 new_map->InitializeDescriptors(map->instance_descriptors()); 7019 new_map->InitializeDescriptors(map->instance_descriptors());
6997 map->set_owns_descriptors(false); 7020 map->set_owns_descriptors(false);
6998 } 7021 }
6999 7022
7000 new_map->SetBackPointer(*map); 7023 new_map->SetBackPointer(*map);
7001 return new_map; 7024 return new_map;
7002 } 7025 }
7003 7026
7004 7027
7005 Handle<Map> Map::Copy(Handle<Map> map) { 7028 Handle<Map> Map::Copy(Handle<Map> map) {
7006 CALL_HEAP_FUNCTION(map->GetIsolate(), map->Copy(), Map); 7029 Handle<DescriptorArray> descriptors = handle(map->instance_descriptors());
7030 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
7031 Handle<DescriptorArray> new_descriptors =
7032 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors);
7033 return Map::CopyReplaceDescriptorsFull(map, new_descriptors, OMIT_TRANSITION);
7007 } 7034 }
7008 7035
7009 7036
7010 MaybeObject* Map::Copy() {
7011 DescriptorArray* descriptors = instance_descriptors();
7012 DescriptorArray* new_descriptors;
7013 int number_of_own_descriptors = NumberOfOwnDescriptors();
7014 MaybeObject* maybe_descriptors =
7015 descriptors->CopyUpTo(number_of_own_descriptors);
7016 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
7017
7018 return CopyReplaceDescriptors(new_descriptors, OMIT_TRANSITION);
7019 }
7020
7021
7022 Handle<Map> Map::Create(Handle<JSFunction> constructor, 7037 Handle<Map> Map::Create(Handle<JSFunction> constructor,
7023 int extra_inobject_properties) { 7038 int extra_inobject_properties) {
7024 Handle<Map> copy = Copy(handle(constructor->initial_map())); 7039 Handle<Map> copy = Copy(handle(constructor->initial_map()));
7025 7040
7026 // Check that we do not overflow the instance size when adding the 7041 // Check that we do not overflow the instance size when adding the
7027 // extra inobject properties. 7042 // extra inobject properties.
7028 int instance_size_delta = extra_inobject_properties * kPointerSize; 7043 int instance_size_delta = extra_inobject_properties * kPointerSize;
7029 int max_instance_size_delta = 7044 int max_instance_size_delta =
7030 JSObject::kMaxInstanceSize - copy->instance_size(); 7045 JSObject::kMaxInstanceSize - copy->instance_size();
7031 int max_extra_properties = max_instance_size_delta >> kPointerSizeLog2; 7046 int max_extra_properties = max_instance_size_delta >> kPointerSizeLog2;
7032 7047
7033 // If the instance size overflows, we allocate as many properties as we can as 7048 // If the instance size overflows, we allocate as many properties as we can as
7034 // inobject properties. 7049 // inobject properties.
7035 if (extra_inobject_properties > max_extra_properties) { 7050 if (extra_inobject_properties > max_extra_properties) {
7036 instance_size_delta = max_instance_size_delta; 7051 instance_size_delta = max_instance_size_delta;
7037 extra_inobject_properties = max_extra_properties; 7052 extra_inobject_properties = max_extra_properties;
7038 } 7053 }
7039 7054
7040 // Adjust the map with the extra inobject properties. 7055 // Adjust the map with the extra inobject properties.
7041 int inobject_properties = 7056 int inobject_properties =
7042 copy->inobject_properties() + extra_inobject_properties; 7057 copy->inobject_properties() + extra_inobject_properties;
7043 copy->set_inobject_properties(inobject_properties); 7058 copy->set_inobject_properties(inobject_properties);
7044 copy->set_unused_property_fields(inobject_properties); 7059 copy->set_unused_property_fields(inobject_properties);
7045 copy->set_instance_size(copy->instance_size() + instance_size_delta); 7060 copy->set_instance_size(copy->instance_size() + instance_size_delta);
7046 copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy)); 7061 copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy));
7047 return copy; 7062 return copy;
7048 } 7063 }
7049 7064
7050 7065
7051 MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor, 7066 Handle<Map> Map::CopyAddDescriptor(Handle<Map> map,
7052 TransitionFlag flag) { 7067 Descriptor* descriptor,
7053 DescriptorArray* descriptors = instance_descriptors(); 7068 TransitionFlag flag) {
7069 Handle<DescriptorArray> descriptors = handle(map->instance_descriptors());
7054 7070
7055 // Ensure the key is unique. 7071 // Ensure the key is unique.
7056 MaybeObject* maybe_failure = descriptor->KeyToUniqueName(); 7072 descriptor->KeyToUniqueName();
7057 if (maybe_failure->IsFailure()) return maybe_failure;
7058 7073
7059 int old_size = NumberOfOwnDescriptors(); 7074 int old_size = map->NumberOfOwnDescriptors();
7060 int new_size = old_size + 1; 7075 int new_size = old_size + 1;
7061 7076
7062 if (flag == INSERT_TRANSITION && 7077 if (flag == INSERT_TRANSITION &&
7063 owns_descriptors() && 7078 map->owns_descriptors() &&
7064 CanHaveMoreTransitions()) { 7079 map->CanHaveMoreTransitions()) {
7065 return ShareDescriptor(descriptors, descriptor); 7080 return Map::ShareDescriptor(map, descriptors, descriptor);
7066 } 7081 }
7067 7082
7068 DescriptorArray* new_descriptors; 7083 Handle<DescriptorArray> new_descriptors =
7069 MaybeObject* maybe_descriptors = 7084 map->GetIsolate()->factory()->NewDescriptorArray(old_size, 1);
7070 DescriptorArray::Allocate(GetIsolate(), old_size, 1);
7071 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
7072 7085
7073 DescriptorArray::WhitenessWitness witness(new_descriptors); 7086 DescriptorArray::WhitenessWitness witness(*new_descriptors);
7074 7087
7075 // Copy the descriptors, inserting a descriptor. 7088 // Copy the descriptors, inserting a descriptor.
7076 for (int i = 0; i < old_size; ++i) { 7089 for (int i = 0; i < old_size; ++i) {
7077 new_descriptors->CopyFrom(i, descriptors, i, witness); 7090 new_descriptors->CopyFrom(i, *descriptors, i, witness);
7078 } 7091 }
7079 7092
7080 if (old_size != descriptors->number_of_descriptors()) { 7093 if (old_size != descriptors->number_of_descriptors()) {
7081 new_descriptors->SetNumberOfDescriptors(new_size); 7094 new_descriptors->SetNumberOfDescriptors(new_size);
7082 new_descriptors->Set(old_size, descriptor, witness); 7095 new_descriptors->Set(old_size, descriptor, witness);
7083 new_descriptors->Sort(); 7096 new_descriptors->Sort();
7084 } else { 7097 } else {
7085 new_descriptors->Append(descriptor, witness); 7098 new_descriptors->Append(descriptor, witness);
7086 } 7099 }
7087 7100
7088 Name* key = descriptor->GetKey(); 7101 Handle<Name> key = descriptor->GetKey();
7089 return CopyReplaceDescriptors(new_descriptors, flag, key, SIMPLE_TRANSITION); 7102 return Map::CopyReplaceDescriptorsFull(map, new_descriptors, flag,
7103 key, SIMPLE_TRANSITION);
7090 } 7104 }
7091 7105
7092 7106
7093 MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor, 7107 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map,
7094 TransitionFlag flag) { 7108 Descriptor* descriptor,
7095 DescriptorArray* old_descriptors = instance_descriptors(); 7109 TransitionFlag flag) {
7110 Handle<DescriptorArray> old_descriptors = handle(map->instance_descriptors());
7096 7111
7097 // Ensure the key is unique. 7112 // Ensure the key is unique.
7098 MaybeObject* maybe_result = descriptor->KeyToUniqueName(); 7113 descriptor->KeyToUniqueName();
7099 if (maybe_result->IsFailure()) return maybe_result;
7100 7114
7101 // We replace the key if it is already present. 7115 // We replace the key if it is already present.
7102 int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this); 7116 int index = old_descriptors->SearchWithCache(*descriptor->GetKey(), *map);
7103 if (index != DescriptorArray::kNotFound) { 7117 if (index != DescriptorArray::kNotFound) {
7104 return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag); 7118 return Map::CopyReplaceDescriptor(map, old_descriptors, descriptor,
7119 index, flag);
7105 } 7120 }
7106 return CopyAddDescriptor(descriptor, flag); 7121 return Map::CopyAddDescriptor(map, descriptor, flag);
7122 }
7123
7124
7125 Handle<DescriptorArray> DescriptorArray::CopyUpTo(
7126 Handle<DescriptorArray> desc,
7127 int enumeration_index) {
7128 return DescriptorArray::CopyUpToAddAttributes(desc,
7129 enumeration_index,
7130 NONE);
7107 } 7131 }
7108 7132
7109 7133
7110 Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes( 7134 Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes(
7111 Handle<DescriptorArray> desc, 7135 Handle<DescriptorArray> desc,
7112 int enumeration_index, 7136 int enumeration_index,
7113 PropertyAttributes attributes) { 7137 PropertyAttributes attributes) {
7114 CALL_HEAP_FUNCTION(desc->GetIsolate(), 7138 if (enumeration_index == 0) {
7115 desc->CopyUpToAddAttributes(enumeration_index, attributes), 7139 return desc->GetIsolate()->factory()->empty_descriptor_array();
7116 DescriptorArray); 7140 }
7117 }
7118
7119
7120 MaybeObject* DescriptorArray::CopyUpToAddAttributes(
7121 int enumeration_index, PropertyAttributes attributes) {
7122 if (enumeration_index == 0) return GetHeap()->empty_descriptor_array();
7123 7141
7124 int size = enumeration_index; 7142 int size = enumeration_index;
7125 7143
7126 DescriptorArray* descriptors; 7144 Handle<DescriptorArray> descriptors =
7127 MaybeObject* maybe_descriptors = Allocate(GetIsolate(), size); 7145 desc->GetIsolate()->factory()->NewDescriptorArray(size);
7128 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; 7146 DescriptorArray::WhitenessWitness witness(*descriptors);
7129 DescriptorArray::WhitenessWitness witness(descriptors);
7130 7147
7131 if (attributes != NONE) { 7148 if (attributes != NONE) {
7132 for (int i = 0; i < size; ++i) { 7149 for (int i = 0; i < size; ++i) {
7133 Object* value = GetValue(i); 7150 Object* value = desc->GetValue(i);
7134 PropertyDetails details = GetDetails(i); 7151 PropertyDetails details = desc->GetDetails(i);
7135 int mask = DONT_DELETE | DONT_ENUM; 7152 int mask = DONT_DELETE | DONT_ENUM;
7136 // READ_ONLY is an invalid attribute for JS setters/getters. 7153 // READ_ONLY is an invalid attribute for JS setters/getters.
7137 if (details.type() != CALLBACKS || !value->IsAccessorPair()) { 7154 if (details.type() != CALLBACKS || !value->IsAccessorPair()) {
7138 mask |= READ_ONLY; 7155 mask |= READ_ONLY;
7139 } 7156 }
7140 details = details.CopyAddAttributes( 7157 details = details.CopyAddAttributes(
7141 static_cast<PropertyAttributes>(attributes & mask)); 7158 static_cast<PropertyAttributes>(attributes & mask));
7142 Descriptor desc(GetKey(i), value, details); 7159 Descriptor inner_desc(handle(desc->GetKey(i)),
7143 descriptors->Set(i, &desc, witness); 7160 handle(value, desc->GetIsolate()),
7161 details);
7162 descriptors->Set(i, &inner_desc, witness);
7144 } 7163 }
7145 } else { 7164 } else {
7146 for (int i = 0; i < size; ++i) { 7165 for (int i = 0; i < size; ++i) {
7147 descriptors->CopyFrom(i, this, i, witness); 7166 descriptors->CopyFrom(i, *desc, i, witness);
7148 } 7167 }
7149 } 7168 }
7150 7169
7151 if (number_of_descriptors() != enumeration_index) descriptors->Sort(); 7170 if (desc->number_of_descriptors() != enumeration_index) descriptors->Sort();
7152 7171
7153 return descriptors; 7172 return descriptors;
7154 } 7173 }
7155 7174
7156 7175
7157 MaybeObject* Map::CopyReplaceDescriptor(DescriptorArray* descriptors, 7176 Handle<Map> Map::CopyReplaceDescriptor(Handle<Map> map,
7158 Descriptor* descriptor, 7177 Handle<DescriptorArray> descriptors,
7159 int insertion_index, 7178 Descriptor* descriptor,
7160 TransitionFlag flag) { 7179 int insertion_index,
7180 TransitionFlag flag) {
7161 // Ensure the key is unique. 7181 // Ensure the key is unique.
7162 MaybeObject* maybe_failure = descriptor->KeyToUniqueName(); 7182 descriptor->KeyToUniqueName();
7163 if (maybe_failure->IsFailure()) return maybe_failure;
7164 7183
7165 Name* key = descriptor->GetKey(); 7184 Handle<Name> key = descriptor->GetKey();
7166 ASSERT(key == descriptors->GetKey(insertion_index)); 7185 ASSERT(*key == descriptors->GetKey(insertion_index));
7167 7186
7168 int new_size = NumberOfOwnDescriptors(); 7187 int new_size = map->NumberOfOwnDescriptors();
7169 ASSERT(0 <= insertion_index && insertion_index < new_size); 7188 ASSERT(0 <= insertion_index && insertion_index < new_size);
7170 7189
7171 ASSERT_LT(insertion_index, new_size); 7190 ASSERT_LT(insertion_index, new_size);
7172 7191
7173 DescriptorArray* new_descriptors; 7192 Handle<DescriptorArray> new_descriptors =
7174 MaybeObject* maybe_descriptors = 7193 map->GetIsolate()->factory()->NewDescriptorArray(new_size);
7175 DescriptorArray::Allocate(GetIsolate(), new_size); 7194 DescriptorArray::WhitenessWitness witness(*new_descriptors);
7176 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
7177 DescriptorArray::WhitenessWitness witness(new_descriptors);
7178 7195
7179 for (int i = 0; i < new_size; ++i) { 7196 for (int i = 0; i < new_size; ++i) {
7180 if (i == insertion_index) { 7197 if (i == insertion_index) {
7181 new_descriptors->Set(i, descriptor, witness); 7198 new_descriptors->Set(i, descriptor, witness);
Toon Verwaest 2014/04/08 12:58:55 In this Set case, the "pointer" will be wrong. Ca
mvstanton 2014/04/09 09:43:20 I followed your suggestion to just add descriptor
7182 } else { 7199 } else {
7183 new_descriptors->CopyFrom(i, descriptors, i, witness); 7200 new_descriptors->CopyFrom(i, *descriptors, i, witness);
7184 } 7201 }
7185 } 7202 }
7186 7203
7187 // Re-sort if descriptors were removed. 7204 // Re-sort if descriptors were removed.
7188 if (new_size != descriptors->length()) new_descriptors->Sort(); 7205 if (new_size != descriptors->length()) new_descriptors->Sort();
7189 7206
7190 SimpleTransitionFlag simple_flag = 7207 SimpleTransitionFlag simple_flag =
7191 (insertion_index == descriptors->number_of_descriptors() - 1) 7208 (insertion_index == descriptors->number_of_descriptors() - 1)
7192 ? SIMPLE_TRANSITION 7209 ? SIMPLE_TRANSITION
7193 : FULL_TRANSITION; 7210 : FULL_TRANSITION;
7194 return CopyReplaceDescriptors(new_descriptors, flag, key, simple_flag); 7211 return Map::CopyReplaceDescriptorsFull(map, new_descriptors, flag, key,
7212 simple_flag);
7195 } 7213 }
7196 7214
7197 7215
7198 void Map::UpdateCodeCache(Handle<Map> map, 7216 void Map::UpdateCodeCache(Handle<Map> map,
7199 Handle<Name> name, 7217 Handle<Name> name,
7200 Handle<Code> code) { 7218 Handle<Code> code) {
7201 Isolate* isolate = map->GetIsolate(); 7219 Isolate* isolate = map->GetIsolate();
7202 CALL_HEAP_FUNCTION_VOID(isolate, 7220 CALL_HEAP_FUNCTION_VOID(isolate,
7203 map->UpdateCodeCache(*name, *code)); 7221 map->UpdateCodeCache(*name, *code));
7204 } 7222 }
(...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after
8028 set(kEnumCacheIndex, bridge_storage); 8046 set(kEnumCacheIndex, bridge_storage);
8029 } 8047 }
8030 8048
8031 8049
8032 void DescriptorArray::CopyFrom(int dst_index, 8050 void DescriptorArray::CopyFrom(int dst_index,
8033 DescriptorArray* src, 8051 DescriptorArray* src,
8034 int src_index, 8052 int src_index,
8035 const WhitenessWitness& witness) { 8053 const WhitenessWitness& witness) {
8036 Object* value = src->GetValue(src_index); 8054 Object* value = src->GetValue(src_index);
8037 PropertyDetails details = src->GetDetails(src_index); 8055 PropertyDetails details = src->GetDetails(src_index);
8038 Descriptor desc(src->GetKey(src_index), value, details); 8056 Descriptor desc(handle(src->GetKey(src_index)),
8057 handle(value, src->GetIsolate()),
8058 details);
8039 Set(dst_index, &desc, witness); 8059 Set(dst_index, &desc, witness);
8040 } 8060 }
8041 8061
8042 8062
8043 // Creates a new descriptor array by merging the descriptor array of |right_map| 8063 // Creates a new descriptor array by merging the descriptor array of |right_map|
8044 // into the (at least partly) updated descriptor array of |left_map|. 8064 // into the (at least partly) updated descriptor array of |left_map|.
8045 // The method merges two descriptor array in three parts. Both descriptor arrays 8065 // The method merges two descriptor array in three parts. Both descriptor arrays
8046 // are identical up to |verbatim|. They also overlap in keys up to |valid|. 8066 // are identical up to |verbatim|. They also overlap in keys up to |valid|.
8047 // Between |verbatim| and |valid|, the resulting descriptor type as well as the 8067 // Between |verbatim| and |valid|, the resulting descriptor type as well as the
8048 // representation are generalized from both |left_map| and |right_map|. Beyond 8068 // representation are generalized from both |left_map| and |right_map|. Beyond
(...skipping 22 matching lines...) Expand all
8071 result->NumberOfSlackDescriptors() > 0 || 8091 result->NumberOfSlackDescriptors() > 0 ||
8072 result->number_of_descriptors() == right->number_of_descriptors()); 8092 result->number_of_descriptors() == right->number_of_descriptors());
8073 ASSERT(result->number_of_descriptors() == new_size); 8093 ASSERT(result->number_of_descriptors() == new_size);
8074 8094
8075 int descriptor; 8095 int descriptor;
8076 8096
8077 // 0 -> |verbatim| 8097 // 0 -> |verbatim|
8078 int current_offset = 0; 8098 int current_offset = 0;
8079 for (descriptor = 0; descriptor < verbatim; descriptor++) { 8099 for (descriptor = 0; descriptor < verbatim; descriptor++) {
8080 if (left->GetDetails(descriptor).type() == FIELD) current_offset++; 8100 if (left->GetDetails(descriptor).type() == FIELD) current_offset++;
8081 Descriptor d(right->GetKey(descriptor), 8101 Descriptor d(handle(right->GetKey(descriptor)),
8082 right->GetValue(descriptor), 8102 handle(right->GetValue(descriptor), right->GetIsolate()),
8083 right->GetDetails(descriptor)); 8103 right->GetDetails(descriptor));
8084 result->Set(descriptor, &d); 8104 result->Set(descriptor, &d);
8085 } 8105 }
8086 8106
8087 // |verbatim| -> |valid| 8107 // |verbatim| -> |valid|
8088 for (; descriptor < valid; descriptor++) { 8108 for (; descriptor < valid; descriptor++) {
8089 PropertyDetails left_details = left->GetDetails(descriptor); 8109 PropertyDetails left_details = left->GetDetails(descriptor);
8090 PropertyDetails right_details = right->GetDetails(descriptor); 8110 PropertyDetails right_details = right->GetDetails(descriptor);
8091 if (left_details.type() == FIELD || right_details.type() == FIELD || 8111 if (left_details.type() == FIELD || right_details.type() == FIELD ||
8092 (store_mode == FORCE_FIELD && descriptor == modify_index) || 8112 (store_mode == FORCE_FIELD && descriptor == modify_index) ||
8093 (left_details.type() == CONSTANT && 8113 (left_details.type() == CONSTANT &&
8094 right_details.type() == CONSTANT && 8114 right_details.type() == CONSTANT &&
8095 left->GetValue(descriptor) != right->GetValue(descriptor))) { 8115 left->GetValue(descriptor) != right->GetValue(descriptor))) {
8096 Representation representation = left_details.representation().generalize( 8116 Representation representation = left_details.representation().generalize(
8097 right_details.representation()); 8117 right_details.representation());
8098 FieldDescriptor d(left->GetKey(descriptor), 8118 FieldDescriptor d(handle(left->GetKey(descriptor)),
8099 current_offset++, 8119 current_offset++,
8100 right_details.attributes(), 8120 right_details.attributes(),
8101 representation); 8121 representation);
8102 result->Set(descriptor, &d); 8122 result->Set(descriptor, &d);
8103 } else { 8123 } else {
8104 Descriptor d(right->GetKey(descriptor), 8124 Descriptor d(handle(right->GetKey(descriptor)),
8105 right->GetValue(descriptor), 8125 handle(right->GetValue(descriptor), right->GetIsolate()),
8106 right_details); 8126 right_details);
8107 result->Set(descriptor, &d); 8127 result->Set(descriptor, &d);
8108 } 8128 }
8109 } 8129 }
8110 8130
8111 // |valid| -> |new_size| 8131 // |valid| -> |new_size|
8112 for (; descriptor < new_size; descriptor++) { 8132 for (; descriptor < new_size; descriptor++) {
8113 PropertyDetails right_details = right->GetDetails(descriptor); 8133 PropertyDetails right_details = right->GetDetails(descriptor);
8114 if (right_details.type() == FIELD || 8134 if (right_details.type() == FIELD ||
8115 (store_mode == FORCE_FIELD && descriptor == modify_index)) { 8135 (store_mode == FORCE_FIELD && descriptor == modify_index)) {
8116 FieldDescriptor d(right->GetKey(descriptor), 8136 FieldDescriptor d(handle(right->GetKey(descriptor)),
8117 current_offset++, 8137 current_offset++,
8118 right_details.attributes(), 8138 right_details.attributes(),
8119 right_details.representation()); 8139 right_details.representation());
8120 result->Set(descriptor, &d); 8140 result->Set(descriptor, &d);
8121 } else { 8141 } else {
8122 Descriptor d(right->GetKey(descriptor), 8142 Descriptor d(handle(right->GetKey(descriptor)),
8123 right->GetValue(descriptor), 8143 handle(right->GetValue(descriptor), right->GetIsolate()),
8124 right_details); 8144 right_details);
8125 result->Set(descriptor, &d); 8145 result->Set(descriptor, &d);
8126 } 8146 }
8127 } 8147 }
8128 8148
8129 result->Sort(); 8149 result->Sort();
8130 return result; 8150 return result;
8131 } 8151 }
8132 8152
8133 8153
(...skipping 1583 matching lines...) Expand 10 before | Expand all | Expand 10 after
9717 if (object->IsGlobalObject()) return; 9737 if (object->IsGlobalObject()) return;
9718 9738
9719 // Make sure prototypes are fast objects and their maps have the bit set 9739 // Make sure prototypes are fast objects and their maps have the bit set
9720 // so they remain fast. 9740 // so they remain fast.
9721 if (!object->HasFastProperties()) { 9741 if (!object->HasFastProperties()) {
9722 TransformToFastProperties(object, 0); 9742 TransformToFastProperties(object, 0);
9723 } 9743 }
9724 } 9744 }
9725 9745
9726 9746
9727 static MUST_USE_RESULT MaybeObject* CacheInitialJSArrayMaps( 9747 Handle<Object> CacheInitialJSArrayMaps(
9728 Context* native_context, Map* initial_map) { 9748 Handle<Context> native_context, Handle<Map> initial_map) {
9729 // Replace all of the cached initial array maps in the native context with 9749 // Replace all of the cached initial array maps in the native context with
9730 // the appropriate transitioned elements kind maps. 9750 // the appropriate transitioned elements kind maps.
9731 Heap* heap = native_context->GetHeap(); 9751 Factory* factory = native_context->GetIsolate()->factory();
9732 MaybeObject* maybe_maps = 9752 Handle<FixedArray> maps = factory->NewFixedArrayWithHoles(
9733 heap->AllocateFixedArrayWithHoles(kElementsKindCount, TENURED); 9753 kElementsKindCount, TENURED);
9734 FixedArray* maps;
9735 if (!maybe_maps->To(&maps)) return maybe_maps;
9736 9754
9737 Map* current_map = initial_map; 9755 Handle<Map> current_map = initial_map;
9738 ElementsKind kind = current_map->elements_kind(); 9756 ElementsKind kind = current_map->elements_kind();
9739 ASSERT(kind == GetInitialFastElementsKind()); 9757 ASSERT(kind == GetInitialFastElementsKind());
9740 maps->set(kind, current_map); 9758 maps->set(kind, *current_map);
9741 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1; 9759 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
9742 i < kFastElementsKindCount; ++i) { 9760 i < kFastElementsKindCount; ++i) {
9743 Map* new_map; 9761 Handle<Map> new_map;
9744 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i); 9762 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
9745 if (current_map->HasElementsTransition()) { 9763 if (current_map->HasElementsTransition()) {
9746 new_map = current_map->elements_transition_map(); 9764 new_map = handle(current_map->elements_transition_map());
9747 ASSERT(new_map->elements_kind() == next_kind); 9765 ASSERT(new_map->elements_kind() == next_kind);
9748 } else { 9766 } else {
9749 MaybeObject* maybe_new_map = 9767 new_map = Map::CopyAsElementsKind(current_map, next_kind,
9750 current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION); 9768 INSERT_TRANSITION);
9751 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
9752 } 9769 }
9753 maps->set(next_kind, new_map); 9770 maps->set(next_kind, *new_map);
9754 current_map = new_map; 9771 current_map = new_map;
9755 } 9772 }
9756 native_context->set_js_array_maps(maps); 9773 native_context->set_js_array_maps(*maps);
9757 return initial_map; 9774 return initial_map;
9758 } 9775 }
9759 9776
9760 9777
9761 Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
9762 Handle<Map> initial_map) {
9763 CALL_HEAP_FUNCTION(native_context->GetIsolate(),
9764 CacheInitialJSArrayMaps(*native_context, *initial_map),
9765 Object);
9766 }
9767
9768
9769 void JSFunction::SetInstancePrototype(Handle<JSFunction> function, 9778 void JSFunction::SetInstancePrototype(Handle<JSFunction> function,
9770 Handle<Object> value) { 9779 Handle<Object> value) {
9771 ASSERT(value->IsJSReceiver()); 9780 ASSERT(value->IsJSReceiver());
9772 9781
9773 // First some logic for the map of the prototype to make sure it is in fast 9782 // First some logic for the map of the prototype to make sure it is in fast
9774 // mode. 9783 // mode.
9775 if (value->IsJSObject()) { 9784 if (value->IsJSObject()) {
9776 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); 9785 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
9777 } 9786 }
9778 9787
(...skipping 5876 matching lines...) Expand 10 before | Expand all | Expand 10 after
15655 // instance descriptor. 15664 // instance descriptor.
15656 MaybeObject* maybe_key = heap->InternalizeString(String::cast(k)); 15665 MaybeObject* maybe_key = heap->InternalizeString(String::cast(k));
15657 if (!maybe_key->To(&key)) return maybe_key; 15666 if (!maybe_key->To(&key)) return maybe_key;
15658 } 15667 }
15659 15668
15660 PropertyDetails details = DetailsAt(i); 15669 PropertyDetails details = DetailsAt(i);
15661 int enumeration_index = details.dictionary_index(); 15670 int enumeration_index = details.dictionary_index();
15662 PropertyType type = details.type(); 15671 PropertyType type = details.type();
15663 15672
15664 if (value->IsJSFunction()) { 15673 if (value->IsJSFunction()) {
15665 ConstantDescriptor d(key, value, details.attributes()); 15674 ConstantDescriptor d(handle(key),
15675 handle(value, GetIsolate()),
15676 details.attributes());
15666 descriptors->Set(enumeration_index - 1, &d, witness); 15677 descriptors->Set(enumeration_index - 1, &d, witness);
15667 } else if (type == NORMAL) { 15678 } else if (type == NORMAL) {
15668 if (current_offset < inobject_props) { 15679 if (current_offset < inobject_props) {
15669 obj->InObjectPropertyAtPut(current_offset, 15680 obj->InObjectPropertyAtPut(current_offset,
15670 value, 15681 value,
15671 UPDATE_WRITE_BARRIER); 15682 UPDATE_WRITE_BARRIER);
15672 } else { 15683 } else {
15673 int offset = current_offset - inobject_props; 15684 int offset = current_offset - inobject_props;
15674 fields->set(offset, value); 15685 fields->set(offset, value);
15675 } 15686 }
15676 FieldDescriptor d(key, 15687 FieldDescriptor d(handle(key),
15677 current_offset++, 15688 current_offset++,
15678 details.attributes(), 15689 details.attributes(),
15679 // TODO(verwaest): value->OptimalRepresentation(); 15690 // TODO(verwaest): value->OptimalRepresentation();
15680 Representation::Tagged()); 15691 Representation::Tagged());
15681 descriptors->Set(enumeration_index - 1, &d, witness); 15692 descriptors->Set(enumeration_index - 1, &d, witness);
15682 } else if (type == CALLBACKS) { 15693 } else if (type == CALLBACKS) {
15683 CallbacksDescriptor d(key, 15694 CallbacksDescriptor d(handle(key),
15684 value, 15695 handle(value, GetIsolate()),
15685 details.attributes()); 15696 details.attributes());
15686 descriptors->Set(enumeration_index - 1, &d, witness); 15697 descriptors->Set(enumeration_index - 1, &d, witness);
15687 } else { 15698 } else {
15688 UNREACHABLE(); 15699 UNREACHABLE();
15689 } 15700 }
15690 } 15701 }
15691 } 15702 }
15692 ASSERT(current_offset == number_of_fields); 15703 ASSERT(current_offset == number_of_fields);
15693 15704
15694 descriptors->Sort(); 15705 descriptors->Sort();
(...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after
16677 #define ERROR_MESSAGES_TEXTS(C, T) T, 16688 #define ERROR_MESSAGES_TEXTS(C, T) T,
16678 static const char* error_messages_[] = { 16689 static const char* error_messages_[] = {
16679 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16690 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16680 }; 16691 };
16681 #undef ERROR_MESSAGES_TEXTS 16692 #undef ERROR_MESSAGES_TEXTS
16682 return error_messages_[reason]; 16693 return error_messages_[reason];
16683 } 16694 }
16684 16695
16685 16696
16686 } } // namespace v8::internal 16697 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | src/transitions.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698