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

Side by Side Diff: src/heap.cc

Issue 240293002: Handlify number-related allocators. (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
« no previous file with comments | « src/heap.h ('k') | src/heap-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 2390 matching lines...) Expand 10 before | Expand all | Expand 10 after
2401 map->set_bit_field2(1 << Map::kIsExtensible); 2401 map->set_bit_field2(1 << Map::kIsExtensible);
2402 int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) | 2402 int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) |
2403 Map::OwnsDescriptors::encode(true); 2403 Map::OwnsDescriptors::encode(true);
2404 map->set_bit_field3(bit_field3); 2404 map->set_bit_field3(bit_field3);
2405 map->set_elements_kind(elements_kind); 2405 map->set_elements_kind(elements_kind);
2406 2406
2407 return map; 2407 return map;
2408 } 2408 }
2409 2409
2410 2410
2411 MaybeObject* Heap::AllocateCodeCache() {
2412 CodeCache* code_cache;
2413 { MaybeObject* maybe_code_cache = AllocateStruct(CODE_CACHE_TYPE);
2414 if (!maybe_code_cache->To(&code_cache)) return maybe_code_cache;
2415 }
2416 code_cache->set_default_cache(empty_fixed_array(), SKIP_WRITE_BARRIER);
2417 code_cache->set_normal_type_cache(undefined_value(), SKIP_WRITE_BARRIER);
2418 return code_cache;
2419 }
2420
2421
2422 MaybeObject* Heap::AllocatePolymorphicCodeCache() { 2411 MaybeObject* Heap::AllocatePolymorphicCodeCache() {
2423 return AllocateStruct(POLYMORPHIC_CODE_CACHE_TYPE); 2412 return AllocateStruct(POLYMORPHIC_CODE_CACHE_TYPE);
2424 } 2413 }
2425 2414
2426 2415
2427 const Heap::StringTypeTable Heap::string_type_table[] = { 2416 const Heap::StringTypeTable Heap::string_type_table[] = {
2428 #define STRING_TYPE_ELEMENT(type, size, name, camel_name) \ 2417 #define STRING_TYPE_ELEMENT(type, size, name, camel_name) \
2429 {type, size, k##camel_name##MapRootIndex}, 2418 {type, size, k##camel_name##MapRootIndex},
2430 STRING_TYPE_LIST(STRING_TYPE_ELEMENT) 2419 STRING_TYPE_LIST(STRING_TYPE_ELEMENT)
2431 #undef STRING_TYPE_ELEMENT 2420 #undef STRING_TYPE_ELEMENT
(...skipping 816 matching lines...) Expand 10 before | Expand all | Expand 10 after
3248 // size to ensure that it is bigger after being made 'full size'. 3237 // size to ensure that it is bigger after being made 'full size'.
3249 int number_string_cache_size = max_semispace_size_ / 512; 3238 int number_string_cache_size = max_semispace_size_ / 512;
3250 number_string_cache_size = Max(kInitialNumberStringCacheSize * 2, 3239 number_string_cache_size = Max(kInitialNumberStringCacheSize * 2,
3251 Min(0x4000, number_string_cache_size)); 3240 Min(0x4000, number_string_cache_size));
3252 // There is a string and a number per entry so the length is twice the number 3241 // There is a string and a number per entry so the length is twice the number
3253 // of entries. 3242 // of entries.
3254 return number_string_cache_size * 2; 3243 return number_string_cache_size * 2;
3255 } 3244 }
3256 3245
3257 3246
3258 void Heap::AllocateFullSizeNumberStringCache() {
3259 // The idea is to have a small number string cache in the snapshot to keep
3260 // boot-time memory usage down. If we expand the number string cache already
3261 // while creating the snapshot then that didn't work out.
3262 ASSERT(!Serializer::enabled() || FLAG_extra_code != NULL);
3263 MaybeObject* maybe_obj =
3264 AllocateFixedArray(FullSizeNumberStringCacheLength(), TENURED);
3265 Object* new_cache;
3266 if (maybe_obj->ToObject(&new_cache)) {
3267 // We don't bother to repopulate the cache with entries from the old cache.
3268 // It will be repopulated soon enough with new strings.
3269 set_number_string_cache(FixedArray::cast(new_cache));
3270 }
3271 // If allocation fails then we just return without doing anything. It is only
3272 // a cache, so best effort is OK here.
3273 }
3274
3275
3276 void Heap::FlushNumberStringCache() { 3247 void Heap::FlushNumberStringCache() {
3277 // Flush the number to string cache. 3248 // Flush the number to string cache.
3278 int len = number_string_cache()->length(); 3249 int len = number_string_cache()->length();
3279 for (int i = 0; i < len; i++) { 3250 for (int i = 0; i < len; i++) {
3280 number_string_cache()->set_undefined(i); 3251 number_string_cache()->set_undefined(i);
3281 } 3252 }
3282 } 3253 }
3283 3254
3284 3255
3285 static inline int double_get_hash(double d) {
3286 DoubleRepresentation rep(d);
3287 return static_cast<int>(rep.bits) ^ static_cast<int>(rep.bits >> 32);
3288 }
3289
3290
3291 static inline int smi_get_hash(Smi* smi) {
3292 return smi->value();
3293 }
3294
3295
3296 Object* Heap::GetNumberStringCache(Object* number) {
3297 int hash;
3298 int mask = (number_string_cache()->length() >> 1) - 1;
3299 if (number->IsSmi()) {
3300 hash = smi_get_hash(Smi::cast(number)) & mask;
3301 } else {
3302 hash = double_get_hash(number->Number()) & mask;
3303 }
3304 Object* key = number_string_cache()->get(hash * 2);
3305 if (key == number) {
3306 return String::cast(number_string_cache()->get(hash * 2 + 1));
3307 } else if (key->IsHeapNumber() &&
3308 number->IsHeapNumber() &&
3309 key->Number() == number->Number()) {
3310 return String::cast(number_string_cache()->get(hash * 2 + 1));
3311 }
3312 return undefined_value();
3313 }
3314
3315
3316 void Heap::SetNumberStringCache(Object* number, String* string) {
3317 int hash;
3318 int mask = (number_string_cache()->length() >> 1) - 1;
3319 if (number->IsSmi()) {
3320 hash = smi_get_hash(Smi::cast(number)) & mask;
3321 } else {
3322 hash = double_get_hash(number->Number()) & mask;
3323 }
3324 if (number_string_cache()->get(hash * 2) != undefined_value() &&
3325 number_string_cache()->length() != FullSizeNumberStringCacheLength()) {
3326 // The first time we have a hash collision, we move to the full sized
3327 // number string cache.
3328 AllocateFullSizeNumberStringCache();
3329 return;
3330 }
3331 number_string_cache()->set(hash * 2, number);
3332 number_string_cache()->set(hash * 2 + 1, string);
3333 }
3334
3335
3336 MaybeObject* Heap::NumberToString(Object* number,
3337 bool check_number_string_cache) {
3338 isolate_->counters()->number_to_string_runtime()->Increment();
3339 if (check_number_string_cache) {
3340 Object* cached = GetNumberStringCache(number);
3341 if (cached != undefined_value()) {
3342 return cached;
3343 }
3344 }
3345
3346 char arr[100];
3347 Vector<char> buffer(arr, ARRAY_SIZE(arr));
3348 const char* str;
3349 if (number->IsSmi()) {
3350 int num = Smi::cast(number)->value();
3351 str = IntToCString(num, buffer);
3352 } else {
3353 double num = HeapNumber::cast(number)->value();
3354 str = DoubleToCString(num, buffer);
3355 }
3356
3357 Object* js_string;
3358
3359 // We tenure the allocated string since it is referenced from the
3360 // number-string cache which lives in the old space.
3361 MaybeObject* maybe_js_string =
3362 AllocateStringFromOneByte(CStrVector(str), TENURED);
3363 if (maybe_js_string->ToObject(&js_string)) {
3364 SetNumberStringCache(number, String::cast(js_string));
3365 }
3366 return maybe_js_string;
3367 }
3368
3369
3370 MaybeObject* Heap::Uint32ToString(uint32_t value,
3371 bool check_number_string_cache) {
3372 Object* number;
3373 MaybeObject* maybe = NumberFromUint32(value);
3374 if (!maybe->To<Object>(&number)) return maybe;
3375 return NumberToString(number, check_number_string_cache);
3376 }
3377
3378
3379 MaybeObject* Heap::AllocateAllocationSitesScratchpad() { 3256 MaybeObject* Heap::AllocateAllocationSitesScratchpad() {
3380 MaybeObject* maybe_obj = 3257 MaybeObject* maybe_obj =
3381 AllocateFixedArray(kAllocationSiteScratchpadSize, TENURED); 3258 AllocateFixedArray(kAllocationSiteScratchpadSize, TENURED);
3382 return maybe_obj; 3259 return maybe_obj;
3383 } 3260 }
3384 3261
3385 3262
3386 void Heap::FlushAllocationSitesScratchpad() { 3263 void Heap::FlushAllocationSitesScratchpad() {
3387 for (int i = 0; i < allocation_sites_scratchpad_length_; i++) { 3264 for (int i = 0; i < allocation_sites_scratchpad_length_; i++) {
3388 allocation_sites_scratchpad()->set_undefined(i); 3265 allocation_sites_scratchpad()->set_undefined(i);
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
3506 roots_[RootIndexForEmptyExternalArray(map->elements_kind())]); 3383 roots_[RootIndexForEmptyExternalArray(map->elements_kind())]);
3507 } 3384 }
3508 3385
3509 3386
3510 FixedTypedArrayBase* Heap::EmptyFixedTypedArrayForMap(Map* map) { 3387 FixedTypedArrayBase* Heap::EmptyFixedTypedArrayForMap(Map* map) {
3511 return FixedTypedArrayBase::cast( 3388 return FixedTypedArrayBase::cast(
3512 roots_[RootIndexForEmptyFixedTypedArray(map->elements_kind())]); 3389 roots_[RootIndexForEmptyFixedTypedArray(map->elements_kind())]);
3513 } 3390 }
3514 3391
3515 3392
3516 MaybeObject* Heap::NumberFromDouble(double value, PretenureFlag pretenure) {
3517 // We need to distinguish the minus zero value and this cannot be
3518 // done after conversion to int. Doing this by comparing bit
3519 // patterns is faster than using fpclassify() et al.
3520 if (IsMinusZero(value)) {
3521 return AllocateHeapNumber(-0.0, pretenure);
3522 }
3523
3524 int int_value = FastD2I(value);
3525 if (value == int_value && Smi::IsValid(int_value)) {
3526 return Smi::FromInt(int_value);
3527 }
3528
3529 // Materialize the value in the heap.
3530 return AllocateHeapNumber(value, pretenure);
3531 }
3532
3533
3534 MaybeObject* Heap::AllocateForeign(Address address, PretenureFlag pretenure) { 3393 MaybeObject* Heap::AllocateForeign(Address address, PretenureFlag pretenure) {
3535 // Statically ensure that it is safe to allocate foreigns in paged spaces. 3394 // Statically ensure that it is safe to allocate foreigns in paged spaces.
3536 STATIC_ASSERT(Foreign::kSize <= Page::kMaxRegularHeapObjectSize); 3395 STATIC_ASSERT(Foreign::kSize <= Page::kMaxRegularHeapObjectSize);
3537 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; 3396 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
3538 Foreign* result; 3397 Foreign* result;
3539 MaybeObject* maybe_result = Allocate(foreign_map(), space); 3398 MaybeObject* maybe_result = Allocate(foreign_map(), space);
3540 if (!maybe_result->To(&result)) return maybe_result; 3399 if (!maybe_result->To(&result)) return maybe_result;
3541 result->set_foreign_address(address); 3400 result->set_foreign_address(address);
3542 return result; 3401 return result;
3543 } 3402 }
(...skipping 3520 matching lines...) Expand 10 before | Expand all | Expand 10 after
7064 static_cast<int>(object_sizes_last_time_[index])); 6923 static_cast<int>(object_sizes_last_time_[index]));
7065 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) 6924 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
7066 #undef ADJUST_LAST_TIME_OBJECT_COUNT 6925 #undef ADJUST_LAST_TIME_OBJECT_COUNT
7067 6926
7068 OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 6927 OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
7069 OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 6928 OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
7070 ClearObjectStats(); 6929 ClearObjectStats();
7071 } 6930 }
7072 6931
7073 } } // namespace v8::internal 6932 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap.h ('k') | src/heap-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698