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

Side by Side Diff: src/heap.cc

Issue 11818021: Allocation Info Tracking, continued. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback Created 7 years, 10 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 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 3892 matching lines...) Expand 10 before | Expand all | Expand 10 after
3903 3903
3904 #ifdef VERIFY_HEAP 3904 #ifdef VERIFY_HEAP
3905 if (FLAG_verify_heap) { 3905 if (FLAG_verify_heap) {
3906 code->Verify(); 3906 code->Verify();
3907 } 3907 }
3908 #endif 3908 #endif
3909 return new_code; 3909 return new_code;
3910 } 3910 }
3911 3911
3912 3912
3913 MaybeObject* Heap::Allocate(Map* map, AllocationSpace space) { 3913 MaybeObject* Heap::Allocate(Map* map, AllocationSpace space,
3914 AllocationSiteMode mode,
3915 Handle<Object>* allocation_site_info_payload) {
3914 ASSERT(gc_state_ == NOT_IN_GC); 3916 ASSERT(gc_state_ == NOT_IN_GC);
3915 ASSERT(map->instance_type() != MAP_TYPE); 3917 ASSERT(map->instance_type() != MAP_TYPE);
3918 ASSERT(allocation_site_info_payload != NULL ||
3919 mode == DONT_TRACK_ALLOCATION_SITE);
3920 ASSERT(space == NEW_SPACE || mode == DONT_TRACK_ALLOCATION_SITE);
3916 // If allocation failures are disallowed, we may allocate in a different 3921 // If allocation failures are disallowed, we may allocate in a different
3917 // space when new space is full and the object is not a large object. 3922 // space when new space is full and the object is not a large object.
3918 AllocationSpace retry_space = 3923 AllocationSpace retry_space =
3919 (space != NEW_SPACE) ? space : TargetSpaceId(map->instance_type()); 3924 (space != NEW_SPACE) ? space : TargetSpaceId(map->instance_type());
3925 int size = map->instance_size();
3926 if (mode == TRACK_ALLOCATION_SITE) {
3927 size += AllocationSiteInfo::kSize;
3928 }
3920 Object* result; 3929 Object* result;
3921 { MaybeObject* maybe_result = 3930 MaybeObject* maybe_result = AllocateRaw(size, space, retry_space);
3922 AllocateRaw(map->instance_size(), space, retry_space); 3931 if (!maybe_result->ToObject(&result)) return maybe_result;
3923 if (!maybe_result->ToObject(&result)) return maybe_result;
3924 }
3925 // No need for write barrier since object is white and map is in old space. 3932 // No need for write barrier since object is white and map is in old space.
3926 HeapObject::cast(result)->set_map_no_write_barrier(map); 3933 HeapObject::cast(result)->set_map_no_write_barrier(map);
3934 if (mode == TRACK_ALLOCATION_SITE) {
3935 Object* allocation_pointer = reinterpret_cast<Object*>(
3936 reinterpret_cast<Address>(result) + map->instance_size());
3937 HeapObject::cast(allocation_pointer)->set_map_no_write_barrier(
3938 allocation_site_info_map());
3939 AllocationSiteInfo* allocation_site_info =
3940 AllocationSiteInfo::cast(allocation_pointer);
3941 allocation_site_info->set_payload(**allocation_site_info_payload);
3942 }
3927 return result; 3943 return result;
3928 } 3944 }
3929 3945
3930
3931 // TODO(mvstanton): consolidate this with the function above.
3932 MaybeObject* Heap::AllocateWithAllocationSiteInfo(Map* map,
3933 AllocationSpace space,
3934 Handle<Object>* allocation_site_info_payload) {
3935 ASSERT(gc_state_ == NOT_IN_GC);
3936 ASSERT(map->instance_type() != MAP_TYPE);
3937 // If allocation failures are disallowed, we may allocate in a different
3938 // space when new space is full and the object is not a large object.
3939 AllocationSpace retry_space =
3940 (space != NEW_SPACE) ? space : TargetSpaceId(map->instance_type());
3941 Object* result;
3942 { MaybeObject* maybe_result =
3943 AllocateRaw(map->instance_size() + AllocationSiteInfo::kSize,
3944 space,
3945 retry_space);
3946 if (!maybe_result->ToObject(&result)) return maybe_result;
3947 }
3948 // No need for write barrier since object is white and map is in old space.
3949 HeapObject::cast(result)->set_map_no_write_barrier(map);
3950 Object* allocation_pointer = reinterpret_cast<Object*>(
3951 reinterpret_cast<Address>(result) + map->instance_size());
3952 HeapObject::cast(allocation_pointer)->set_map_no_write_barrier(
3953 allocation_site_info_map());
3954 AllocationSiteInfo* allocation_site_info =
3955 AllocationSiteInfo::cast(allocation_pointer);
3956 allocation_site_info->set_payload(**allocation_site_info_payload);
3957 return result;
3958 }
3959
3960 3946
3961 void Heap::InitializeFunction(JSFunction* function, 3947 void Heap::InitializeFunction(JSFunction* function,
3962 SharedFunctionInfo* shared, 3948 SharedFunctionInfo* shared,
3963 Object* prototype) { 3949 Object* prototype) {
3964 ASSERT(!prototype->IsMap()); 3950 ASSERT(!prototype->IsMap());
3965 function->initialize_properties(); 3951 function->initialize_properties();
3966 function->initialize_elements(); 3952 function->initialize_elements();
3967 function->set_shared(shared); 3953 function->set_shared(shared);
3968 function->set_code(shared->code()); 3954 function->set_code(shared->code());
3969 function->set_prototype_or_initial_map(prototype); 3955 function->set_prototype_or_initial_map(prototype);
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
4189 } else { 4175 } else {
4190 filler = Heap::undefined_value(); 4176 filler = Heap::undefined_value();
4191 } 4177 }
4192 obj->InitializeBody(map, Heap::undefined_value(), filler); 4178 obj->InitializeBody(map, Heap::undefined_value(), filler);
4193 } 4179 }
4194 4180
4195 4181
4196 MaybeObject* Heap::AllocateJSObjectFromMap(Map* map, PretenureFlag pretenure, 4182 MaybeObject* Heap::AllocateJSObjectFromMap(Map* map, PretenureFlag pretenure,
4197 AllocationSiteMode mode, 4183 AllocationSiteMode mode,
4198 Handle<Object>* allocation_site_info_payload) { 4184 Handle<Object>* allocation_site_info_payload) {
4185 ASSERT(allocation_site_info_payload != NULL ||
4186 mode == DONT_TRACK_ALLOCATION_SITE);
4199 ASSERT(pretenure == NOT_TENURED || mode == DONT_TRACK_ALLOCATION_SITE); 4187 ASSERT(pretenure == NOT_TENURED || mode == DONT_TRACK_ALLOCATION_SITE);
4200 // JSFunctions should be allocated using AllocateFunction to be 4188 // JSFunctions should be allocated using AllocateFunction to be
4201 // properly initialized. 4189 // properly initialized.
4202 ASSERT(map->instance_type() != JS_FUNCTION_TYPE); 4190 ASSERT(map->instance_type() != JS_FUNCTION_TYPE);
4203 4191
4204 // Both types of global objects should be allocated using 4192 // Both types of global objects should be allocated using
4205 // AllocateGlobalObject to be properly initialized. 4193 // AllocateGlobalObject to be properly initialized.
4206 ASSERT(map->instance_type() != JS_GLOBAL_OBJECT_TYPE); 4194 ASSERT(map->instance_type() != JS_GLOBAL_OBJECT_TYPE);
4207 ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE); 4195 ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE);
4208 4196
4209 // Allocate the backing storage for the properties. 4197 // Allocate the backing storage for the properties.
4210 int prop_size = 4198 int prop_size =
4211 map->pre_allocated_property_fields() + 4199 map->pre_allocated_property_fields() +
4212 map->unused_property_fields() - 4200 map->unused_property_fields() -
4213 map->inobject_properties(); 4201 map->inobject_properties();
4214 ASSERT(prop_size >= 0); 4202 ASSERT(prop_size >= 0);
4215 Object* properties; 4203 Object* properties;
4216 { MaybeObject* maybe_properties = AllocateFixedArray(prop_size, pretenure); 4204 { MaybeObject* maybe_properties = AllocateFixedArray(prop_size, pretenure);
4217 if (!maybe_properties->ToObject(&properties)) return maybe_properties; 4205 if (!maybe_properties->ToObject(&properties)) return maybe_properties;
4218 } 4206 }
4219 4207
4220 // Allocate the JSObject. 4208 // Allocate the JSObject.
4221 AllocationSpace space = 4209 AllocationSpace space =
4222 (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE; 4210 (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
4223 if (map->instance_size() > Page::kMaxNonCodeHeapObjectSize) space = LO_SPACE; 4211 if (map->instance_size() > Page::kMaxNonCodeHeapObjectSize) space = LO_SPACE;
4224 Object* obj; 4212 Object* obj;
4225 { 4213 MaybeObject* maybe_obj = Allocate(map, space, mode,
4226 MaybeObject* maybe_obj; 4214 allocation_site_info_payload);
4227 if (mode == TRACK_ALLOCATION_SITE) { 4215 if (!maybe_obj->To(&obj)) return maybe_obj;
4228 maybe_obj = AllocateWithAllocationSiteInfo(map, space,
4229 allocation_site_info_payload);
4230 } else {
4231 maybe_obj = Allocate(map, space);
4232 }
4233 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
4234 }
4235 4216
4236 // Initialize the JSObject. 4217 // Initialize the JSObject.
4237 InitializeJSObjectFromMap(JSObject::cast(obj), 4218 InitializeJSObjectFromMap(JSObject::cast(obj),
4238 FixedArray::cast(properties), 4219 FixedArray::cast(properties),
4239 map); 4220 map);
4240 ASSERT(JSObject::cast(obj)->HasFastElements()); 4221 ASSERT(JSObject::cast(obj)->HasFastElements());
4241 return obj; 4222 return obj;
4242 } 4223 }
4243 4224
4244 4225
4245 MaybeObject* Heap::AllocateJSObject(JSFunction* constructor, 4226 MaybeObject* Heap::AllocateJSObject(JSFunction* constructor,
4246 PretenureFlag pretenure, 4227 PretenureFlag pretenure,
4247 AllocationSiteMode mode, 4228 AllocationSiteMode mode,
4248 Handle<Object>* allocation_site_info_payload) { 4229 Handle<Object>* allocation_site_info_payload) {
4230 ASSERT(allocation_site_info_payload != NULL ||
4231 mode == DONT_TRACK_ALLOCATION_SITE);
4232 ASSERT(pretenure == NOT_TENURED || mode == DONT_TRACK_ALLOCATION_SITE);
4249 // Allocate the initial map if absent. 4233 // Allocate the initial map if absent.
4250 if (!constructor->has_initial_map()) { 4234 if (!constructor->has_initial_map()) {
4251 Object* initial_map; 4235 Object* initial_map;
4252 { MaybeObject* maybe_initial_map = AllocateInitialMap(constructor); 4236 { MaybeObject* maybe_initial_map = AllocateInitialMap(constructor);
4253 if (!maybe_initial_map->ToObject(&initial_map)) return maybe_initial_map; 4237 if (!maybe_initial_map->ToObject(&initial_map)) return maybe_initial_map;
4254 } 4238 }
4255 constructor->set_initial_map(Map::cast(initial_map)); 4239 constructor->set_initial_map(Map::cast(initial_map));
4256 Map::cast(initial_map)->set_constructor(constructor); 4240 Map::cast(initial_map)->set_constructor(constructor);
4257 } 4241 }
4258 // Allocate the object based on the constructors initial map, or the payload 4242 // Allocate the object based on the constructors initial map, or the payload
4259 // advice 4243 // advice
4260 Map* initial_map = constructor->initial_map(); 4244 Map* initial_map = constructor->initial_map();
4261 if (mode == TRACK_ALLOCATION_SITE) { 4245 if (mode == TRACK_ALLOCATION_SITE) {
4262 ASSERT(allocation_site_info_payload != NULL);
4263 ASSERT((*allocation_site_info_payload)->IsJSGlobalPropertyCell());
4264 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast( 4246 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(
4265 **allocation_site_info_payload); 4247 **allocation_site_info_payload);
4266 ASSERT(cell->value()->IsSmi());
4267 Smi* smi = Smi::cast(cell->value()); 4248 Smi* smi = Smi::cast(cell->value());
4268 ElementsKind to_kind = static_cast<ElementsKind>(smi->value()); 4249 ElementsKind to_kind = static_cast<ElementsKind>(smi->value());
4269 if (to_kind != initial_map->elements_kind()) { 4250 if (to_kind != initial_map->elements_kind()) {
4270 initial_map = initial_map->LookupElementsTransitionMap(to_kind); 4251 MaybeObject* maybe_new_map = constructor->GetElementsTransitionMap(
4271 // TODO(mvstanton): I may have to allocate this transition, right? 4252 isolate(), to_kind);
4272 ASSERT(initial_map != NULL); 4253 if (!maybe_new_map->To(&initial_map)) return maybe_new_map;
4273 // constructor->set_initial_map(Map::cast(initial_map)); 4254 // TODO(mvstanton): Is the line below useful for performance?
4274 // Map::cast(initial_map)->set_constructor(constructor); 4255 // mode = DONT_TRACK_ALLOCATION_SITE;
Toon Verwaest 2013/02/21 12:13:03 Use GetMode(to_kind); here to decide whether or no
mvstanton 2013/02/27 14:37:07 Done.
4275 mode = DONT_TRACK_ALLOCATION_SITE;
4276 } 4256 }
4277 } 4257 }
4278 4258
4279 MaybeObject* result = AllocateJSObjectFromMap( 4259 MaybeObject* result = AllocateJSObjectFromMap(
4280 initial_map, pretenure, 4260 initial_map, pretenure,
4281 mode, allocation_site_info_payload); 4261 mode, allocation_site_info_payload);
4282 #ifdef DEBUG 4262 #ifdef DEBUG
4283 // Make sure result is NOT a global object if valid. 4263 // Make sure result is NOT a global object if valid.
4284 Object* non_failure; 4264 Object* non_failure;
4285 ASSERT(!result->ToObject(&non_failure) || !non_failure->IsGlobalObject()); 4265 ASSERT(!result->ToObject(&non_failure) || !non_failure->IsGlobalObject());
(...skipping 18 matching lines...) Expand all
4304 4284
4305 4285
4306 MaybeObject* Heap::AllocateJSArrayAndStorage( 4286 MaybeObject* Heap::AllocateJSArrayAndStorage(
4307 ElementsKind elements_kind, 4287 ElementsKind elements_kind,
4308 int length, 4288 int length,
4309 int capacity, 4289 int capacity,
4310 AllocationSiteMode allocation_site_info_mode, 4290 AllocationSiteMode allocation_site_info_mode,
4311 Handle<Object> *allocation_site_payload, 4291 Handle<Object> *allocation_site_payload,
4312 ArrayStorageAllocationMode mode, 4292 ArrayStorageAllocationMode mode,
4313 PretenureFlag pretenure) { 4293 PretenureFlag pretenure) {
4314 ASSERT(capacity >= length);
4315 ASSERT(allocation_site_payload != NULL || 4294 ASSERT(allocation_site_payload != NULL ||
4316 allocation_site_info_mode == DONT_TRACK_ALLOCATION_SITE); 4295 allocation_site_info_mode == DONT_TRACK_ALLOCATION_SITE);
4317 if (pretenure == TENURED && 4296 ASSERT(pretenure == NOT_TENURED ||
4318 allocation_site_info_mode == TRACK_ALLOCATION_SITE) { 4297 allocation_site_info_mode == DONT_TRACK_ALLOCATION_SITE);
4319 PrintF("Sorry, can't track yet in tenured space\n");
4320 }
4321 MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure, 4298 MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure,
4322 allocation_site_info_mode, 4299 allocation_site_info_mode,
4323 allocation_site_payload); 4300 allocation_site_payload);
4324 JSArray* array; 4301 JSArray* array;
4325 if (!maybe_array->To(&array)) return maybe_array; 4302 if (!maybe_array->To(&array)) return maybe_array;
4303 return AllocateJSArrayStorage(array, length, capacity, mode);
4304 }
4305
4306
4307 MaybeObject* Heap::AllocateJSArrayStorage(
4308 JSArray* array,
4309 int length,
4310 int capacity,
4311 ArrayStorageAllocationMode mode) {
4312 ASSERT(capacity >= length);
4326 4313
4327 if (capacity == 0) { 4314 if (capacity == 0) {
4328 array->set_length(Smi::FromInt(0)); 4315 array->set_length(Smi::FromInt(0));
4329 array->set_elements(empty_fixed_array()); 4316 array->set_elements(empty_fixed_array());
4330 return array; 4317 return array;
4331 } 4318 }
4332 4319
4333 FixedArrayBase* elms; 4320 FixedArrayBase* elms;
4334 MaybeObject* maybe_elms = NULL; 4321 MaybeObject* maybe_elms = NULL;
4322 ElementsKind elements_kind = array->GetElementsKind();
4335 if (IsFastDoubleElementsKind(elements_kind)) { 4323 if (IsFastDoubleElementsKind(elements_kind)) {
4336 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { 4324 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
4337 maybe_elms = AllocateUninitializedFixedDoubleArray(capacity); 4325 maybe_elms = AllocateUninitializedFixedDoubleArray(capacity);
4338 } else { 4326 } else {
4339 ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); 4327 ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
4340 maybe_elms = AllocateFixedDoubleArrayWithHoles(capacity); 4328 maybe_elms = AllocateFixedDoubleArrayWithHoles(capacity);
4341 } 4329 }
4342 } else { 4330 } else {
4343 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind)); 4331 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind));
4344 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { 4332 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
(...skipping 3284 matching lines...) Expand 10 before | Expand all | Expand 10 after
7629 static_cast<int>(object_sizes_last_time_[index])); 7617 static_cast<int>(object_sizes_last_time_[index]));
7630 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) 7618 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
7631 #undef ADJUST_LAST_TIME_OBJECT_COUNT 7619 #undef ADJUST_LAST_TIME_OBJECT_COUNT
7632 7620
7633 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 7621 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
7634 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 7622 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
7635 ClearObjectStats(); 7623 ClearObjectStats();
7636 } 7624 }
7637 7625
7638 } } // namespace v8::internal 7626 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap.h ('k') | src/ia32/code-stubs-ia32.cc » ('j') | src/objects.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698