OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 4174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4185 AllocationSite* allocation_site) { | 4185 AllocationSite* allocation_site) { |
4186 memento->set_map_no_write_barrier(allocation_memento_map()); | 4186 memento->set_map_no_write_barrier(allocation_memento_map()); |
4187 ASSERT(allocation_site->map() == allocation_site_map()); | 4187 ASSERT(allocation_site->map() == allocation_site_map()); |
4188 memento->set_allocation_site(allocation_site, SKIP_WRITE_BARRIER); | 4188 memento->set_allocation_site(allocation_site, SKIP_WRITE_BARRIER); |
4189 if (FLAG_allocation_site_pretenuring) { | 4189 if (FLAG_allocation_site_pretenuring) { |
4190 allocation_site->IncrementMementoCreateCount(); | 4190 allocation_site->IncrementMementoCreateCount(); |
4191 } | 4191 } |
4192 } | 4192 } |
4193 | 4193 |
4194 | 4194 |
4195 MaybeObject* Heap::AllocateWithAllocationSite(Map* map, AllocationSpace space, | 4195 MaybeObject* Heap::Allocate(Map* map, AllocationSpace space, |
4196 Handle<AllocationSite> allocation_site) { | 4196 AllocationSite* allocation_site) { |
4197 ASSERT(gc_state_ == NOT_IN_GC); | 4197 ASSERT(gc_state_ == NOT_IN_GC); |
4198 ASSERT(map->instance_type() != MAP_TYPE); | 4198 ASSERT(map->instance_type() != MAP_TYPE); |
4199 // If allocation failures are disallowed, we may allocate in a different | 4199 // If allocation failures are disallowed, we may allocate in a different |
4200 // space when new space is full and the object is not a large object. | |
4201 AllocationSpace retry_space = | |
4202 (space != NEW_SPACE) ? space : TargetSpaceId(map->instance_type()); | |
4203 int size = map->instance_size() + AllocationMemento::kSize; | |
4204 Object* result; | |
4205 MaybeObject* maybe_result = AllocateRaw(size, space, retry_space); | |
4206 if (!maybe_result->ToObject(&result)) return maybe_result; | |
4207 // No need for write barrier since object is white and map is in old space. | |
4208 HeapObject::cast(result)->set_map_no_write_barrier(map); | |
4209 AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>( | |
4210 reinterpret_cast<Address>(result) + map->instance_size()); | |
4211 InitializeAllocationMemento(alloc_memento, *allocation_site); | |
4212 return result; | |
4213 } | |
4214 | |
4215 | |
4216 MaybeObject* Heap::Allocate(Map* map, AllocationSpace space) { | |
4217 ASSERT(gc_state_ == NOT_IN_GC); | |
4218 ASSERT(map->instance_type() != MAP_TYPE); | |
4219 // If allocation failures are disallowed, we may allocate in a different | |
4220 // space when new space is full and the object is not a large object. | 4200 // space when new space is full and the object is not a large object. |
4221 AllocationSpace retry_space = | 4201 AllocationSpace retry_space = |
4222 (space != NEW_SPACE) ? space : TargetSpaceId(map->instance_type()); | 4202 (space != NEW_SPACE) ? space : TargetSpaceId(map->instance_type()); |
4223 int size = map->instance_size(); | 4203 int size = map->instance_size(); |
| 4204 if (allocation_site != NULL) { |
| 4205 size += AllocationMemento::kSize; |
| 4206 } |
4224 Object* result; | 4207 Object* result; |
4225 MaybeObject* maybe_result = AllocateRaw(size, space, retry_space); | 4208 MaybeObject* maybe_result = AllocateRaw(size, space, retry_space); |
4226 if (!maybe_result->ToObject(&result)) return maybe_result; | 4209 if (!maybe_result->ToObject(&result)) return maybe_result; |
4227 // No need for write barrier since object is white and map is in old space. | 4210 // No need for write barrier since object is white and map is in old space. |
4228 HeapObject::cast(result)->set_map_no_write_barrier(map); | 4211 HeapObject::cast(result)->set_map_no_write_barrier(map); |
| 4212 if (allocation_site != NULL) { |
| 4213 AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>( |
| 4214 reinterpret_cast<Address>(result) + map->instance_size()); |
| 4215 InitializeAllocationMemento(alloc_memento, allocation_site); |
| 4216 } |
4229 return result; | 4217 return result; |
4230 } | 4218 } |
4231 | 4219 |
4232 | 4220 |
4233 void Heap::InitializeFunction(JSFunction* function, | 4221 void Heap::InitializeFunction(JSFunction* function, |
4234 SharedFunctionInfo* shared, | 4222 SharedFunctionInfo* shared, |
4235 Object* prototype) { | 4223 Object* prototype) { |
4236 ASSERT(!prototype->IsMap()); | 4224 ASSERT(!prototype->IsMap()); |
4237 function->initialize_properties(); | 4225 function->initialize_properties(); |
4238 function->initialize_elements(); | 4226 function->initialize_elements(); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4342 ASSERT(obj->GetInternalFieldCount() == 0); | 4330 ASSERT(obj->GetInternalFieldCount() == 0); |
4343 filler = Heap::one_pointer_filler_map(); | 4331 filler = Heap::one_pointer_filler_map(); |
4344 } else { | 4332 } else { |
4345 filler = Heap::undefined_value(); | 4333 filler = Heap::undefined_value(); |
4346 } | 4334 } |
4347 obj->InitializeBody(map, Heap::undefined_value(), filler); | 4335 obj->InitializeBody(map, Heap::undefined_value(), filler); |
4348 } | 4336 } |
4349 | 4337 |
4350 | 4338 |
4351 MaybeObject* Heap::AllocateJSObjectFromMap( | 4339 MaybeObject* Heap::AllocateJSObjectFromMap( |
4352 Map* map, PretenureFlag pretenure, bool allocate_properties) { | 4340 Map* map, |
| 4341 PretenureFlag pretenure, |
| 4342 bool allocate_properties, |
| 4343 AllocationSite* allocation_site) { |
4353 // JSFunctions should be allocated using AllocateFunction to be | 4344 // JSFunctions should be allocated using AllocateFunction to be |
4354 // properly initialized. | 4345 // properly initialized. |
4355 ASSERT(map->instance_type() != JS_FUNCTION_TYPE); | 4346 ASSERT(map->instance_type() != JS_FUNCTION_TYPE); |
4356 | 4347 |
4357 // Both types of global objects should be allocated using | 4348 // Both types of global objects should be allocated using |
4358 // AllocateGlobalObject to be properly initialized. | 4349 // AllocateGlobalObject to be properly initialized. |
4359 ASSERT(map->instance_type() != JS_GLOBAL_OBJECT_TYPE); | 4350 ASSERT(map->instance_type() != JS_GLOBAL_OBJECT_TYPE); |
4360 ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE); | 4351 ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE); |
4361 | 4352 |
4362 // Allocate the backing storage for the properties. | 4353 // Allocate the backing storage for the properties. |
4363 FixedArray* properties; | 4354 FixedArray* properties; |
4364 if (allocate_properties) { | 4355 if (allocate_properties) { |
4365 int prop_size = map->InitialPropertiesLength(); | 4356 int prop_size = map->InitialPropertiesLength(); |
4366 ASSERT(prop_size >= 0); | 4357 ASSERT(prop_size >= 0); |
4367 { MaybeObject* maybe_properties = AllocateFixedArray(prop_size, pretenure); | 4358 { MaybeObject* maybe_properties = AllocateFixedArray(prop_size, pretenure); |
4368 if (!maybe_properties->To(&properties)) return maybe_properties; | 4359 if (!maybe_properties->To(&properties)) return maybe_properties; |
4369 } | 4360 } |
4370 } else { | 4361 } else { |
4371 properties = empty_fixed_array(); | 4362 properties = empty_fixed_array(); |
4372 } | 4363 } |
4373 | 4364 |
4374 // Allocate the JSObject. | 4365 // Allocate the JSObject. |
4375 int size = map->instance_size(); | 4366 int size = map->instance_size(); |
4376 AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, pretenure); | 4367 AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, pretenure); |
4377 Object* obj; | 4368 Object* obj; |
4378 MaybeObject* maybe_obj = Allocate(map, space); | 4369 MaybeObject* maybe_obj = Allocate(map, space, allocation_site); |
4379 if (!maybe_obj->To(&obj)) return maybe_obj; | 4370 if (!maybe_obj->To(&obj)) return maybe_obj; |
4380 | 4371 |
4381 // Initialize the JSObject. | 4372 // Initialize the JSObject. |
4382 InitializeJSObjectFromMap(JSObject::cast(obj), properties, map); | 4373 InitializeJSObjectFromMap(JSObject::cast(obj), properties, map); |
4383 ASSERT(JSObject::cast(obj)->HasFastElements() || | 4374 ASSERT(JSObject::cast(obj)->HasFastElements() || |
4384 JSObject::cast(obj)->HasExternalArrayElements()); | 4375 JSObject::cast(obj)->HasExternalArrayElements()); |
4385 return obj; | 4376 return obj; |
4386 } | 4377 } |
4387 | 4378 |
4388 | 4379 |
4389 MaybeObject* Heap::AllocateJSObjectFromMapWithAllocationSite( | |
4390 Map* map, Handle<AllocationSite> allocation_site) { | |
4391 // JSFunctions should be allocated using AllocateFunction to be | |
4392 // properly initialized. | |
4393 ASSERT(map->instance_type() != JS_FUNCTION_TYPE); | |
4394 | |
4395 // Both types of global objects should be allocated using | |
4396 // AllocateGlobalObject to be properly initialized. | |
4397 ASSERT(map->instance_type() != JS_GLOBAL_OBJECT_TYPE); | |
4398 ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE); | |
4399 | |
4400 // Allocate the backing storage for the properties. | |
4401 int prop_size = map->InitialPropertiesLength(); | |
4402 ASSERT(prop_size >= 0); | |
4403 FixedArray* properties; | |
4404 { MaybeObject* maybe_properties = AllocateFixedArray(prop_size); | |
4405 if (!maybe_properties->To(&properties)) return maybe_properties; | |
4406 } | |
4407 | |
4408 // Allocate the JSObject. | |
4409 int size = map->instance_size(); | |
4410 AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, NOT_TENURED); | |
4411 Object* obj; | |
4412 MaybeObject* maybe_obj = | |
4413 AllocateWithAllocationSite(map, space, allocation_site); | |
4414 if (!maybe_obj->To(&obj)) return maybe_obj; | |
4415 | |
4416 // Initialize the JSObject. | |
4417 InitializeJSObjectFromMap(JSObject::cast(obj), properties, map); | |
4418 ASSERT(JSObject::cast(obj)->HasFastElements()); | |
4419 return obj; | |
4420 } | |
4421 | |
4422 | |
4423 MaybeObject* Heap::AllocateJSObject(JSFunction* constructor, | 4380 MaybeObject* Heap::AllocateJSObject(JSFunction* constructor, |
4424 PretenureFlag pretenure) { | 4381 PretenureFlag pretenure, |
| 4382 AllocationSite* allocation_site) { |
4425 ASSERT(constructor->has_initial_map()); | 4383 ASSERT(constructor->has_initial_map()); |
| 4384 |
4426 // Allocate the object based on the constructors initial map. | 4385 // Allocate the object based on the constructors initial map. |
4427 MaybeObject* result = AllocateJSObjectFromMap( | 4386 MaybeObject* result = AllocateJSObjectFromMap(constructor->initial_map(), |
4428 constructor->initial_map(), pretenure); | 4387 pretenure, |
| 4388 true, |
| 4389 allocation_site); |
4429 #ifdef DEBUG | 4390 #ifdef DEBUG |
4430 // Make sure result is NOT a global object if valid. | 4391 // Make sure result is NOT a global object if valid. |
4431 Object* non_failure; | 4392 Object* non_failure; |
4432 ASSERT(!result->ToObject(&non_failure) || !non_failure->IsGlobalObject()); | |
4433 #endif | |
4434 return result; | |
4435 } | |
4436 | |
4437 | |
4438 MaybeObject* Heap::AllocateJSObjectWithAllocationSite(JSFunction* constructor, | |
4439 Handle<AllocationSite> allocation_site) { | |
4440 ASSERT(constructor->has_initial_map()); | |
4441 // Allocate the object based on the constructors initial map, or the payload | |
4442 // advice | |
4443 Map* initial_map = constructor->initial_map(); | |
4444 | |
4445 ElementsKind to_kind = allocation_site->GetElementsKind(); | |
4446 AllocationSiteMode mode = TRACK_ALLOCATION_SITE; | |
4447 if (to_kind != initial_map->elements_kind()) { | |
4448 MaybeObject* maybe_new_map = initial_map->AsElementsKind(to_kind); | |
4449 if (!maybe_new_map->To(&initial_map)) return maybe_new_map; | |
4450 // Possibly alter the mode, since we found an updated elements kind | |
4451 // in the type info cell. | |
4452 mode = AllocationSite::GetMode(to_kind); | |
4453 } | |
4454 | |
4455 MaybeObject* result; | |
4456 if (mode == TRACK_ALLOCATION_SITE) { | |
4457 result = AllocateJSObjectFromMapWithAllocationSite(initial_map, | |
4458 allocation_site); | |
4459 } else { | |
4460 result = AllocateJSObjectFromMap(initial_map, NOT_TENURED); | |
4461 } | |
4462 #ifdef DEBUG | |
4463 // Make sure result is NOT a global object if valid. | |
4464 Object* non_failure; | |
4465 ASSERT(!result->ToObject(&non_failure) || !non_failure->IsGlobalObject()); | 4393 ASSERT(!result->ToObject(&non_failure) || !non_failure->IsGlobalObject()); |
4466 #endif | 4394 #endif |
4467 return result; | 4395 return result; |
4468 } | 4396 } |
4469 | 4397 |
4470 | 4398 |
4471 MaybeObject* Heap::AllocateJSModule(Context* context, ScopeInfo* scope_info) { | 4399 MaybeObject* Heap::AllocateJSModule(Context* context, ScopeInfo* scope_info) { |
4472 // Allocate a fresh map. Modules do not have a prototype. | 4400 // Allocate a fresh map. Modules do not have a prototype. |
4473 Map* map; | 4401 Map* map; |
4474 MaybeObject* maybe_map = AllocateMap(JS_MODULE_TYPE, JSModule::kSize); | 4402 MaybeObject* maybe_map = AllocateMap(JS_MODULE_TYPE, JSModule::kSize); |
(...skipping 3273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7748 static_cast<int>(object_sizes_last_time_[index])); | 7676 static_cast<int>(object_sizes_last_time_[index])); |
7749 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) | 7677 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) |
7750 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 7678 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
7751 | 7679 |
7752 OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 7680 OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
7753 OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 7681 OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
7754 ClearObjectStats(); | 7682 ClearObjectStats(); |
7755 } | 7683 } |
7756 | 7684 |
7757 } } // namespace v8::internal | 7685 } } // namespace v8::internal |
OLD | NEW |