OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "accessors.h" | 7 #include "accessors.h" |
8 #include "api.h" | 8 #include "api.h" |
9 #include "bootstrapper.h" | 9 #include "bootstrapper.h" |
10 #include "codegen.h" | 10 #include "codegen.h" |
(...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
907 | 907 |
908 void Heap::ReserveSpace(int *sizes, Address *locations_out) { | 908 void Heap::ReserveSpace(int *sizes, Address *locations_out) { |
909 bool gc_performed = true; | 909 bool gc_performed = true; |
910 int counter = 0; | 910 int counter = 0; |
911 static const int kThreshold = 20; | 911 static const int kThreshold = 20; |
912 while (gc_performed && counter++ < kThreshold) { | 912 while (gc_performed && counter++ < kThreshold) { |
913 gc_performed = false; | 913 gc_performed = false; |
914 ASSERT(NEW_SPACE == FIRST_PAGED_SPACE - 1); | 914 ASSERT(NEW_SPACE == FIRST_PAGED_SPACE - 1); |
915 for (int space = NEW_SPACE; space <= LAST_PAGED_SPACE; space++) { | 915 for (int space = NEW_SPACE; space <= LAST_PAGED_SPACE; space++) { |
916 if (sizes[space] != 0) { | 916 if (sizes[space] != 0) { |
917 MaybeObject* allocation; | 917 AllocationResult allocation; |
918 if (space == NEW_SPACE) { | 918 if (space == NEW_SPACE) { |
919 allocation = new_space()->AllocateRaw(sizes[space]); | 919 allocation = new_space()->AllocateRaw(sizes[space]); |
920 } else { | 920 } else { |
921 allocation = paged_space(space)->AllocateRaw(sizes[space]); | 921 allocation = paged_space(space)->AllocateRaw(sizes[space]); |
922 } | 922 } |
923 FreeListNode* node; | 923 FreeListNode* node; |
924 if (!allocation->To<FreeListNode>(&node)) { | 924 if (!allocation.To(&node)) { |
925 if (space == NEW_SPACE) { | 925 if (space == NEW_SPACE) { |
926 Heap::CollectGarbage(NEW_SPACE, | 926 Heap::CollectGarbage(NEW_SPACE, |
927 "failed to reserve space in the new space"); | 927 "failed to reserve space in the new space"); |
928 } else { | 928 } else { |
929 AbortIncrementalMarkingAndCollectGarbage( | 929 AbortIncrementalMarkingAndCollectGarbage( |
930 this, | 930 this, |
931 static_cast<AllocationSpace>(space), | 931 static_cast<AllocationSpace>(space), |
932 "failed to reserve space in paged space"); | 932 "failed to reserve space in paged space"); |
933 } | 933 } |
934 gc_performed = true; | 934 gc_performed = true; |
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2038 SLOW_ASSERT(object->Size() == object_size); | 2038 SLOW_ASSERT(object->Size() == object_size); |
2039 | 2039 |
2040 int allocation_size = object_size; | 2040 int allocation_size = object_size; |
2041 if (alignment != kObjectAlignment) { | 2041 if (alignment != kObjectAlignment) { |
2042 ASSERT(alignment == kDoubleAlignment); | 2042 ASSERT(alignment == kDoubleAlignment); |
2043 allocation_size += kPointerSize; | 2043 allocation_size += kPointerSize; |
2044 } | 2044 } |
2045 | 2045 |
2046 Heap* heap = map->GetHeap(); | 2046 Heap* heap = map->GetHeap(); |
2047 if (heap->ShouldBePromoted(object->address(), object_size)) { | 2047 if (heap->ShouldBePromoted(object->address(), object_size)) { |
2048 MaybeObject* maybe_result; | 2048 AllocationResult allocation; |
2049 | 2049 |
2050 if (object_contents == DATA_OBJECT) { | 2050 if (object_contents == DATA_OBJECT) { |
2051 ASSERT(heap->AllowedToBeMigrated(object, OLD_DATA_SPACE)); | 2051 ASSERT(heap->AllowedToBeMigrated(object, OLD_DATA_SPACE)); |
2052 maybe_result = heap->old_data_space()->AllocateRaw(allocation_size); | 2052 allocation = heap->old_data_space()->AllocateRaw(allocation_size); |
2053 } else { | 2053 } else { |
2054 ASSERT(heap->AllowedToBeMigrated(object, OLD_POINTER_SPACE)); | 2054 ASSERT(heap->AllowedToBeMigrated(object, OLD_POINTER_SPACE)); |
2055 maybe_result = heap->old_pointer_space()->AllocateRaw(allocation_size); | 2055 allocation = heap->old_pointer_space()->AllocateRaw(allocation_size); |
2056 } | 2056 } |
2057 | 2057 |
2058 Object* result = NULL; // Initialization to please compiler. | 2058 HeapObject* target = NULL; // Initialization to please compiler. |
2059 if (maybe_result->ToObject(&result)) { | 2059 if (allocation.To(&target)) { |
2060 HeapObject* target = HeapObject::cast(result); | |
2061 | |
2062 if (alignment != kObjectAlignment) { | 2060 if (alignment != kObjectAlignment) { |
2063 target = EnsureDoubleAligned(heap, target, allocation_size); | 2061 target = EnsureDoubleAligned(heap, target, allocation_size); |
2064 } | 2062 } |
2065 | 2063 |
2066 // Order is important: slot might be inside of the target if target | 2064 // Order is important: slot might be inside of the target if target |
2067 // was allocated over a dead object and slot comes from the store | 2065 // was allocated over a dead object and slot comes from the store |
2068 // buffer. | 2066 // buffer. |
2069 *slot = target; | 2067 *slot = target; |
2070 MigrateObject(heap, object, target, object_size); | 2068 MigrateObject(heap, object, target, object_size); |
2071 | 2069 |
2072 if (object_contents == POINTER_OBJECT) { | 2070 if (object_contents == POINTER_OBJECT) { |
2073 if (map->instance_type() == JS_FUNCTION_TYPE) { | 2071 if (map->instance_type() == JS_FUNCTION_TYPE) { |
2074 heap->promotion_queue()->insert( | 2072 heap->promotion_queue()->insert( |
2075 target, JSFunction::kNonWeakFieldsEndOffset); | 2073 target, JSFunction::kNonWeakFieldsEndOffset); |
2076 } else { | 2074 } else { |
2077 heap->promotion_queue()->insert(target, object_size); | 2075 heap->promotion_queue()->insert(target, object_size); |
2078 } | 2076 } |
2079 } | 2077 } |
2080 | 2078 |
2081 heap->tracer()->increment_promoted_objects_size(object_size); | 2079 heap->tracer()->increment_promoted_objects_size(object_size); |
2082 return; | 2080 return; |
2083 } | 2081 } |
2084 } | 2082 } |
2085 ASSERT(heap->AllowedToBeMigrated(object, NEW_SPACE)); | 2083 ASSERT(heap->AllowedToBeMigrated(object, NEW_SPACE)); |
2086 MaybeObject* allocation = heap->new_space()->AllocateRaw(allocation_size); | 2084 AllocationResult allocation = |
2085 heap->new_space()->AllocateRaw(allocation_size); | |
2087 heap->promotion_queue()->SetNewLimit(heap->new_space()->top()); | 2086 heap->promotion_queue()->SetNewLimit(heap->new_space()->top()); |
2088 Object* result = allocation->ToObjectUnchecked(); | 2087 HeapObject* target = HeapObject::cast(allocation.ToObjectChecked()); |
2089 HeapObject* target = HeapObject::cast(result); | |
2090 | 2088 |
2091 if (alignment != kObjectAlignment) { | 2089 if (alignment != kObjectAlignment) { |
2092 target = EnsureDoubleAligned(heap, target, allocation_size); | 2090 target = EnsureDoubleAligned(heap, target, allocation_size); |
2093 } | 2091 } |
2094 | 2092 |
2095 // Order is important: slot might be inside of the target if target | 2093 // Order is important: slot might be inside of the target if target |
2096 // was allocated over a dead object and slot comes from the store | 2094 // was allocated over a dead object and slot comes from the store |
2097 // buffer. | 2095 // buffer. |
2098 *slot = target; | 2096 *slot = target; |
2099 MigrateObject(heap, object, target, object_size); | 2097 MigrateObject(heap, object, target, object_size); |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2316 | 2314 |
2317 void Heap::ScavengeObjectSlow(HeapObject** p, HeapObject* object) { | 2315 void Heap::ScavengeObjectSlow(HeapObject** p, HeapObject* object) { |
2318 SLOW_ASSERT(object->GetIsolate()->heap()->InFromSpace(object)); | 2316 SLOW_ASSERT(object->GetIsolate()->heap()->InFromSpace(object)); |
2319 MapWord first_word = object->map_word(); | 2317 MapWord first_word = object->map_word(); |
2320 SLOW_ASSERT(!first_word.IsForwardingAddress()); | 2318 SLOW_ASSERT(!first_word.IsForwardingAddress()); |
2321 Map* map = first_word.ToMap(); | 2319 Map* map = first_word.ToMap(); |
2322 map->GetHeap()->DoScavengeObject(map, p, object); | 2320 map->GetHeap()->DoScavengeObject(map, p, object); |
2323 } | 2321 } |
2324 | 2322 |
2325 | 2323 |
2326 MaybeObject* Heap::AllocatePartialMap(InstanceType instance_type, | 2324 AllocationResult Heap::AllocatePartialMap(InstanceType instance_type, |
2327 int instance_size) { | 2325 int instance_size) { |
2328 Object* result; | 2326 Object* result; |
2329 MaybeObject* maybe_result = AllocateRaw(Map::kSize, MAP_SPACE, MAP_SPACE); | 2327 AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE, MAP_SPACE); |
2330 if (!maybe_result->ToObject(&result)) return maybe_result; | 2328 if (!allocation.To(&result)) return allocation; |
2331 | 2329 |
2332 // Map::cast cannot be used due to uninitialized map field. | 2330 // Map::cast cannot be used due to uninitialized map field. |
2333 reinterpret_cast<Map*>(result)->set_map(raw_unchecked_meta_map()); | 2331 reinterpret_cast<Map*>(result)->set_map(raw_unchecked_meta_map()); |
2334 reinterpret_cast<Map*>(result)->set_instance_type(instance_type); | 2332 reinterpret_cast<Map*>(result)->set_instance_type(instance_type); |
2335 reinterpret_cast<Map*>(result)->set_instance_size(instance_size); | 2333 reinterpret_cast<Map*>(result)->set_instance_size(instance_size); |
2336 reinterpret_cast<Map*>(result)->set_visitor_id( | 2334 reinterpret_cast<Map*>(result)->set_visitor_id( |
2337 StaticVisitorBase::GetVisitorId(instance_type, instance_size)); | 2335 StaticVisitorBase::GetVisitorId(instance_type, instance_size)); |
2338 reinterpret_cast<Map*>(result)->set_inobject_properties(0); | 2336 reinterpret_cast<Map*>(result)->set_inobject_properties(0); |
2339 reinterpret_cast<Map*>(result)->set_pre_allocated_property_fields(0); | 2337 reinterpret_cast<Map*>(result)->set_pre_allocated_property_fields(0); |
2340 reinterpret_cast<Map*>(result)->set_unused_property_fields(0); | 2338 reinterpret_cast<Map*>(result)->set_unused_property_fields(0); |
2341 reinterpret_cast<Map*>(result)->set_bit_field(0); | 2339 reinterpret_cast<Map*>(result)->set_bit_field(0); |
2342 reinterpret_cast<Map*>(result)->set_bit_field2(0); | 2340 reinterpret_cast<Map*>(result)->set_bit_field2(0); |
2343 int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) | | 2341 int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) | |
2344 Map::OwnsDescriptors::encode(true); | 2342 Map::OwnsDescriptors::encode(true); |
2345 reinterpret_cast<Map*>(result)->set_bit_field3(bit_field3); | 2343 reinterpret_cast<Map*>(result)->set_bit_field3(bit_field3); |
2346 return result; | 2344 return result; |
2347 } | 2345 } |
2348 | 2346 |
2349 | 2347 |
2350 MaybeObject* Heap::AllocateMap(InstanceType instance_type, | 2348 AllocationResult Heap::AllocateMap(InstanceType instance_type, |
2351 int instance_size, | 2349 int instance_size, |
2352 ElementsKind elements_kind) { | 2350 ElementsKind elements_kind) { |
2353 Object* result; | 2351 HeapObject* result; |
2354 MaybeObject* maybe_result = AllocateRaw(Map::kSize, MAP_SPACE, MAP_SPACE); | 2352 AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE, MAP_SPACE); |
2355 if (!maybe_result->To(&result)) return maybe_result; | 2353 if (!allocation.To(&result)) return allocation; |
2356 | 2354 |
2357 Map* map = reinterpret_cast<Map*>(result); | 2355 result->set_map_no_write_barrier(meta_map()); |
2358 map->set_map_no_write_barrier(meta_map()); | 2356 Map* map = Map::cast(result); |
2359 map->set_instance_type(instance_type); | 2357 map->set_instance_type(instance_type); |
2360 map->set_visitor_id( | 2358 map->set_visitor_id( |
2361 StaticVisitorBase::GetVisitorId(instance_type, instance_size)); | 2359 StaticVisitorBase::GetVisitorId(instance_type, instance_size)); |
2362 map->set_prototype(null_value(), SKIP_WRITE_BARRIER); | 2360 map->set_prototype(null_value(), SKIP_WRITE_BARRIER); |
2363 map->set_constructor(null_value(), SKIP_WRITE_BARRIER); | 2361 map->set_constructor(null_value(), SKIP_WRITE_BARRIER); |
2364 map->set_instance_size(instance_size); | 2362 map->set_instance_size(instance_size); |
2365 map->set_inobject_properties(0); | 2363 map->set_inobject_properties(0); |
2366 map->set_pre_allocated_property_fields(0); | 2364 map->set_pre_allocated_property_fields(0); |
2367 map->set_code_cache(empty_fixed_array(), SKIP_WRITE_BARRIER); | 2365 map->set_code_cache(empty_fixed_array(), SKIP_WRITE_BARRIER); |
2368 map->set_dependent_code(DependentCode::cast(empty_fixed_array()), | 2366 map->set_dependent_code(DependentCode::cast(empty_fixed_array()), |
2369 SKIP_WRITE_BARRIER); | 2367 SKIP_WRITE_BARRIER); |
2370 map->init_back_pointer(undefined_value()); | 2368 map->init_back_pointer(undefined_value()); |
2371 map->set_unused_property_fields(0); | 2369 map->set_unused_property_fields(0); |
2372 map->set_instance_descriptors(empty_descriptor_array()); | 2370 map->set_instance_descriptors(empty_descriptor_array()); |
2373 map->set_bit_field(0); | 2371 map->set_bit_field(0); |
2374 map->set_bit_field2(1 << Map::kIsExtensible); | 2372 map->set_bit_field2(1 << Map::kIsExtensible); |
2375 int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) | | 2373 int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) | |
2376 Map::OwnsDescriptors::encode(true); | 2374 Map::OwnsDescriptors::encode(true); |
2377 map->set_bit_field3(bit_field3); | 2375 map->set_bit_field3(bit_field3); |
2378 map->set_elements_kind(elements_kind); | 2376 map->set_elements_kind(elements_kind); |
2379 | 2377 |
2380 return map; | 2378 return map; |
2381 } | 2379 } |
2382 | 2380 |
2383 | 2381 |
2384 MaybeObject* Heap::AllocateFillerObject(int size, | 2382 AllocationResult Heap::AllocateFillerObject(int size, |
2385 bool double_align, | 2383 bool double_align, |
2386 AllocationSpace space) { | 2384 AllocationSpace space) { |
2387 HeapObject* allocation; | 2385 HeapObject* obj; |
2388 { MaybeObject* maybe_allocation = AllocateRaw(size, space, space); | 2386 { AllocationResult allocation = AllocateRaw(size, space, space); |
2389 if (!maybe_allocation->To(&allocation)) return maybe_allocation; | 2387 if (!allocation.To(&obj)) return allocation; |
2390 } | 2388 } |
2391 #ifdef DEBUG | 2389 #ifdef DEBUG |
2392 MemoryChunk* chunk = MemoryChunk::FromAddress(allocation->address()); | 2390 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); |
2393 ASSERT(chunk->owner()->identity() == space); | 2391 ASSERT(chunk->owner()->identity() == space); |
2394 #endif | 2392 #endif |
2395 CreateFillerObjectAt(allocation->address(), size); | 2393 CreateFillerObjectAt(obj->address(), size); |
2396 return allocation; | 2394 return obj; |
2397 } | 2395 } |
2398 | 2396 |
2399 | 2397 |
2400 const Heap::StringTypeTable Heap::string_type_table[] = { | 2398 const Heap::StringTypeTable Heap::string_type_table[] = { |
2401 #define STRING_TYPE_ELEMENT(type, size, name, camel_name) \ | 2399 #define STRING_TYPE_ELEMENT(type, size, name, camel_name) \ |
2402 {type, size, k##camel_name##MapRootIndex}, | 2400 {type, size, k##camel_name##MapRootIndex}, |
2403 STRING_TYPE_LIST(STRING_TYPE_ELEMENT) | 2401 STRING_TYPE_LIST(STRING_TYPE_ELEMENT) |
2404 #undef STRING_TYPE_ELEMENT | 2402 #undef STRING_TYPE_ELEMENT |
2405 }; | 2403 }; |
2406 | 2404 |
2407 | 2405 |
2408 const Heap::ConstantStringTable Heap::constant_string_table[] = { | 2406 const Heap::ConstantStringTable Heap::constant_string_table[] = { |
2409 #define CONSTANT_STRING_ELEMENT(name, contents) \ | 2407 #define CONSTANT_STRING_ELEMENT(name, contents) \ |
2410 {contents, k##name##RootIndex}, | 2408 {contents, k##name##RootIndex}, |
2411 INTERNALIZED_STRING_LIST(CONSTANT_STRING_ELEMENT) | 2409 INTERNALIZED_STRING_LIST(CONSTANT_STRING_ELEMENT) |
2412 #undef CONSTANT_STRING_ELEMENT | 2410 #undef CONSTANT_STRING_ELEMENT |
2413 }; | 2411 }; |
2414 | 2412 |
2415 | 2413 |
2416 const Heap::StructTable Heap::struct_table[] = { | 2414 const Heap::StructTable Heap::struct_table[] = { |
2417 #define STRUCT_TABLE_ELEMENT(NAME, Name, name) \ | 2415 #define STRUCT_TABLE_ELEMENT(NAME, Name, name) \ |
2418 { NAME##_TYPE, Name::kSize, k##Name##MapRootIndex }, | 2416 { NAME##_TYPE, Name::kSize, k##Name##MapRootIndex }, |
2419 STRUCT_LIST(STRUCT_TABLE_ELEMENT) | 2417 STRUCT_LIST(STRUCT_TABLE_ELEMENT) |
2420 #undef STRUCT_TABLE_ELEMENT | 2418 #undef STRUCT_TABLE_ELEMENT |
2421 }; | 2419 }; |
2422 | 2420 |
2423 | 2421 |
2424 bool Heap::CreateInitialMaps() { | 2422 bool Heap::CreateInitialMaps() { |
2425 Object* obj; | 2423 HeapObject* obj; |
Hannes Payer (out of office)
2014/04/30 07:07:07
obj -> object; c++ google styleguide "Function nam
| |
2426 { MaybeObject* maybe_obj = AllocatePartialMap(MAP_TYPE, Map::kSize); | 2424 { AllocationResult allocation = AllocatePartialMap(MAP_TYPE, Map::kSize); |
2427 if (!maybe_obj->ToObject(&obj)) return false; | 2425 if (!allocation.To(&obj)) return false; |
2428 } | 2426 } |
2429 // Map::cast cannot be used due to uninitialized map field. | 2427 // Map::cast cannot be used due to uninitialized map field. |
2430 Map* new_meta_map = reinterpret_cast<Map*>(obj); | 2428 Map* new_meta_map = reinterpret_cast<Map*>(obj); |
2431 set_meta_map(new_meta_map); | 2429 set_meta_map(new_meta_map); |
2432 new_meta_map->set_map(new_meta_map); | 2430 new_meta_map->set_map(new_meta_map); |
2433 | 2431 |
2434 { // Partial map allocation | 2432 { // Partial map allocation |
2435 #define ALLOCATE_PARTIAL_MAP(instance_type, size, field_name) \ | 2433 #define ALLOCATE_PARTIAL_MAP(instance_type, size, field_name) \ |
2436 { Map* map; \ | 2434 { Map* map; \ |
2437 if (!AllocatePartialMap((instance_type), (size))->To(&map)) return false;\ | 2435 if (!AllocatePartialMap((instance_type), (size)).To(&map)) return false; \ |
2438 set_##field_name##_map(map); \ | 2436 set_##field_name##_map(map); \ |
2439 } | 2437 } |
2440 | 2438 |
2441 ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel, fixed_array); | 2439 ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel, fixed_array); |
2442 ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, undefined); | 2440 ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, undefined); |
2443 ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, null); | 2441 ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, null); |
2444 ALLOCATE_PARTIAL_MAP(CONSTANT_POOL_ARRAY_TYPE, kVariableSizeSentinel, | 2442 ALLOCATE_PARTIAL_MAP(CONSTANT_POOL_ARRAY_TYPE, kVariableSizeSentinel, |
2445 constant_pool_array); | 2443 constant_pool_array); |
2446 | 2444 |
2447 #undef ALLOCATE_PARTIAL_MAP | 2445 #undef ALLOCATE_PARTIAL_MAP |
2448 } | 2446 } |
2449 | 2447 |
2450 // Allocate the empty array. | 2448 // Allocate the empty array. |
2451 { MaybeObject* maybe_obj = AllocateEmptyFixedArray(); | 2449 { AllocationResult allocation = AllocateEmptyFixedArray(); |
2452 if (!maybe_obj->ToObject(&obj)) return false; | 2450 if (!allocation.To(&obj)) return false; |
2453 } | 2451 } |
2454 set_empty_fixed_array(FixedArray::cast(obj)); | 2452 set_empty_fixed_array(FixedArray::cast(obj)); |
2455 | 2453 |
2456 { MaybeObject* maybe_obj = Allocate(null_map(), OLD_POINTER_SPACE); | 2454 { AllocationResult allocation = Allocate(null_map(), OLD_POINTER_SPACE); |
2457 if (!maybe_obj->ToObject(&obj)) return false; | 2455 if (!allocation.To(&obj)) return false; |
2458 } | 2456 } |
2459 set_null_value(Oddball::cast(obj)); | 2457 set_null_value(Oddball::cast(obj)); |
2460 Oddball::cast(obj)->set_kind(Oddball::kNull); | 2458 Oddball::cast(obj)->set_kind(Oddball::kNull); |
2461 | 2459 |
2462 { MaybeObject* maybe_obj = Allocate(undefined_map(), OLD_POINTER_SPACE); | 2460 { AllocationResult allocation = Allocate(undefined_map(), OLD_POINTER_SPACE); |
2463 if (!maybe_obj->ToObject(&obj)) return false; | 2461 if (!allocation.To(&obj)) return false; |
2464 } | 2462 } |
2465 set_undefined_value(Oddball::cast(obj)); | 2463 set_undefined_value(Oddball::cast(obj)); |
2466 Oddball::cast(obj)->set_kind(Oddball::kUndefined); | 2464 Oddball::cast(obj)->set_kind(Oddball::kUndefined); |
2467 ASSERT(!InNewSpace(undefined_value())); | 2465 ASSERT(!InNewSpace(undefined_value())); |
2468 | 2466 |
2469 // Set preliminary exception sentinel value before actually initializing it. | 2467 // Set preliminary exception sentinel value before actually initializing it. |
2470 set_exception(null_value()); | 2468 set_exception(null_value()); |
2471 | 2469 |
2472 // Allocate the empty descriptor array. | 2470 // Allocate the empty descriptor array. |
2473 { MaybeObject* maybe_obj = AllocateEmptyFixedArray(); | 2471 { AllocationResult allocation = AllocateEmptyFixedArray(); |
2474 if (!maybe_obj->ToObject(&obj)) return false; | 2472 if (!allocation.To(&obj)) return false; |
2475 } | 2473 } |
2476 set_empty_descriptor_array(DescriptorArray::cast(obj)); | 2474 set_empty_descriptor_array(DescriptorArray::cast(obj)); |
2477 | 2475 |
2478 // Allocate the constant pool array. | 2476 // Allocate the constant pool array. |
2479 { MaybeObject* maybe_obj = AllocateEmptyConstantPoolArray(); | 2477 { AllocationResult allocation = AllocateEmptyConstantPoolArray(); |
2480 if (!maybe_obj->ToObject(&obj)) return false; | 2478 if (!allocation.To(&obj)) return false; |
2481 } | 2479 } |
2482 set_empty_constant_pool_array(ConstantPoolArray::cast(obj)); | 2480 set_empty_constant_pool_array(ConstantPoolArray::cast(obj)); |
2483 | 2481 |
2484 // Fix the instance_descriptors for the existing maps. | 2482 // Fix the instance_descriptors for the existing maps. |
2485 meta_map()->set_code_cache(empty_fixed_array()); | 2483 meta_map()->set_code_cache(empty_fixed_array()); |
2486 meta_map()->set_dependent_code(DependentCode::cast(empty_fixed_array())); | 2484 meta_map()->set_dependent_code(DependentCode::cast(empty_fixed_array())); |
2487 meta_map()->init_back_pointer(undefined_value()); | 2485 meta_map()->init_back_pointer(undefined_value()); |
2488 meta_map()->set_instance_descriptors(empty_descriptor_array()); | 2486 meta_map()->set_instance_descriptors(empty_descriptor_array()); |
2489 | 2487 |
2490 fixed_array_map()->set_code_cache(empty_fixed_array()); | 2488 fixed_array_map()->set_code_cache(empty_fixed_array()); |
(...skipping 30 matching lines...) Expand all Loading... | |
2521 | 2519 |
2522 null_map()->set_prototype(null_value()); | 2520 null_map()->set_prototype(null_value()); |
2523 null_map()->set_constructor(null_value()); | 2521 null_map()->set_constructor(null_value()); |
2524 | 2522 |
2525 constant_pool_array_map()->set_prototype(null_value()); | 2523 constant_pool_array_map()->set_prototype(null_value()); |
2526 constant_pool_array_map()->set_constructor(null_value()); | 2524 constant_pool_array_map()->set_constructor(null_value()); |
2527 | 2525 |
2528 { // Map allocation | 2526 { // Map allocation |
2529 #define ALLOCATE_MAP(instance_type, size, field_name) \ | 2527 #define ALLOCATE_MAP(instance_type, size, field_name) \ |
2530 { Map* map; \ | 2528 { Map* map; \ |
2531 if (!AllocateMap((instance_type), size)->To(&map)) return false; \ | 2529 if (!AllocateMap((instance_type), size).To(&map)) return false; \ |
2532 set_##field_name##_map(map); \ | 2530 set_##field_name##_map(map); \ |
2533 } | 2531 } |
2534 | 2532 |
2535 #define ALLOCATE_VARSIZE_MAP(instance_type, field_name) \ | 2533 #define ALLOCATE_VARSIZE_MAP(instance_type, field_name) \ |
2536 ALLOCATE_MAP(instance_type, kVariableSizeSentinel, field_name) | 2534 ALLOCATE_MAP(instance_type, kVariableSizeSentinel, field_name) |
2537 | 2535 |
2538 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, fixed_cow_array) | 2536 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, fixed_cow_array) |
2539 ASSERT(fixed_array_map() != fixed_cow_array_map()); | 2537 ASSERT(fixed_array_map() != fixed_cow_array_map()); |
2540 | 2538 |
2541 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, scope_info) | 2539 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, scope_info) |
2542 ALLOCATE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number) | 2540 ALLOCATE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number) |
2543 ALLOCATE_MAP(SYMBOL_TYPE, Symbol::kSize, symbol) | 2541 ALLOCATE_MAP(SYMBOL_TYPE, Symbol::kSize, symbol) |
2544 ALLOCATE_MAP(FOREIGN_TYPE, Foreign::kSize, foreign) | 2542 ALLOCATE_MAP(FOREIGN_TYPE, Foreign::kSize, foreign) |
2545 | 2543 |
2546 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, the_hole); | 2544 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, the_hole); |
2547 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, boolean); | 2545 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, boolean); |
2548 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, uninitialized); | 2546 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, uninitialized); |
2549 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, arguments_marker); | 2547 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, arguments_marker); |
2550 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, no_interceptor_result_sentinel); | 2548 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, no_interceptor_result_sentinel); |
2551 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, exception); | 2549 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, exception); |
2552 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, termination_exception); | 2550 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, termination_exception); |
2553 | 2551 |
2554 for (unsigned i = 0; i < ARRAY_SIZE(string_type_table); i++) { | 2552 for (unsigned i = 0; i < ARRAY_SIZE(string_type_table); i++) { |
2555 const StringTypeTable& entry = string_type_table[i]; | 2553 const StringTypeTable& entry = string_type_table[i]; |
2556 { MaybeObject* maybe_obj = AllocateMap(entry.type, entry.size); | 2554 { AllocationResult allocation = AllocateMap(entry.type, entry.size); |
2557 if (!maybe_obj->ToObject(&obj)) return false; | 2555 if (!allocation.To(&obj)) return false; |
2558 } | 2556 } |
2559 // Mark cons string maps as unstable, because their objects can change | 2557 // Mark cons string maps as unstable, because their objects can change |
2560 // maps during GC. | 2558 // maps during GC. |
2561 Map* map = Map::cast(obj); | 2559 Map* map = Map::cast(obj); |
2562 if (StringShape(entry.type).IsCons()) map->mark_unstable(); | 2560 if (StringShape(entry.type).IsCons()) map->mark_unstable(); |
2563 roots_[entry.index] = map; | 2561 roots_[entry.index] = map; |
2564 } | 2562 } |
2565 | 2563 |
2566 ALLOCATE_VARSIZE_MAP(STRING_TYPE, undetectable_string) | 2564 ALLOCATE_VARSIZE_MAP(STRING_TYPE, undetectable_string) |
2567 undetectable_string_map()->set_is_undetectable(); | 2565 undetectable_string_map()->set_is_undetectable(); |
(...skipping 25 matching lines...) Expand all Loading... | |
2593 | 2591 |
2594 ALLOCATE_MAP(CELL_TYPE, Cell::kSize, cell) | 2592 ALLOCATE_MAP(CELL_TYPE, Cell::kSize, cell) |
2595 ALLOCATE_MAP(PROPERTY_CELL_TYPE, PropertyCell::kSize, global_property_cell) | 2593 ALLOCATE_MAP(PROPERTY_CELL_TYPE, PropertyCell::kSize, global_property_cell) |
2596 ALLOCATE_MAP(FILLER_TYPE, kPointerSize, one_pointer_filler) | 2594 ALLOCATE_MAP(FILLER_TYPE, kPointerSize, one_pointer_filler) |
2597 ALLOCATE_MAP(FILLER_TYPE, 2 * kPointerSize, two_pointer_filler) | 2595 ALLOCATE_MAP(FILLER_TYPE, 2 * kPointerSize, two_pointer_filler) |
2598 | 2596 |
2599 | 2597 |
2600 for (unsigned i = 0; i < ARRAY_SIZE(struct_table); i++) { | 2598 for (unsigned i = 0; i < ARRAY_SIZE(struct_table); i++) { |
2601 const StructTable& entry = struct_table[i]; | 2599 const StructTable& entry = struct_table[i]; |
2602 Map* map; | 2600 Map* map; |
2603 if (!AllocateMap(entry.type, entry.size)->To(&map)) | 2601 if (!AllocateMap(entry.type, entry.size).To(&map)) |
2604 return false; | 2602 return false; |
2605 roots_[entry.index] = map; | 2603 roots_[entry.index] = map; |
2606 } | 2604 } |
2607 | 2605 |
2608 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, hash_table) | 2606 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, hash_table) |
2609 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, ordered_hash_table) | 2607 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, ordered_hash_table) |
2610 | 2608 |
2611 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, function_context) | 2609 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, function_context) |
2612 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, catch_context) | 2610 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, catch_context) |
2613 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, with_context) | 2611 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, with_context) |
(...skipping 13 matching lines...) Expand all Loading... | |
2627 message_object) | 2625 message_object) |
2628 ALLOCATE_MAP(JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize, | 2626 ALLOCATE_MAP(JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize, |
2629 external) | 2627 external) |
2630 external_map()->set_is_extensible(false); | 2628 external_map()->set_is_extensible(false); |
2631 #undef ALLOCATE_VARSIZE_MAP | 2629 #undef ALLOCATE_VARSIZE_MAP |
2632 #undef ALLOCATE_MAP | 2630 #undef ALLOCATE_MAP |
2633 } | 2631 } |
2634 | 2632 |
2635 { // Empty arrays | 2633 { // Empty arrays |
2636 { ByteArray* byte_array; | 2634 { ByteArray* byte_array; |
2637 if (!AllocateByteArray(0, TENURED)->To(&byte_array)) return false; | 2635 if (!AllocateByteArray(0, TENURED).To(&byte_array)) return false; |
2638 set_empty_byte_array(byte_array); | 2636 set_empty_byte_array(byte_array); |
2639 } | 2637 } |
2640 | 2638 |
2641 #define ALLOCATE_EMPTY_EXTERNAL_ARRAY(Type, type, TYPE, ctype, size) \ | 2639 #define ALLOCATE_EMPTY_EXTERNAL_ARRAY(Type, type, TYPE, ctype, size) \ |
2642 { ExternalArray* obj; \ | 2640 { ExternalArray* obj; \ |
2643 if (!AllocateEmptyExternalArray(kExternal##Type##Array)->To(&obj)) \ | 2641 if (!AllocateEmptyExternalArray(kExternal##Type##Array).To(&obj)) \ |
2644 return false; \ | 2642 return false; \ |
2645 set_empty_external_##type##_array(obj); \ | 2643 set_empty_external_##type##_array(obj); \ |
2646 } | 2644 } |
2647 | 2645 |
2648 TYPED_ARRAYS(ALLOCATE_EMPTY_EXTERNAL_ARRAY) | 2646 TYPED_ARRAYS(ALLOCATE_EMPTY_EXTERNAL_ARRAY) |
2649 #undef ALLOCATE_EMPTY_EXTERNAL_ARRAY | 2647 #undef ALLOCATE_EMPTY_EXTERNAL_ARRAY |
2650 | 2648 |
2651 #define ALLOCATE_EMPTY_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \ | 2649 #define ALLOCATE_EMPTY_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \ |
2652 { FixedTypedArrayBase* obj; \ | 2650 { FixedTypedArrayBase* obj; \ |
2653 if (!AllocateEmptyFixedTypedArray(kExternal##Type##Array)->To(&obj)) \ | 2651 if (!AllocateEmptyFixedTypedArray(kExternal##Type##Array).To(&obj)) \ |
2654 return false; \ | 2652 return false; \ |
2655 set_empty_fixed_##type##_array(obj); \ | 2653 set_empty_fixed_##type##_array(obj); \ |
2656 } | 2654 } |
2657 | 2655 |
2658 TYPED_ARRAYS(ALLOCATE_EMPTY_FIXED_TYPED_ARRAY) | 2656 TYPED_ARRAYS(ALLOCATE_EMPTY_FIXED_TYPED_ARRAY) |
2659 #undef ALLOCATE_EMPTY_FIXED_TYPED_ARRAY | 2657 #undef ALLOCATE_EMPTY_FIXED_TYPED_ARRAY |
2660 } | 2658 } |
2661 ASSERT(!InNewSpace(empty_fixed_array())); | 2659 ASSERT(!InNewSpace(empty_fixed_array())); |
2662 return true; | 2660 return true; |
2663 } | 2661 } |
2664 | 2662 |
2665 | 2663 |
2666 MaybeObject* Heap::AllocateHeapNumber(double value, PretenureFlag pretenure) { | 2664 AllocationResult Heap::AllocateHeapNumber(double value, |
2665 PretenureFlag pretenure) { | |
2667 // Statically ensure that it is safe to allocate heap numbers in paged | 2666 // Statically ensure that it is safe to allocate heap numbers in paged |
2668 // spaces. | 2667 // spaces. |
2669 int size = HeapNumber::kSize; | 2668 int size = HeapNumber::kSize; |
2670 STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxRegularHeapObjectSize); | 2669 STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxRegularHeapObjectSize); |
2671 | 2670 |
2672 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); | 2671 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); |
2673 | 2672 |
2674 Object* result; | 2673 HeapObject* result; |
2675 { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE); | 2674 { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); |
2676 if (!maybe_result->ToObject(&result)) return maybe_result; | 2675 if (!allocation.To(&result)) return allocation; |
2677 } | 2676 } |
2678 | 2677 |
2679 HeapObject::cast(result)->set_map_no_write_barrier(heap_number_map()); | 2678 result->set_map_no_write_barrier(heap_number_map()); |
2680 HeapNumber::cast(result)->set_value(value); | 2679 HeapNumber::cast(result)->set_value(value); |
2681 return result; | 2680 return result; |
2682 } | 2681 } |
2683 | 2682 |
2684 | 2683 |
2685 MaybeObject* Heap::AllocateCell(Object* value) { | 2684 AllocationResult Heap::AllocateCell(Object* value) { |
2686 int size = Cell::kSize; | 2685 int size = Cell::kSize; |
2687 STATIC_ASSERT(Cell::kSize <= Page::kMaxRegularHeapObjectSize); | 2686 STATIC_ASSERT(Cell::kSize <= Page::kMaxRegularHeapObjectSize); |
2688 | 2687 |
2689 Object* result; | 2688 HeapObject* result; |
2690 { MaybeObject* maybe_result = AllocateRaw(size, CELL_SPACE, CELL_SPACE); | 2689 { AllocationResult allocation = AllocateRaw(size, CELL_SPACE, CELL_SPACE); |
2691 if (!maybe_result->ToObject(&result)) return maybe_result; | 2690 if (!allocation.To(&result)) return allocation; |
2692 } | 2691 } |
2693 HeapObject::cast(result)->set_map_no_write_barrier(cell_map()); | 2692 result->set_map_no_write_barrier(cell_map()); |
2694 Cell::cast(result)->set_value(value); | 2693 Cell::cast(result)->set_value(value); |
2695 return result; | 2694 return result; |
2696 } | 2695 } |
2697 | 2696 |
2698 | 2697 |
2699 MaybeObject* Heap::AllocatePropertyCell() { | 2698 AllocationResult Heap::AllocatePropertyCell() { |
2700 int size = PropertyCell::kSize; | 2699 int size = PropertyCell::kSize; |
2701 STATIC_ASSERT(PropertyCell::kSize <= Page::kMaxRegularHeapObjectSize); | 2700 STATIC_ASSERT(PropertyCell::kSize <= Page::kMaxRegularHeapObjectSize); |
2702 | 2701 |
2703 Object* result; | 2702 HeapObject* result; |
2704 MaybeObject* maybe_result = | 2703 AllocationResult allocation = |
2705 AllocateRaw(size, PROPERTY_CELL_SPACE, PROPERTY_CELL_SPACE); | 2704 AllocateRaw(size, PROPERTY_CELL_SPACE, PROPERTY_CELL_SPACE); |
2706 if (!maybe_result->ToObject(&result)) return maybe_result; | 2705 if (!allocation.To(&result)) return allocation; |
2707 | 2706 |
2708 HeapObject::cast(result)->set_map_no_write_barrier( | 2707 result->set_map_no_write_barrier(global_property_cell_map()); |
2709 global_property_cell_map()); | |
2710 PropertyCell* cell = PropertyCell::cast(result); | 2708 PropertyCell* cell = PropertyCell::cast(result); |
2711 cell->set_dependent_code(DependentCode::cast(empty_fixed_array()), | 2709 cell->set_dependent_code(DependentCode::cast(empty_fixed_array()), |
2712 SKIP_WRITE_BARRIER); | 2710 SKIP_WRITE_BARRIER); |
2713 cell->set_value(the_hole_value()); | 2711 cell->set_value(the_hole_value()); |
2714 cell->set_type(HeapType::None()); | 2712 cell->set_type(HeapType::None()); |
2715 return result; | 2713 return result; |
2716 } | 2714 } |
2717 | 2715 |
2718 | 2716 |
2719 void Heap::CreateApiObjects() { | 2717 void Heap::CreateApiObjects() { |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3233 roots_[RootIndexForEmptyExternalArray(map->elements_kind())]); | 3231 roots_[RootIndexForEmptyExternalArray(map->elements_kind())]); |
3234 } | 3232 } |
3235 | 3233 |
3236 | 3234 |
3237 FixedTypedArrayBase* Heap::EmptyFixedTypedArrayForMap(Map* map) { | 3235 FixedTypedArrayBase* Heap::EmptyFixedTypedArrayForMap(Map* map) { |
3238 return FixedTypedArrayBase::cast( | 3236 return FixedTypedArrayBase::cast( |
3239 roots_[RootIndexForEmptyFixedTypedArray(map->elements_kind())]); | 3237 roots_[RootIndexForEmptyFixedTypedArray(map->elements_kind())]); |
3240 } | 3238 } |
3241 | 3239 |
3242 | 3240 |
3243 MaybeObject* Heap::AllocateForeign(Address address, PretenureFlag pretenure) { | 3241 AllocationResult Heap::AllocateForeign(Address address, |
3242 PretenureFlag pretenure) { | |
3244 // Statically ensure that it is safe to allocate foreigns in paged spaces. | 3243 // Statically ensure that it is safe to allocate foreigns in paged spaces. |
3245 STATIC_ASSERT(Foreign::kSize <= Page::kMaxRegularHeapObjectSize); | 3244 STATIC_ASSERT(Foreign::kSize <= Page::kMaxRegularHeapObjectSize); |
3246 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; | 3245 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
3247 Foreign* result; | 3246 Foreign* result; |
3248 MaybeObject* maybe_result = Allocate(foreign_map(), space); | 3247 AllocationResult allocation = Allocate(foreign_map(), space); |
3249 if (!maybe_result->To(&result)) return maybe_result; | 3248 if (!allocation.To(&result)) return allocation; |
3250 result->set_foreign_address(address); | 3249 result->set_foreign_address(address); |
3251 return result; | 3250 return result; |
3252 } | 3251 } |
3253 | 3252 |
3254 | 3253 |
3255 MaybeObject* Heap::AllocateByteArray(int length, PretenureFlag pretenure) { | 3254 AllocationResult Heap::AllocateByteArray(int length, PretenureFlag pretenure) { |
3256 if (length < 0 || length > ByteArray::kMaxLength) { | 3255 if (length < 0 || length > ByteArray::kMaxLength) { |
3257 v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true); | 3256 v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true); |
3258 } | 3257 } |
3259 int size = ByteArray::SizeFor(length); | 3258 int size = ByteArray::SizeFor(length); |
3260 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); | 3259 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); |
3261 Object* result; | 3260 HeapObject* result; |
3262 { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE); | 3261 { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); |
3263 if (!maybe_result->ToObject(&result)) return maybe_result; | 3262 if (!allocation.To(&result)) return allocation; |
3264 } | 3263 } |
3265 | 3264 |
3266 reinterpret_cast<ByteArray*>(result)->set_map_no_write_barrier( | 3265 result->set_map_no_write_barrier(byte_array_map()); |
3267 byte_array_map()); | 3266 ByteArray::cast(result)->set_length(length); |
3268 reinterpret_cast<ByteArray*>(result)->set_length(length); | |
3269 return result; | 3267 return result; |
3270 } | 3268 } |
3271 | 3269 |
3272 | 3270 |
3273 void Heap::CreateFillerObjectAt(Address addr, int size) { | 3271 void Heap::CreateFillerObjectAt(Address addr, int size) { |
3274 if (size == 0) return; | 3272 if (size == 0) return; |
3275 HeapObject* filler = HeapObject::FromAddress(addr); | 3273 HeapObject* filler = HeapObject::FromAddress(addr); |
3276 if (size == kPointerSize) { | 3274 if (size == kPointerSize) { |
3277 filler->set_map_no_write_barrier(one_pointer_filler_map()); | 3275 filler->set_map_no_write_barrier(one_pointer_filler_map()); |
3278 } else if (size == 2 * kPointerSize) { | 3276 } else if (size == 2 * kPointerSize) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3311 Marking::IsBlack(Marking::MarkBitFrom(address))) { | 3309 Marking::IsBlack(Marking::MarkBitFrom(address))) { |
3312 if (mode == FROM_GC) { | 3310 if (mode == FROM_GC) { |
3313 MemoryChunk::IncrementLiveBytesFromGC(address, by); | 3311 MemoryChunk::IncrementLiveBytesFromGC(address, by); |
3314 } else { | 3312 } else { |
3315 MemoryChunk::IncrementLiveBytesFromMutator(address, by); | 3313 MemoryChunk::IncrementLiveBytesFromMutator(address, by); |
3316 } | 3314 } |
3317 } | 3315 } |
3318 } | 3316 } |
3319 | 3317 |
3320 | 3318 |
3321 MaybeObject* Heap::AllocateExternalArray(int length, | 3319 AllocationResult Heap::AllocateExternalArray(int length, |
3322 ExternalArrayType array_type, | 3320 ExternalArrayType array_type, |
3323 void* external_pointer, | 3321 void* external_pointer, |
3324 PretenureFlag pretenure) { | 3322 PretenureFlag pretenure) { |
3325 int size = ExternalArray::kAlignedSize; | 3323 int size = ExternalArray::kAlignedSize; |
3326 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); | 3324 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); |
3327 Object* result; | 3325 HeapObject* result; |
3328 { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE); | 3326 { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); |
3329 if (!maybe_result->ToObject(&result)) return maybe_result; | 3327 if (!allocation.To(&result)) return allocation; |
3330 } | 3328 } |
3331 | 3329 |
3332 reinterpret_cast<ExternalArray*>(result)->set_map_no_write_barrier( | 3330 result->set_map_no_write_barrier( |
3333 MapForExternalArrayType(array_type)); | 3331 MapForExternalArrayType(array_type)); |
3334 reinterpret_cast<ExternalArray*>(result)->set_length(length); | 3332 ExternalArray::cast(result)->set_length(length); |
3335 reinterpret_cast<ExternalArray*>(result)->set_external_pointer( | 3333 ExternalArray::cast(result)->set_external_pointer(external_pointer); |
3336 external_pointer); | |
3337 | |
3338 return result; | 3334 return result; |
3339 } | 3335 } |
3340 | 3336 |
3341 static void ForFixedTypedArray(ExternalArrayType array_type, | 3337 static void ForFixedTypedArray(ExternalArrayType array_type, |
3342 int* element_size, | 3338 int* element_size, |
3343 ElementsKind* element_kind) { | 3339 ElementsKind* element_kind) { |
3344 switch (array_type) { | 3340 switch (array_type) { |
3345 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 3341 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
3346 case kExternal##Type##Array: \ | 3342 case kExternal##Type##Array: \ |
3347 *element_size = size; \ | 3343 *element_size = size; \ |
3348 *element_kind = TYPE##_ELEMENTS; \ | 3344 *element_kind = TYPE##_ELEMENTS; \ |
3349 return; | 3345 return; |
3350 | 3346 |
3351 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 3347 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
3352 #undef TYPED_ARRAY_CASE | 3348 #undef TYPED_ARRAY_CASE |
3353 | 3349 |
3354 default: | 3350 default: |
3355 *element_size = 0; // Bogus | 3351 *element_size = 0; // Bogus |
3356 *element_kind = UINT8_ELEMENTS; // Bogus | 3352 *element_kind = UINT8_ELEMENTS; // Bogus |
3357 UNREACHABLE(); | 3353 UNREACHABLE(); |
3358 } | 3354 } |
3359 } | 3355 } |
3360 | 3356 |
3361 | 3357 |
3362 MaybeObject* Heap::AllocateFixedTypedArray(int length, | 3358 AllocationResult Heap::AllocateFixedTypedArray(int length, |
3363 ExternalArrayType array_type, | 3359 ExternalArrayType array_type, |
3364 PretenureFlag pretenure) { | 3360 PretenureFlag pretenure) { |
3365 int element_size; | 3361 int element_size; |
3366 ElementsKind elements_kind; | 3362 ElementsKind elements_kind; |
3367 ForFixedTypedArray(array_type, &element_size, &elements_kind); | 3363 ForFixedTypedArray(array_type, &element_size, &elements_kind); |
3368 int size = OBJECT_POINTER_ALIGN( | 3364 int size = OBJECT_POINTER_ALIGN( |
3369 length * element_size + FixedTypedArrayBase::kDataOffset); | 3365 length * element_size + FixedTypedArrayBase::kDataOffset); |
3370 #ifndef V8_HOST_ARCH_64_BIT | 3366 #ifndef V8_HOST_ARCH_64_BIT |
3371 if (array_type == kExternalFloat64Array) { | 3367 if (array_type == kExternalFloat64Array) { |
3372 size += kPointerSize; | 3368 size += kPointerSize; |
3373 } | 3369 } |
3374 #endif | 3370 #endif |
3375 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); | 3371 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); |
3376 | 3372 |
3377 HeapObject* object; | 3373 HeapObject* object; |
3378 MaybeObject* maybe_object = AllocateRaw(size, space, OLD_DATA_SPACE); | 3374 AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); |
3379 if (!maybe_object->To(&object)) return maybe_object; | 3375 if (!allocation.To(&object)) return allocation; |
3380 | 3376 |
3381 if (array_type == kExternalFloat64Array) { | 3377 if (array_type == kExternalFloat64Array) { |
3382 object = EnsureDoubleAligned(this, object, size); | 3378 object = EnsureDoubleAligned(this, object, size); |
3383 } | 3379 } |
3384 | 3380 |
3385 FixedTypedArrayBase* elements = | 3381 object->set_map(MapForFixedTypedArray(array_type)); |
3386 reinterpret_cast<FixedTypedArrayBase*>(object); | 3382 FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(object); |
3387 elements->set_map(MapForFixedTypedArray(array_type)); | |
3388 elements->set_length(length); | 3383 elements->set_length(length); |
3389 memset(elements->DataPtr(), 0, elements->DataSize()); | 3384 memset(elements->DataPtr(), 0, elements->DataSize()); |
3390 return elements; | 3385 return elements; |
3391 } | 3386 } |
3392 | 3387 |
3393 | 3388 |
3394 MaybeObject* Heap::AllocateCode(int object_size, | 3389 AllocationResult Heap::AllocateCode(int object_size, |
3395 bool immovable) { | 3390 bool immovable) { |
3396 ASSERT(IsAligned(static_cast<intptr_t>(object_size), kCodeAlignment)); | 3391 ASSERT(IsAligned(static_cast<intptr_t>(object_size), kCodeAlignment)); |
3397 MaybeObject* maybe_result; | 3392 AllocationResult allocation; |
3398 // Large code objects and code objects which should stay at a fixed address | 3393 // Large code objects and code objects which should stay at a fixed address |
3399 // are allocated in large object space. | 3394 // are allocated in large object space. |
3400 HeapObject* result; | 3395 HeapObject* result; |
3401 bool force_lo_space = object_size > code_space()->AreaSize(); | 3396 bool force_lo_space = object_size > code_space()->AreaSize(); |
3402 if (force_lo_space) { | 3397 if (force_lo_space) { |
3403 maybe_result = lo_space_->AllocateRaw(object_size, EXECUTABLE); | 3398 allocation = lo_space_->AllocateRaw(object_size, EXECUTABLE); |
3404 } else { | 3399 } else { |
3405 maybe_result = AllocateRaw(object_size, CODE_SPACE, CODE_SPACE); | 3400 allocation = AllocateRaw(object_size, CODE_SPACE, CODE_SPACE); |
3406 } | 3401 } |
3407 if (!maybe_result->To<HeapObject>(&result)) return maybe_result; | 3402 if (!allocation.To(&result)) return allocation; |
3408 | 3403 |
3409 if (immovable && !force_lo_space && | 3404 if (immovable && !force_lo_space && |
3410 // Objects on the first page of each space are never moved. | 3405 // Objects on the first page of each space are never moved. |
3411 !code_space_->FirstPage()->Contains(result->address())) { | 3406 !code_space_->FirstPage()->Contains(result->address())) { |
3412 // Discard the first code allocation, which was on a page where it could be | 3407 // Discard the first code allocation, which was on a page where it could be |
3413 // moved. | 3408 // moved. |
3414 CreateFillerObjectAt(result->address(), object_size); | 3409 CreateFillerObjectAt(result->address(), object_size); |
3415 maybe_result = lo_space_->AllocateRaw(object_size, EXECUTABLE); | 3410 allocation = lo_space_->AllocateRaw(object_size, EXECUTABLE); |
3416 if (!maybe_result->To<HeapObject>(&result)) return maybe_result; | 3411 if (!allocation.To(&result)) return allocation; |
3417 } | 3412 } |
3418 | 3413 |
3419 result->set_map_no_write_barrier(code_map()); | 3414 result->set_map_no_write_barrier(code_map()); |
3420 Code* code = Code::cast(result); | 3415 Code* code = Code::cast(result); |
3421 ASSERT(!isolate_->code_range()->exists() || | 3416 ASSERT(!isolate_->code_range()->exists() || |
3422 isolate_->code_range()->contains(code->address())); | 3417 isolate_->code_range()->contains(code->address())); |
3423 code->set_gc_metadata(Smi::FromInt(0)); | 3418 code->set_gc_metadata(Smi::FromInt(0)); |
3424 code->set_ic_age(global_ic_age_); | 3419 code->set_ic_age(global_ic_age_); |
3425 return code; | 3420 return code; |
3426 } | 3421 } |
3427 | 3422 |
3428 | 3423 |
3429 MaybeObject* Heap::CopyCode(Code* code) { | 3424 AllocationResult Heap::CopyCode(Code* code) { |
3430 MaybeObject* maybe_result; | 3425 AllocationResult allocation; |
3431 Object* new_constant_pool; | 3426 HeapObject* new_constant_pool; |
3432 if (FLAG_enable_ool_constant_pool && | 3427 if (FLAG_enable_ool_constant_pool && |
3433 code->constant_pool() != empty_constant_pool_array()) { | 3428 code->constant_pool() != empty_constant_pool_array()) { |
3434 // Copy the constant pool, since edits to the copied code may modify | 3429 // Copy the constant pool, since edits to the copied code may modify |
3435 // the constant pool. | 3430 // the constant pool. |
3436 maybe_result = CopyConstantPoolArray(code->constant_pool()); | 3431 allocation = CopyConstantPoolArray(code->constant_pool()); |
3437 if (!maybe_result->ToObject(&new_constant_pool)) return maybe_result; | 3432 if (!allocation.To(&new_constant_pool)) return allocation; |
3438 } else { | 3433 } else { |
3439 new_constant_pool = empty_constant_pool_array(); | 3434 new_constant_pool = empty_constant_pool_array(); |
3440 } | 3435 } |
3441 | 3436 |
3442 // Allocate an object the same size as the code object. | 3437 // Allocate an object the same size as the code object. |
3443 int obj_size = code->Size(); | 3438 int obj_size = code->Size(); |
3444 if (obj_size > code_space()->AreaSize()) { | 3439 if (obj_size > code_space()->AreaSize()) { |
3445 maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE); | 3440 allocation = lo_space_->AllocateRaw(obj_size, EXECUTABLE); |
3446 } else { | 3441 } else { |
3447 maybe_result = AllocateRaw(obj_size, CODE_SPACE, CODE_SPACE); | 3442 allocation = AllocateRaw(obj_size, CODE_SPACE, CODE_SPACE); |
3448 } | 3443 } |
3449 | 3444 |
3450 Object* result; | 3445 HeapObject* result; |
3451 if (!maybe_result->ToObject(&result)) return maybe_result; | 3446 if (!allocation.To(&result)) return allocation; |
3452 | 3447 |
3453 // Copy code object. | 3448 // Copy code object. |
3454 Address old_addr = code->address(); | 3449 Address old_addr = code->address(); |
3455 Address new_addr = reinterpret_cast<HeapObject*>(result)->address(); | 3450 Address new_addr = result->address(); |
3456 CopyBlock(new_addr, old_addr, obj_size); | 3451 CopyBlock(new_addr, old_addr, obj_size); |
3457 Code* new_code = Code::cast(result); | 3452 Code* new_code = Code::cast(result); |
3458 | 3453 |
3459 // Update the constant pool. | 3454 // Update the constant pool. |
3460 new_code->set_constant_pool(new_constant_pool); | 3455 new_code->set_constant_pool(new_constant_pool); |
3461 | 3456 |
3462 // Relocate the copy. | 3457 // Relocate the copy. |
3463 ASSERT(!isolate_->code_range()->exists() || | 3458 ASSERT(!isolate_->code_range()->exists() || |
3464 isolate_->code_range()->contains(code->address())); | 3459 isolate_->code_range()->contains(code->address())); |
3465 new_code->Relocate(new_addr - old_addr); | 3460 new_code->Relocate(new_addr - old_addr); |
3466 return new_code; | 3461 return new_code; |
3467 } | 3462 } |
3468 | 3463 |
3469 | 3464 |
3470 MaybeObject* Heap::CopyCode(Code* code, Vector<byte> reloc_info) { | 3465 AllocationResult Heap::CopyCode(Code* code, Vector<byte> reloc_info) { |
3471 // Allocate ByteArray and ConstantPoolArray before the Code object, so that we | 3466 // Allocate ByteArray and ConstantPoolArray before the Code object, so that we |
3472 // do not risk leaving uninitialized Code object (and breaking the heap). | 3467 // do not risk leaving uninitialized Code object (and breaking the heap). |
3473 Object* reloc_info_array; | 3468 ByteArray* reloc_info_array; |
3474 { MaybeObject* maybe_reloc_info_array = | 3469 { AllocationResult allocation = |
3475 AllocateByteArray(reloc_info.length(), TENURED); | 3470 AllocateByteArray(reloc_info.length(), TENURED); |
3476 if (!maybe_reloc_info_array->ToObject(&reloc_info_array)) { | 3471 if (!allocation.To(&reloc_info_array)) return allocation; |
3477 return maybe_reloc_info_array; | |
3478 } | |
3479 } | 3472 } |
3480 Object* new_constant_pool; | 3473 HeapObject* new_constant_pool; |
3481 if (FLAG_enable_ool_constant_pool && | 3474 if (FLAG_enable_ool_constant_pool && |
3482 code->constant_pool() != empty_constant_pool_array()) { | 3475 code->constant_pool() != empty_constant_pool_array()) { |
3483 // Copy the constant pool, since edits to the copied code may modify | 3476 // Copy the constant pool, since edits to the copied code may modify |
3484 // the constant pool. | 3477 // the constant pool. |
3485 MaybeObject* maybe_constant_pool = | 3478 AllocationResult allocation = |
3486 CopyConstantPoolArray(code->constant_pool()); | 3479 CopyConstantPoolArray(code->constant_pool()); |
3487 if (!maybe_constant_pool->ToObject(&new_constant_pool)) | 3480 if (!allocation.To(&new_constant_pool)) return allocation; |
3488 return maybe_constant_pool; | |
3489 } else { | 3481 } else { |
3490 new_constant_pool = empty_constant_pool_array(); | 3482 new_constant_pool = empty_constant_pool_array(); |
3491 } | 3483 } |
3492 | 3484 |
3493 int new_body_size = RoundUp(code->instruction_size(), kObjectAlignment); | 3485 int new_body_size = RoundUp(code->instruction_size(), kObjectAlignment); |
3494 | 3486 |
3495 int new_obj_size = Code::SizeFor(new_body_size); | 3487 int new_obj_size = Code::SizeFor(new_body_size); |
3496 | 3488 |
3497 Address old_addr = code->address(); | 3489 Address old_addr = code->address(); |
3498 | 3490 |
3499 size_t relocation_offset = | 3491 size_t relocation_offset = |
3500 static_cast<size_t>(code->instruction_end() - old_addr); | 3492 static_cast<size_t>(code->instruction_end() - old_addr); |
3501 | 3493 |
3502 MaybeObject* maybe_result; | 3494 AllocationResult allocation; |
3503 if (new_obj_size > code_space()->AreaSize()) { | 3495 if (new_obj_size > code_space()->AreaSize()) { |
3504 maybe_result = lo_space_->AllocateRaw(new_obj_size, EXECUTABLE); | 3496 allocation = lo_space_->AllocateRaw(new_obj_size, EXECUTABLE); |
3505 } else { | 3497 } else { |
3506 maybe_result = AllocateRaw(new_obj_size, CODE_SPACE, CODE_SPACE); | 3498 allocation = AllocateRaw(new_obj_size, CODE_SPACE, CODE_SPACE); |
3507 } | 3499 } |
3508 | 3500 |
3509 Object* result; | 3501 HeapObject* result; |
3510 if (!maybe_result->ToObject(&result)) return maybe_result; | 3502 if (!allocation.To(&result)) return allocation; |
3511 | 3503 |
3512 // Copy code object. | 3504 // Copy code object. |
3513 Address new_addr = reinterpret_cast<HeapObject*>(result)->address(); | 3505 Address new_addr = result->address(); |
3514 | 3506 |
3515 // Copy header and instructions. | 3507 // Copy header and instructions. |
3516 CopyBytes(new_addr, old_addr, relocation_offset); | 3508 CopyBytes(new_addr, old_addr, relocation_offset); |
3517 | 3509 |
3518 Code* new_code = Code::cast(result); | 3510 Code* new_code = Code::cast(result); |
3519 new_code->set_relocation_info(ByteArray::cast(reloc_info_array)); | 3511 new_code->set_relocation_info(reloc_info_array); |
3520 | 3512 |
3521 // Update constant pool. | 3513 // Update constant pool. |
3522 new_code->set_constant_pool(new_constant_pool); | 3514 new_code->set_constant_pool(new_constant_pool); |
3523 | 3515 |
3524 // Copy patched rinfo. | 3516 // Copy patched rinfo. |
3525 CopyBytes(new_code->relocation_start(), | 3517 CopyBytes(new_code->relocation_start(), |
3526 reloc_info.start(), | 3518 reloc_info.start(), |
3527 static_cast<size_t>(reloc_info.length())); | 3519 static_cast<size_t>(reloc_info.length())); |
3528 | 3520 |
3529 // Relocate the copy. | 3521 // Relocate the copy. |
3530 ASSERT(!isolate_->code_range()->exists() || | 3522 ASSERT(!isolate_->code_range()->exists() || |
3531 isolate_->code_range()->contains(code->address())); | 3523 isolate_->code_range()->contains(code->address())); |
3532 new_code->Relocate(new_addr - old_addr); | 3524 new_code->Relocate(new_addr - old_addr); |
3533 | 3525 |
3534 #ifdef VERIFY_HEAP | 3526 #ifdef VERIFY_HEAP |
3535 if (FLAG_verify_heap) { | 3527 if (FLAG_verify_heap) code->ObjectVerify(); |
3536 code->Verify(); | |
3537 } | |
3538 #endif | 3528 #endif |
3539 return new_code; | 3529 return new_code; |
3540 } | 3530 } |
3541 | 3531 |
3542 | 3532 |
3543 void Heap::InitializeAllocationMemento(AllocationMemento* memento, | 3533 void Heap::InitializeAllocationMemento(AllocationMemento* memento, |
3544 AllocationSite* allocation_site) { | 3534 AllocationSite* allocation_site) { |
3545 memento->set_map_no_write_barrier(allocation_memento_map()); | 3535 memento->set_map_no_write_barrier(allocation_memento_map()); |
3546 ASSERT(allocation_site->map() == allocation_site_map()); | 3536 ASSERT(allocation_site->map() == allocation_site_map()); |
3547 memento->set_allocation_site(allocation_site, SKIP_WRITE_BARRIER); | 3537 memento->set_allocation_site(allocation_site, SKIP_WRITE_BARRIER); |
3548 if (FLAG_allocation_site_pretenuring) { | 3538 if (FLAG_allocation_site_pretenuring) { |
3549 allocation_site->IncrementMementoCreateCount(); | 3539 allocation_site->IncrementMementoCreateCount(); |
3550 } | 3540 } |
3551 } | 3541 } |
3552 | 3542 |
3553 | 3543 |
3554 MaybeObject* Heap::Allocate(Map* map, AllocationSpace space, | 3544 AllocationResult Heap::Allocate(Map* map, AllocationSpace space, |
3555 AllocationSite* allocation_site) { | 3545 AllocationSite* allocation_site) { |
3556 ASSERT(gc_state_ == NOT_IN_GC); | 3546 ASSERT(gc_state_ == NOT_IN_GC); |
3557 ASSERT(map->instance_type() != MAP_TYPE); | 3547 ASSERT(map->instance_type() != MAP_TYPE); |
3558 // If allocation failures are disallowed, we may allocate in a different | 3548 // If allocation failures are disallowed, we may allocate in a different |
3559 // space when new space is full and the object is not a large object. | 3549 // space when new space is full and the object is not a large object. |
3560 AllocationSpace retry_space = | 3550 AllocationSpace retry_space = |
3561 (space != NEW_SPACE) ? space : TargetSpaceId(map->instance_type()); | 3551 (space != NEW_SPACE) ? space : TargetSpaceId(map->instance_type()); |
3562 int size = map->instance_size(); | 3552 int size = map->instance_size(); |
3563 if (allocation_site != NULL) { | 3553 if (allocation_site != NULL) { |
3564 size += AllocationMemento::kSize; | 3554 size += AllocationMemento::kSize; |
3565 } | 3555 } |
3566 Object* result; | 3556 HeapObject* result; |
3567 MaybeObject* maybe_result = AllocateRaw(size, space, retry_space); | 3557 AllocationResult allocation = AllocateRaw(size, space, retry_space); |
3568 if (!maybe_result->ToObject(&result)) return maybe_result; | 3558 if (!allocation.To(&result)) return allocation; |
3569 // No need for write barrier since object is white and map is in old space. | 3559 // No need for write barrier since object is white and map is in old space. |
3570 HeapObject::cast(result)->set_map_no_write_barrier(map); | 3560 result->set_map_no_write_barrier(map); |
3571 if (allocation_site != NULL) { | 3561 if (allocation_site != NULL) { |
3572 AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>( | 3562 AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>( |
3573 reinterpret_cast<Address>(result) + map->instance_size()); | 3563 reinterpret_cast<Address>(result) + map->instance_size()); |
3574 InitializeAllocationMemento(alloc_memento, allocation_site); | 3564 InitializeAllocationMemento(alloc_memento, allocation_site); |
3575 } | 3565 } |
3576 return result; | 3566 return result; |
3577 } | 3567 } |
3578 | 3568 |
3579 | 3569 |
3580 MaybeObject* Heap::AllocateArgumentsObject(Object* callee, int length) { | 3570 AllocationResult Heap::AllocateArgumentsObject(Object* callee, int length) { |
3581 // To get fast allocation and map sharing for arguments objects we | 3571 // To get fast allocation and map sharing for arguments objects we |
3582 // allocate them based on an arguments boilerplate. | 3572 // allocate them based on an arguments boilerplate. |
3583 | 3573 |
3584 JSObject* boilerplate; | 3574 JSObject* boilerplate; |
3585 int arguments_object_size; | 3575 int arguments_object_size; |
3586 bool strict_mode_callee = callee->IsJSFunction() && | 3576 bool strict_mode_callee = callee->IsJSFunction() && |
3587 JSFunction::cast(callee)->shared()->strict_mode() == STRICT; | 3577 JSFunction::cast(callee)->shared()->strict_mode() == STRICT; |
3588 if (strict_mode_callee) { | 3578 if (strict_mode_callee) { |
3589 boilerplate = | 3579 boilerplate = |
3590 isolate()->context()->native_context()->strict_arguments_boilerplate(); | 3580 isolate()->context()->native_context()->strict_arguments_boilerplate(); |
3591 arguments_object_size = kStrictArgumentsObjectSize; | 3581 arguments_object_size = kStrictArgumentsObjectSize; |
3592 } else { | 3582 } else { |
3593 boilerplate = | 3583 boilerplate = |
3594 isolate()->context()->native_context()->sloppy_arguments_boilerplate(); | 3584 isolate()->context()->native_context()->sloppy_arguments_boilerplate(); |
3595 arguments_object_size = kSloppyArgumentsObjectSize; | 3585 arguments_object_size = kSloppyArgumentsObjectSize; |
3596 } | 3586 } |
3597 | 3587 |
3598 // Check that the size of the boilerplate matches our | 3588 // Check that the size of the boilerplate matches our |
3599 // expectations. The ArgumentsAccessStub::GenerateNewObject relies | 3589 // expectations. The ArgumentsAccessStub::GenerateNewObject relies |
3600 // on the size being a known constant. | 3590 // on the size being a known constant. |
3601 ASSERT(arguments_object_size == boilerplate->map()->instance_size()); | 3591 ASSERT(arguments_object_size == boilerplate->map()->instance_size()); |
3602 | 3592 |
3603 // Do the allocation. | 3593 // Do the allocation. |
3604 Object* result; | 3594 HeapObject* result; |
3605 { MaybeObject* maybe_result = | 3595 { AllocationResult allocation = |
3606 AllocateRaw(arguments_object_size, NEW_SPACE, OLD_POINTER_SPACE); | 3596 AllocateRaw(arguments_object_size, NEW_SPACE, OLD_POINTER_SPACE); |
3607 if (!maybe_result->ToObject(&result)) return maybe_result; | 3597 if (!allocation.To(&result)) return allocation; |
3608 } | 3598 } |
3609 | 3599 |
3610 // Copy the content. The arguments boilerplate doesn't have any | 3600 // Copy the content. The arguments boilerplate doesn't have any |
3611 // fields that point to new space so it's safe to skip the write | 3601 // fields that point to new space so it's safe to skip the write |
3612 // barrier here. | 3602 // barrier here. |
3613 CopyBlock(HeapObject::cast(result)->address(), | 3603 CopyBlock(result->address(), boilerplate->address(), JSObject::kHeaderSize); |
3614 boilerplate->address(), | |
3615 JSObject::kHeaderSize); | |
3616 | 3604 |
3617 // Set the length property. | 3605 // Set the length property. |
3618 JSObject::cast(result)->InObjectPropertyAtPut(kArgumentsLengthIndex, | 3606 JSObject* js_obj = JSObject::cast(result); |
Hannes Payer (out of office)
2014/04/30 07:07:07
js_obj -> js_object
| |
3619 Smi::FromInt(length), | 3607 js_obj->InObjectPropertyAtPut( |
3620 SKIP_WRITE_BARRIER); | 3608 kArgumentsLengthIndex, Smi::FromInt(length), SKIP_WRITE_BARRIER); |
3621 // Set the callee property for sloppy mode arguments object only. | 3609 // Set the callee property for sloppy mode arguments object only. |
3622 if (!strict_mode_callee) { | 3610 if (!strict_mode_callee) { |
3623 JSObject::cast(result)->InObjectPropertyAtPut(kArgumentsCalleeIndex, | 3611 js_obj->InObjectPropertyAtPut(kArgumentsCalleeIndex, callee); |
3624 callee); | |
3625 } | 3612 } |
3626 | 3613 |
3627 // Check the state of the object | 3614 // Check the state of the object |
3628 ASSERT(JSObject::cast(result)->HasFastProperties()); | 3615 ASSERT(js_obj->HasFastProperties()); |
3629 ASSERT(JSObject::cast(result)->HasFastObjectElements()); | 3616 ASSERT(js_obj->HasFastObjectElements()); |
3630 | 3617 |
3631 return result; | 3618 return js_obj; |
3632 } | 3619 } |
3633 | 3620 |
3634 | 3621 |
3635 void Heap::InitializeJSObjectFromMap(JSObject* obj, | 3622 void Heap::InitializeJSObjectFromMap(JSObject* obj, |
3636 FixedArray* properties, | 3623 FixedArray* properties, |
3637 Map* map) { | 3624 Map* map) { |
3638 obj->set_properties(properties); | 3625 obj->set_properties(properties); |
3639 obj->initialize_elements(); | 3626 obj->initialize_elements(); |
3640 // TODO(1240798): Initialize the object's body using valid initial values | 3627 // TODO(1240798): Initialize the object's body using valid initial values |
3641 // according to the object's initial map. For example, if the map's | 3628 // according to the object's initial map. For example, if the map's |
(...skipping 15 matching lines...) Expand all Loading... | |
3657 // We might want to shrink the object later. | 3644 // We might want to shrink the object later. |
3658 ASSERT(obj->GetInternalFieldCount() == 0); | 3645 ASSERT(obj->GetInternalFieldCount() == 0); |
3659 filler = Heap::one_pointer_filler_map(); | 3646 filler = Heap::one_pointer_filler_map(); |
3660 } else { | 3647 } else { |
3661 filler = Heap::undefined_value(); | 3648 filler = Heap::undefined_value(); |
3662 } | 3649 } |
3663 obj->InitializeBody(map, Heap::undefined_value(), filler); | 3650 obj->InitializeBody(map, Heap::undefined_value(), filler); |
3664 } | 3651 } |
3665 | 3652 |
3666 | 3653 |
3667 MaybeObject* Heap::AllocateJSObjectFromMap( | 3654 AllocationResult Heap::AllocateJSObjectFromMap( |
3668 Map* map, | 3655 Map* map, |
3669 PretenureFlag pretenure, | 3656 PretenureFlag pretenure, |
3670 bool allocate_properties, | 3657 bool allocate_properties, |
3671 AllocationSite* allocation_site) { | 3658 AllocationSite* allocation_site) { |
3672 // JSFunctions should be allocated using AllocateFunction to be | 3659 // JSFunctions should be allocated using AllocateFunction to be |
3673 // properly initialized. | 3660 // properly initialized. |
3674 ASSERT(map->instance_type() != JS_FUNCTION_TYPE); | 3661 ASSERT(map->instance_type() != JS_FUNCTION_TYPE); |
3675 | 3662 |
3676 // Both types of global objects should be allocated using | 3663 // Both types of global objects should be allocated using |
3677 // AllocateGlobalObject to be properly initialized. | 3664 // AllocateGlobalObject to be properly initialized. |
3678 ASSERT(map->instance_type() != JS_GLOBAL_OBJECT_TYPE); | 3665 ASSERT(map->instance_type() != JS_GLOBAL_OBJECT_TYPE); |
3679 ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE); | 3666 ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE); |
3680 | 3667 |
3681 // Allocate the backing storage for the properties. | 3668 // Allocate the backing storage for the properties. |
3682 FixedArray* properties; | 3669 FixedArray* properties; |
3683 if (allocate_properties) { | 3670 if (allocate_properties) { |
3684 int prop_size = map->InitialPropertiesLength(); | 3671 int prop_size = map->InitialPropertiesLength(); |
3685 ASSERT(prop_size >= 0); | 3672 ASSERT(prop_size >= 0); |
3686 { MaybeObject* maybe_properties = AllocateFixedArray(prop_size, pretenure); | 3673 { AllocationResult allocation = AllocateFixedArray(prop_size, pretenure); |
3687 if (!maybe_properties->To(&properties)) return maybe_properties; | 3674 if (!allocation.To(&properties)) return allocation; |
3688 } | 3675 } |
3689 } else { | 3676 } else { |
3690 properties = empty_fixed_array(); | 3677 properties = empty_fixed_array(); |
3691 } | 3678 } |
3692 | 3679 |
3693 // Allocate the JSObject. | 3680 // Allocate the JSObject. |
3694 int size = map->instance_size(); | 3681 int size = map->instance_size(); |
3695 AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, pretenure); | 3682 AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, pretenure); |
3696 Object* obj; | 3683 JSObject* js_obj; |
Hannes Payer (out of office)
2014/04/30 07:07:07
js_obj -> js_object
| |
3697 MaybeObject* maybe_obj = Allocate(map, space, allocation_site); | 3684 AllocationResult allocation = Allocate(map, space, allocation_site); |
3698 if (!maybe_obj->To(&obj)) return maybe_obj; | 3685 if (!allocation.To(&js_obj)) return allocation; |
3699 | 3686 |
3700 // Initialize the JSObject. | 3687 // Initialize the JSObject. |
3701 InitializeJSObjectFromMap(JSObject::cast(obj), properties, map); | 3688 InitializeJSObjectFromMap(js_obj, properties, map); |
3702 ASSERT(JSObject::cast(obj)->HasFastElements() || | 3689 ASSERT(js_obj->HasFastElements() || |
3703 JSObject::cast(obj)->HasExternalArrayElements() || | 3690 js_obj->HasExternalArrayElements() || |
3704 JSObject::cast(obj)->HasFixedTypedArrayElements()); | 3691 js_obj->HasFixedTypedArrayElements()); |
3705 return obj; | 3692 return js_obj; |
3706 } | 3693 } |
3707 | 3694 |
3708 | 3695 |
3709 MaybeObject* Heap::AllocateJSObject(JSFunction* constructor, | 3696 AllocationResult Heap::AllocateJSObject(JSFunction* constructor, |
3710 PretenureFlag pretenure, | 3697 PretenureFlag pretenure, |
3711 AllocationSite* allocation_site) { | 3698 AllocationSite* allocation_site) { |
3712 ASSERT(constructor->has_initial_map()); | 3699 ASSERT(constructor->has_initial_map()); |
3713 | 3700 |
3714 // Allocate the object based on the constructors initial map. | 3701 // Allocate the object based on the constructors initial map. |
3715 MaybeObject* result = AllocateJSObjectFromMap(constructor->initial_map(), | 3702 AllocationResult allocation = AllocateJSObjectFromMap( |
3716 pretenure, | 3703 constructor->initial_map(), pretenure, true, allocation_site); |
3717 true, | |
3718 allocation_site); | |
3719 #ifdef DEBUG | 3704 #ifdef DEBUG |
3720 // Make sure result is NOT a global object if valid. | 3705 // Make sure result is NOT a global object if valid. |
3721 Object* non_failure; | 3706 HeapObject* obj; |
3722 ASSERT(!result->ToObject(&non_failure) || !non_failure->IsGlobalObject()); | 3707 ASSERT(!allocation.To(&obj) || !obj->IsGlobalObject()); |
3723 #endif | 3708 #endif |
3724 return result; | 3709 return allocation; |
3725 } | 3710 } |
3726 | 3711 |
3727 | 3712 |
3728 MaybeObject* Heap::CopyJSObject(JSObject* source, AllocationSite* site) { | 3713 AllocationResult Heap::CopyJSObject(JSObject* source, AllocationSite* site) { |
3729 // Never used to copy functions. If functions need to be copied we | 3714 // Never used to copy functions. If functions need to be copied we |
3730 // have to be careful to clear the literals array. | 3715 // have to be careful to clear the literals array. |
3731 SLOW_ASSERT(!source->IsJSFunction()); | 3716 SLOW_ASSERT(!source->IsJSFunction()); |
3732 | 3717 |
3733 // Make the clone. | 3718 // Make the clone. |
3734 Map* map = source->map(); | 3719 Map* map = source->map(); |
3735 int object_size = map->instance_size(); | 3720 int object_size = map->instance_size(); |
3736 Object* clone; | 3721 HeapObject* clone; |
3737 | 3722 |
3738 ASSERT(site == NULL || AllocationSite::CanTrack(map->instance_type())); | 3723 ASSERT(site == NULL || AllocationSite::CanTrack(map->instance_type())); |
3739 | 3724 |
3740 WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER; | 3725 WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER; |
3741 | 3726 |
3742 // If we're forced to always allocate, we use the general allocation | 3727 // If we're forced to always allocate, we use the general allocation |
3743 // functions which may leave us with an object in old space. | 3728 // functions which may leave us with an object in old space. |
3744 if (always_allocate()) { | 3729 if (always_allocate()) { |
3745 { MaybeObject* maybe_clone = | 3730 { AllocationResult allocation = |
3746 AllocateRaw(object_size, NEW_SPACE, OLD_POINTER_SPACE); | 3731 AllocateRaw(object_size, NEW_SPACE, OLD_POINTER_SPACE); |
3747 if (!maybe_clone->ToObject(&clone)) return maybe_clone; | 3732 if (!allocation.To(&clone)) return allocation; |
3748 } | 3733 } |
3749 Address clone_address = HeapObject::cast(clone)->address(); | 3734 Address clone_address = clone->address(); |
3750 CopyBlock(clone_address, | 3735 CopyBlock(clone_address, |
3751 source->address(), | 3736 source->address(), |
3752 object_size); | 3737 object_size); |
3753 // Update write barrier for all fields that lie beyond the header. | 3738 // Update write barrier for all fields that lie beyond the header. |
3754 RecordWrites(clone_address, | 3739 RecordWrites(clone_address, |
3755 JSObject::kHeaderSize, | 3740 JSObject::kHeaderSize, |
3756 (object_size - JSObject::kHeaderSize) / kPointerSize); | 3741 (object_size - JSObject::kHeaderSize) / kPointerSize); |
3757 } else { | 3742 } else { |
3758 wb_mode = SKIP_WRITE_BARRIER; | 3743 wb_mode = SKIP_WRITE_BARRIER; |
3759 | 3744 |
3760 { int adjusted_object_size = site != NULL | 3745 { int adjusted_object_size = site != NULL |
3761 ? object_size + AllocationMemento::kSize | 3746 ? object_size + AllocationMemento::kSize |
3762 : object_size; | 3747 : object_size; |
3763 MaybeObject* maybe_clone = | 3748 AllocationResult allocation = |
3764 AllocateRaw(adjusted_object_size, NEW_SPACE, NEW_SPACE); | 3749 AllocateRaw(adjusted_object_size, NEW_SPACE, NEW_SPACE); |
3765 if (!maybe_clone->ToObject(&clone)) return maybe_clone; | 3750 if (!allocation.To(&clone)) return allocation; |
3766 } | 3751 } |
3767 SLOW_ASSERT(InNewSpace(clone)); | 3752 SLOW_ASSERT(InNewSpace(clone)); |
3768 // Since we know the clone is allocated in new space, we can copy | 3753 // Since we know the clone is allocated in new space, we can copy |
3769 // the contents without worrying about updating the write barrier. | 3754 // the contents without worrying about updating the write barrier. |
3770 CopyBlock(HeapObject::cast(clone)->address(), | 3755 CopyBlock(clone->address(), |
3771 source->address(), | 3756 source->address(), |
3772 object_size); | 3757 object_size); |
3773 | 3758 |
3774 if (site != NULL) { | 3759 if (site != NULL) { |
3775 AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>( | 3760 AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>( |
3776 reinterpret_cast<Address>(clone) + object_size); | 3761 reinterpret_cast<Address>(clone) + object_size); |
3777 InitializeAllocationMemento(alloc_memento, site); | 3762 InitializeAllocationMemento(alloc_memento, site); |
3778 } | 3763 } |
3779 } | 3764 } |
3780 | 3765 |
3781 SLOW_ASSERT( | 3766 SLOW_ASSERT( |
3782 JSObject::cast(clone)->GetElementsKind() == source->GetElementsKind()); | 3767 JSObject::cast(clone)->GetElementsKind() == source->GetElementsKind()); |
3783 FixedArrayBase* elements = FixedArrayBase::cast(source->elements()); | 3768 FixedArrayBase* elements = FixedArrayBase::cast(source->elements()); |
3784 FixedArray* properties = FixedArray::cast(source->properties()); | 3769 FixedArray* properties = FixedArray::cast(source->properties()); |
3785 // Update elements if necessary. | 3770 // Update elements if necessary. |
3786 if (elements->length() > 0) { | 3771 if (elements->length() > 0) { |
3787 Object* elem; | 3772 FixedArrayBase* elem; |
3788 { MaybeObject* maybe_elem; | 3773 { AllocationResult allocation; |
3789 if (elements->map() == fixed_cow_array_map()) { | 3774 if (elements->map() == fixed_cow_array_map()) { |
3790 maybe_elem = FixedArray::cast(elements); | 3775 allocation = FixedArray::cast(elements); |
3791 } else if (source->HasFastDoubleElements()) { | 3776 } else if (source->HasFastDoubleElements()) { |
3792 maybe_elem = CopyFixedDoubleArray(FixedDoubleArray::cast(elements)); | 3777 allocation = CopyFixedDoubleArray(FixedDoubleArray::cast(elements)); |
3793 } else { | 3778 } else { |
3794 maybe_elem = CopyFixedArray(FixedArray::cast(elements)); | 3779 allocation = CopyFixedArray(FixedArray::cast(elements)); |
3795 } | 3780 } |
3796 if (!maybe_elem->ToObject(&elem)) return maybe_elem; | 3781 if (!allocation.To(&elem)) return allocation; |
3797 } | 3782 } |
3798 JSObject::cast(clone)->set_elements(FixedArrayBase::cast(elem), wb_mode); | 3783 JSObject::cast(clone)->set_elements(elem, wb_mode); |
3799 } | 3784 } |
3800 // Update properties if necessary. | 3785 // Update properties if necessary. |
3801 if (properties->length() > 0) { | 3786 if (properties->length() > 0) { |
3802 Object* prop; | 3787 FixedArray* prop; |
3803 { MaybeObject* maybe_prop = CopyFixedArray(properties); | 3788 { AllocationResult allocation = CopyFixedArray(properties); |
3804 if (!maybe_prop->ToObject(&prop)) return maybe_prop; | 3789 if (!allocation.To(&prop)) return allocation; |
3805 } | 3790 } |
3806 JSObject::cast(clone)->set_properties(FixedArray::cast(prop), wb_mode); | 3791 JSObject::cast(clone)->set_properties(prop, wb_mode); |
3807 } | 3792 } |
3808 // Return the new clone. | 3793 // Return the new clone. |
3809 return clone; | 3794 return clone; |
3810 } | 3795 } |
3811 | 3796 |
3812 | 3797 |
3813 MaybeObject* Heap::AllocateStringFromUtf8Slow(Vector<const char> string, | 3798 AllocationResult Heap::AllocateStringFromUtf8Slow(Vector<const char> string, |
3814 int non_ascii_start, | 3799 int non_ascii_start, |
3815 PretenureFlag pretenure) { | 3800 PretenureFlag pretenure) { |
3816 // Continue counting the number of characters in the UTF-8 string, starting | 3801 // Continue counting the number of characters in the UTF-8 string, starting |
3817 // from the first non-ascii character or word. | 3802 // from the first non-ascii character or word. |
3818 Access<UnicodeCache::Utf8Decoder> | 3803 Access<UnicodeCache::Utf8Decoder> |
3819 decoder(isolate_->unicode_cache()->utf8_decoder()); | 3804 decoder(isolate_->unicode_cache()->utf8_decoder()); |
3820 decoder->Reset(string.start() + non_ascii_start, | 3805 decoder->Reset(string.start() + non_ascii_start, |
3821 string.length() - non_ascii_start); | 3806 string.length() - non_ascii_start); |
3822 int utf16_length = decoder->Utf16Length(); | 3807 int utf16_length = decoder->Utf16Length(); |
3823 ASSERT(utf16_length > 0); | 3808 ASSERT(utf16_length > 0); |
3824 // Allocate string. | 3809 // Allocate string. |
3825 Object* result; | 3810 HeapObject* result; |
3826 { | 3811 { |
3827 int chars = non_ascii_start + utf16_length; | 3812 int chars = non_ascii_start + utf16_length; |
3828 MaybeObject* maybe_result = AllocateRawTwoByteString(chars, pretenure); | 3813 AllocationResult allocation = AllocateRawTwoByteString(chars, pretenure); |
3829 if (!maybe_result->ToObject(&result) || result->IsException()) { | 3814 if (!allocation.To(&result) || result->IsException()) { |
3830 return maybe_result; | 3815 return allocation; |
3831 } | 3816 } |
3832 } | 3817 } |
3833 // Convert and copy the characters into the new object. | |
3834 SeqTwoByteString* twobyte = SeqTwoByteString::cast(result); | |
3835 // Copy ascii portion. | 3818 // Copy ascii portion. |
3836 uint16_t* data = twobyte->GetChars(); | 3819 uint16_t* data = SeqTwoByteString::cast(result)->GetChars(); |
3837 if (non_ascii_start != 0) { | 3820 if (non_ascii_start != 0) { |
3838 const char* ascii_data = string.start(); | 3821 const char* ascii_data = string.start(); |
3839 for (int i = 0; i < non_ascii_start; i++) { | 3822 for (int i = 0; i < non_ascii_start; i++) { |
3840 *data++ = *ascii_data++; | 3823 *data++ = *ascii_data++; |
3841 } | 3824 } |
3842 } | 3825 } |
3843 // Now write the remainder. | 3826 // Now write the remainder. |
3844 decoder->WriteUtf16(data, utf16_length); | 3827 decoder->WriteUtf16(data, utf16_length); |
3845 return result; | 3828 return result; |
3846 } | 3829 } |
3847 | 3830 |
3848 | 3831 |
3849 MaybeObject* Heap::AllocateStringFromTwoByte(Vector<const uc16> string, | 3832 AllocationResult Heap::AllocateStringFromTwoByte(Vector<const uc16> string, |
3850 PretenureFlag pretenure) { | 3833 PretenureFlag pretenure) { |
3851 // Check if the string is an ASCII string. | 3834 // Check if the string is an ASCII string. |
3852 Object* result; | 3835 HeapObject* result; |
3853 int length = string.length(); | 3836 int length = string.length(); |
3854 const uc16* start = string.start(); | 3837 const uc16* start = string.start(); |
3855 | 3838 |
3856 if (String::IsOneByte(start, length)) { | 3839 if (String::IsOneByte(start, length)) { |
3857 MaybeObject* maybe_result = AllocateRawOneByteString(length, pretenure); | 3840 AllocationResult allocation = AllocateRawOneByteString(length, pretenure); |
3858 if (!maybe_result->ToObject(&result) || result->IsException()) { | 3841 if (!allocation.To(&result) || result->IsException()) { |
3859 return maybe_result; | 3842 return allocation; |
3860 } | 3843 } |
3861 CopyChars(SeqOneByteString::cast(result)->GetChars(), start, length); | 3844 CopyChars(SeqOneByteString::cast(result)->GetChars(), start, length); |
3862 } else { // It's not a one byte string. | 3845 } else { // It's not a one byte string. |
3863 MaybeObject* maybe_result = AllocateRawTwoByteString(length, pretenure); | 3846 AllocationResult allocation = AllocateRawTwoByteString(length, pretenure); |
3864 if (!maybe_result->ToObject(&result) || result->IsException()) { | 3847 if (!allocation.To(&result) || result->IsException()) { |
3865 return maybe_result; | 3848 return allocation; |
3866 } | 3849 } |
3867 CopyChars(SeqTwoByteString::cast(result)->GetChars(), start, length); | 3850 CopyChars(SeqTwoByteString::cast(result)->GetChars(), start, length); |
3868 } | 3851 } |
3869 return result; | 3852 return result; |
3870 } | 3853 } |
3871 | 3854 |
3872 | 3855 |
3873 static inline void WriteOneByteData(Vector<const char> vector, | 3856 static inline void WriteOneByteData(Vector<const char> vector, |
3874 uint8_t* chars, | 3857 uint8_t* chars, |
3875 int len) { | 3858 int len) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3912 } | 3895 } |
3913 | 3896 |
3914 | 3897 |
3915 static inline void WriteTwoByteData(String* s, uint16_t* chars, int len) { | 3898 static inline void WriteTwoByteData(String* s, uint16_t* chars, int len) { |
3916 ASSERT(s->length() == len); | 3899 ASSERT(s->length() == len); |
3917 String::WriteToFlat(s, chars, 0, len); | 3900 String::WriteToFlat(s, chars, 0, len); |
3918 } | 3901 } |
3919 | 3902 |
3920 | 3903 |
3921 template<bool is_one_byte, typename T> | 3904 template<bool is_one_byte, typename T> |
3922 MaybeObject* Heap::AllocateInternalizedStringImpl( | 3905 AllocationResult Heap::AllocateInternalizedStringImpl( |
3923 T t, int chars, uint32_t hash_field) { | 3906 T t, int chars, uint32_t hash_field) { |
3924 ASSERT(chars >= 0); | 3907 ASSERT(chars >= 0); |
3925 // Compute map and object size. | 3908 // Compute map and object size. |
3926 int size; | 3909 int size; |
3927 Map* map; | 3910 Map* map; |
3928 | 3911 |
3929 if (chars < 0 || chars > String::kMaxLength) { | 3912 if (chars < 0 || chars > String::kMaxLength) { |
3930 return isolate()->ThrowInvalidStringLength(); | 3913 return isolate()->ThrowInvalidStringLength(); |
3931 } | 3914 } |
3932 if (is_one_byte) { | 3915 if (is_one_byte) { |
3933 map = ascii_internalized_string_map(); | 3916 map = ascii_internalized_string_map(); |
3934 size = SeqOneByteString::SizeFor(chars); | 3917 size = SeqOneByteString::SizeFor(chars); |
3935 } else { | 3918 } else { |
3936 map = internalized_string_map(); | 3919 map = internalized_string_map(); |
3937 size = SeqTwoByteString::SizeFor(chars); | 3920 size = SeqTwoByteString::SizeFor(chars); |
3938 } | 3921 } |
3939 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, TENURED); | 3922 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, TENURED); |
3940 | 3923 |
3941 // Allocate string. | 3924 // Allocate string. |
3942 Object* result; | 3925 HeapObject* result; |
3943 { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE); | 3926 { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); |
3944 if (!maybe_result->ToObject(&result)) return maybe_result; | 3927 if (!allocation.To(&result)) return allocation; |
3945 } | 3928 } |
3946 | 3929 |
3947 reinterpret_cast<HeapObject*>(result)->set_map_no_write_barrier(map); | 3930 result->set_map_no_write_barrier(map); |
3948 // Set length and hash fields of the allocated string. | 3931 // Set length and hash fields of the allocated string. |
3949 String* answer = String::cast(result); | 3932 String* answer = String::cast(result); |
3950 answer->set_length(chars); | 3933 answer->set_length(chars); |
3951 answer->set_hash_field(hash_field); | 3934 answer->set_hash_field(hash_field); |
3952 | 3935 |
3953 ASSERT_EQ(size, answer->Size()); | 3936 ASSERT_EQ(size, answer->Size()); |
3954 | 3937 |
3955 if (is_one_byte) { | 3938 if (is_one_byte) { |
3956 WriteOneByteData(t, SeqOneByteString::cast(answer)->GetChars(), chars); | 3939 WriteOneByteData(t, SeqOneByteString::cast(answer)->GetChars(), chars); |
3957 } else { | 3940 } else { |
3958 WriteTwoByteData(t, SeqTwoByteString::cast(answer)->GetChars(), chars); | 3941 WriteTwoByteData(t, SeqTwoByteString::cast(answer)->GetChars(), chars); |
3959 } | 3942 } |
3960 return answer; | 3943 return answer; |
3961 } | 3944 } |
3962 | 3945 |
3963 | 3946 |
3964 // Need explicit instantiations. | 3947 // Need explicit instantiations. |
3965 template | 3948 template |
3966 MaybeObject* Heap::AllocateInternalizedStringImpl<true>(String*, int, uint32_t); | 3949 AllocationResult Heap::AllocateInternalizedStringImpl<true>( |
3967 template | |
3968 MaybeObject* Heap::AllocateInternalizedStringImpl<false>( | |
3969 String*, int, uint32_t); | 3950 String*, int, uint32_t); |
3970 template | 3951 template |
3971 MaybeObject* Heap::AllocateInternalizedStringImpl<false>( | 3952 AllocationResult Heap::AllocateInternalizedStringImpl<false>( |
3953 String*, int, uint32_t); | |
3954 template | |
3955 AllocationResult Heap::AllocateInternalizedStringImpl<false>( | |
3972 Vector<const char>, int, uint32_t); | 3956 Vector<const char>, int, uint32_t); |
3973 | 3957 |
3974 | 3958 |
3975 MaybeObject* Heap::AllocateRawOneByteString(int length, | 3959 AllocationResult Heap::AllocateRawOneByteString(int length, |
3976 PretenureFlag pretenure) { | 3960 PretenureFlag pretenure) { |
3977 if (length < 0 || length > String::kMaxLength) { | 3961 if (length < 0 || length > String::kMaxLength) { |
3978 return isolate()->ThrowInvalidStringLength(); | 3962 return isolate()->ThrowInvalidStringLength(); |
3979 } | 3963 } |
3980 int size = SeqOneByteString::SizeFor(length); | 3964 int size = SeqOneByteString::SizeFor(length); |
3981 ASSERT(size <= SeqOneByteString::kMaxSize); | 3965 ASSERT(size <= SeqOneByteString::kMaxSize); |
3982 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); | 3966 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); |
3983 | 3967 |
3984 Object* result; | 3968 HeapObject* result; |
3985 { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE); | 3969 { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); |
3986 if (!maybe_result->ToObject(&result)) return maybe_result; | 3970 if (!allocation.To(&result)) return allocation; |
3987 } | 3971 } |
3988 | 3972 |
3989 // Partially initialize the object. | 3973 // Partially initialize the object. |
3990 HeapObject::cast(result)->set_map_no_write_barrier(ascii_string_map()); | 3974 result->set_map_no_write_barrier(ascii_string_map()); |
3991 String::cast(result)->set_length(length); | 3975 String::cast(result)->set_length(length); |
3992 String::cast(result)->set_hash_field(String::kEmptyHashField); | 3976 String::cast(result)->set_hash_field(String::kEmptyHashField); |
3993 ASSERT_EQ(size, HeapObject::cast(result)->Size()); | 3977 ASSERT_EQ(size, HeapObject::cast(result)->Size()); |
3994 | 3978 |
3995 return result; | 3979 return result; |
3996 } | 3980 } |
3997 | 3981 |
3998 | 3982 |
3999 MaybeObject* Heap::AllocateRawTwoByteString(int length, | 3983 AllocationResult Heap::AllocateRawTwoByteString(int length, |
4000 PretenureFlag pretenure) { | 3984 PretenureFlag pretenure) { |
Hannes Payer (out of office)
2014/04/30 07:07:07
indent
| |
4001 if (length < 0 || length > String::kMaxLength) { | 3985 if (length < 0 || length > String::kMaxLength) { |
4002 return isolate()->ThrowInvalidStringLength(); | 3986 return isolate()->ThrowInvalidStringLength(); |
4003 } | 3987 } |
4004 int size = SeqTwoByteString::SizeFor(length); | 3988 int size = SeqTwoByteString::SizeFor(length); |
4005 ASSERT(size <= SeqTwoByteString::kMaxSize); | 3989 ASSERT(size <= SeqTwoByteString::kMaxSize); |
4006 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); | 3990 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); |
4007 | 3991 |
4008 Object* result; | 3992 HeapObject* result; |
4009 { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE); | 3993 { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); |
4010 if (!maybe_result->ToObject(&result)) return maybe_result; | 3994 if (!allocation.To(&result)) return allocation; |
4011 } | 3995 } |
4012 | 3996 |
4013 // Partially initialize the object. | 3997 // Partially initialize the object. |
4014 HeapObject::cast(result)->set_map_no_write_barrier(string_map()); | 3998 result->set_map_no_write_barrier(string_map()); |
4015 String::cast(result)->set_length(length); | 3999 String::cast(result)->set_length(length); |
4016 String::cast(result)->set_hash_field(String::kEmptyHashField); | 4000 String::cast(result)->set_hash_field(String::kEmptyHashField); |
4017 ASSERT_EQ(size, HeapObject::cast(result)->Size()); | 4001 ASSERT_EQ(size, HeapObject::cast(result)->Size()); |
4018 return result; | 4002 return result; |
4019 } | 4003 } |
4020 | 4004 |
4021 | 4005 |
4022 MaybeObject* Heap::AllocateEmptyFixedArray() { | 4006 AllocationResult Heap::AllocateEmptyFixedArray() { |
4023 int size = FixedArray::SizeFor(0); | 4007 int size = FixedArray::SizeFor(0); |
4024 Object* result; | 4008 HeapObject* result; |
4025 { MaybeObject* maybe_result = | 4009 { AllocationResult allocation = |
4026 AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE); | 4010 AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE); |
4027 if (!maybe_result->ToObject(&result)) return maybe_result; | 4011 if (!allocation.To(&result)) return allocation; |
4028 } | 4012 } |
4029 // Initialize the object. | 4013 // Initialize the object. |
4030 reinterpret_cast<FixedArray*>(result)->set_map_no_write_barrier( | 4014 result->set_map_no_write_barrier(fixed_array_map()); |
4031 fixed_array_map()); | 4015 FixedArray::cast(result)->set_length(0); |
4032 reinterpret_cast<FixedArray*>(result)->set_length(0); | |
4033 return result; | 4016 return result; |
4034 } | 4017 } |
4035 | 4018 |
4036 | 4019 |
4037 MaybeObject* Heap::AllocateEmptyExternalArray(ExternalArrayType array_type) { | 4020 AllocationResult Heap::AllocateEmptyExternalArray( |
4021 ExternalArrayType array_type) { | |
4038 return AllocateExternalArray(0, array_type, NULL, TENURED); | 4022 return AllocateExternalArray(0, array_type, NULL, TENURED); |
4039 } | 4023 } |
4040 | 4024 |
4041 | 4025 |
4042 MaybeObject* Heap::CopyAndTenureFixedCOWArray(FixedArray* src) { | 4026 AllocationResult Heap::CopyAndTenureFixedCOWArray(FixedArray* src) { |
Hannes Payer (out of office)
2014/04/30 07:07:07
src -> source
| |
4043 if (!InNewSpace(src)) { | 4027 if (!InNewSpace(src)) { |
4044 return src; | 4028 return src; |
4045 } | 4029 } |
4046 | 4030 |
4047 int len = src->length(); | 4031 int len = src->length(); |
4048 Object* obj; | 4032 HeapObject* obj; |
Hannes Payer (out of office)
2014/04/30 07:07:07
obj -> object
| |
4049 { MaybeObject* maybe_obj = AllocateRawFixedArray(len, TENURED); | 4033 { AllocationResult allocation = AllocateRawFixedArray(len, TENURED); |
4050 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 4034 if (!allocation.To(&obj)) return allocation; |
4051 } | 4035 } |
4052 HeapObject::cast(obj)->set_map_no_write_barrier(fixed_array_map()); | 4036 obj->set_map_no_write_barrier(fixed_array_map()); |
4053 FixedArray* result = FixedArray::cast(obj); | 4037 FixedArray* result = FixedArray::cast(obj); |
4054 result->set_length(len); | 4038 result->set_length(len); |
4055 | 4039 |
4056 // Copy the content | 4040 // Copy the content |
4057 DisallowHeapAllocation no_gc; | 4041 DisallowHeapAllocation no_gc; |
4058 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 4042 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
4059 for (int i = 0; i < len; i++) result->set(i, src->get(i), mode); | 4043 for (int i = 0; i < len; i++) result->set(i, src->get(i), mode); |
4060 | 4044 |
4061 // TODO(mvstanton): The map is set twice because of protection against calling | 4045 // TODO(mvstanton): The map is set twice because of protection against calling |
4062 // set() on a COW FixedArray. Issue v8:3221 created to track this, and | 4046 // set() on a COW FixedArray. Issue v8:3221 created to track this, and |
4063 // we might then be able to remove this whole method. | 4047 // we might then be able to remove this whole method. |
4064 HeapObject::cast(obj)->set_map_no_write_barrier(fixed_cow_array_map()); | 4048 HeapObject::cast(obj)->set_map_no_write_barrier(fixed_cow_array_map()); |
4065 return result; | 4049 return result; |
4066 } | 4050 } |
4067 | 4051 |
4068 | 4052 |
4069 MaybeObject* Heap::AllocateEmptyFixedTypedArray(ExternalArrayType array_type) { | 4053 AllocationResult Heap::AllocateEmptyFixedTypedArray( |
4054 ExternalArrayType array_type) { | |
4070 return AllocateFixedTypedArray(0, array_type, TENURED); | 4055 return AllocateFixedTypedArray(0, array_type, TENURED); |
4071 } | 4056 } |
4072 | 4057 |
4073 | 4058 |
4074 MaybeObject* Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) { | 4059 AllocationResult Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) { |
Hannes Payer (out of office)
2014/04/30 07:07:07
src -> source
| |
4075 int len = src->length(); | 4060 int len = src->length(); |
4076 Object* obj; | 4061 HeapObject* obj; |
Hannes Payer (out of office)
2014/04/30 07:07:07
obj -> object
| |
4077 { MaybeObject* maybe_obj = AllocateRawFixedArray(len, NOT_TENURED); | 4062 { AllocationResult allocation = AllocateRawFixedArray(len, NOT_TENURED); |
4078 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 4063 if (!allocation.To(&obj)) return allocation; |
4079 } | 4064 } |
4080 if (InNewSpace(obj)) { | 4065 if (InNewSpace(obj)) { |
4081 HeapObject* dst = HeapObject::cast(obj); | 4066 obj->set_map_no_write_barrier(map); |
4082 dst->set_map_no_write_barrier(map); | 4067 CopyBlock(obj->address() + kPointerSize, |
4083 CopyBlock(dst->address() + kPointerSize, | |
4084 src->address() + kPointerSize, | 4068 src->address() + kPointerSize, |
4085 FixedArray::SizeFor(len) - kPointerSize); | 4069 FixedArray::SizeFor(len) - kPointerSize); |
4086 return obj; | 4070 return obj; |
4087 } | 4071 } |
4088 HeapObject::cast(obj)->set_map_no_write_barrier(map); | 4072 obj->set_map_no_write_barrier(map); |
4089 FixedArray* result = FixedArray::cast(obj); | 4073 FixedArray* result = FixedArray::cast(obj); |
4090 result->set_length(len); | 4074 result->set_length(len); |
4091 | 4075 |
4092 // Copy the content | 4076 // Copy the content |
4093 DisallowHeapAllocation no_gc; | 4077 DisallowHeapAllocation no_gc; |
4094 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 4078 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
4095 for (int i = 0; i < len; i++) result->set(i, src->get(i), mode); | 4079 for (int i = 0; i < len; i++) result->set(i, src->get(i), mode); |
4096 return result; | 4080 return result; |
4097 } | 4081 } |
4098 | 4082 |
4099 | 4083 |
4100 MaybeObject* Heap::CopyFixedDoubleArrayWithMap(FixedDoubleArray* src, | 4084 AllocationResult Heap::CopyFixedDoubleArrayWithMap(FixedDoubleArray* src, |
Hannes Payer (out of office)
2014/04/30 07:07:07
src -> source
| |
4101 Map* map) { | 4085 Map* map) { |
4102 int len = src->length(); | 4086 int len = src->length(); |
4103 Object* obj; | 4087 HeapObject* obj; |
Hannes Payer (out of office)
2014/04/30 07:07:07
obj -> object
| |
4104 { MaybeObject* maybe_obj = AllocateRawFixedDoubleArray(len, NOT_TENURED); | 4088 { AllocationResult allocation = AllocateRawFixedDoubleArray(len, NOT_TENURED); |
4105 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 4089 if (!allocation.To(&obj)) return allocation; |
4106 } | 4090 } |
4107 HeapObject* dst = HeapObject::cast(obj); | 4091 obj->set_map_no_write_barrier(map); |
4108 dst->set_map_no_write_barrier(map); | |
4109 CopyBlock( | 4092 CopyBlock( |
4110 dst->address() + FixedDoubleArray::kLengthOffset, | 4093 obj->address() + FixedDoubleArray::kLengthOffset, |
4111 src->address() + FixedDoubleArray::kLengthOffset, | 4094 src->address() + FixedDoubleArray::kLengthOffset, |
4112 FixedDoubleArray::SizeFor(len) - FixedDoubleArray::kLengthOffset); | 4095 FixedDoubleArray::SizeFor(len) - FixedDoubleArray::kLengthOffset); |
4113 return obj; | 4096 return obj; |
4114 } | 4097 } |
4115 | 4098 |
4116 | 4099 |
4117 MaybeObject* Heap::CopyConstantPoolArrayWithMap(ConstantPoolArray* src, | 4100 AllocationResult Heap::CopyConstantPoolArrayWithMap(ConstantPoolArray* src, |
Hannes Payer (out of office)
2014/04/30 07:07:07
src -> source
| |
4118 Map* map) { | 4101 Map* map) { |
4119 int int64_entries = src->count_of_int64_entries(); | 4102 int int64_entries = src->count_of_int64_entries(); |
4120 int code_ptr_entries = src->count_of_code_ptr_entries(); | 4103 int code_ptr_entries = src->count_of_code_ptr_entries(); |
4121 int heap_ptr_entries = src->count_of_heap_ptr_entries(); | 4104 int heap_ptr_entries = src->count_of_heap_ptr_entries(); |
4122 int int32_entries = src->count_of_int32_entries(); | 4105 int int32_entries = src->count_of_int32_entries(); |
4123 Object* obj; | 4106 HeapObject* obj; |
4124 { MaybeObject* maybe_obj = | 4107 { AllocationResult allocation = |
4125 AllocateConstantPoolArray(int64_entries, code_ptr_entries, | 4108 AllocateConstantPoolArray(int64_entries, code_ptr_entries, |
4126 heap_ptr_entries, int32_entries); | 4109 heap_ptr_entries, int32_entries); |
4127 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 4110 if (!allocation.To(&obj)) return allocation; |
4128 } | 4111 } |
4129 HeapObject* dst = HeapObject::cast(obj); | 4112 obj->set_map_no_write_barrier(map); |
4130 dst->set_map_no_write_barrier(map); | |
4131 int size = ConstantPoolArray::SizeFor( | 4113 int size = ConstantPoolArray::SizeFor( |
4132 int64_entries, code_ptr_entries, heap_ptr_entries, int32_entries); | 4114 int64_entries, code_ptr_entries, heap_ptr_entries, int32_entries); |
4133 CopyBlock( | 4115 CopyBlock( |
4134 dst->address() + ConstantPoolArray::kLengthOffset, | 4116 obj->address() + ConstantPoolArray::kLengthOffset, |
4135 src->address() + ConstantPoolArray::kLengthOffset, | 4117 src->address() + ConstantPoolArray::kLengthOffset, |
4136 size - ConstantPoolArray::kLengthOffset); | 4118 size - ConstantPoolArray::kLengthOffset); |
4137 return obj; | 4119 return obj; |
4138 } | 4120 } |
4139 | 4121 |
4140 | 4122 |
4141 MaybeObject* Heap::AllocateRawFixedArray(int length, PretenureFlag pretenure) { | 4123 AllocationResult Heap::AllocateRawFixedArray(int length, |
4124 PretenureFlag pretenure) { | |
4142 if (length < 0 || length > FixedArray::kMaxLength) { | 4125 if (length < 0 || length > FixedArray::kMaxLength) { |
4143 v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true); | 4126 v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true); |
4144 } | 4127 } |
4145 int size = FixedArray::SizeFor(length); | 4128 int size = FixedArray::SizeFor(length); |
4146 AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, pretenure); | 4129 AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, pretenure); |
4147 | 4130 |
4148 return AllocateRaw(size, space, OLD_POINTER_SPACE); | 4131 return AllocateRaw(size, space, OLD_POINTER_SPACE); |
4149 } | 4132 } |
4150 | 4133 |
4151 | 4134 |
4152 MaybeObject* Heap::AllocateFixedArrayWithFiller(int length, | 4135 AllocationResult Heap::AllocateFixedArrayWithFiller(int length, |
4153 PretenureFlag pretenure, | 4136 PretenureFlag pretenure, |
4154 Object* filler) { | 4137 Object* filler) { |
4155 ASSERT(length >= 0); | 4138 ASSERT(length >= 0); |
4156 ASSERT(empty_fixed_array()->IsFixedArray()); | 4139 ASSERT(empty_fixed_array()->IsFixedArray()); |
4157 if (length == 0) return empty_fixed_array(); | 4140 if (length == 0) return empty_fixed_array(); |
4158 | 4141 |
4159 ASSERT(!InNewSpace(filler)); | 4142 ASSERT(!InNewSpace(filler)); |
4160 Object* result; | 4143 HeapObject* result; |
4161 { MaybeObject* maybe_result = AllocateRawFixedArray(length, pretenure); | 4144 { AllocationResult allocation = AllocateRawFixedArray(length, pretenure); |
4162 if (!maybe_result->ToObject(&result)) return maybe_result; | 4145 if (!allocation.To(&result)) return allocation; |
4163 } | 4146 } |
4164 | 4147 |
4165 HeapObject::cast(result)->set_map_no_write_barrier(fixed_array_map()); | 4148 result->set_map_no_write_barrier(fixed_array_map()); |
4166 FixedArray* array = FixedArray::cast(result); | 4149 FixedArray* array = FixedArray::cast(result); |
4167 array->set_length(length); | 4150 array->set_length(length); |
4168 MemsetPointer(array->data_start(), filler, length); | 4151 MemsetPointer(array->data_start(), filler, length); |
4169 return array; | 4152 return array; |
4170 } | 4153 } |
4171 | 4154 |
4172 | 4155 |
4173 MaybeObject* Heap::AllocateFixedArray(int length, PretenureFlag pretenure) { | 4156 AllocationResult Heap::AllocateFixedArray(int length, PretenureFlag pretenure) { |
4174 return AllocateFixedArrayWithFiller(length, pretenure, undefined_value()); | 4157 return AllocateFixedArrayWithFiller(length, pretenure, undefined_value()); |
4175 } | 4158 } |
4176 | 4159 |
4177 | 4160 |
4178 MaybeObject* Heap::AllocateUninitializedFixedArray(int length) { | 4161 AllocationResult Heap::AllocateUninitializedFixedArray(int length) { |
4179 if (length == 0) return empty_fixed_array(); | 4162 if (length == 0) return empty_fixed_array(); |
4180 | 4163 |
4181 Object* obj; | 4164 HeapObject* obj; |
4182 { MaybeObject* maybe_obj = AllocateRawFixedArray(length, NOT_TENURED); | 4165 { AllocationResult allocation = AllocateRawFixedArray(length, NOT_TENURED); |
4183 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 4166 if (!allocation.To(&obj)) return allocation; |
4184 } | 4167 } |
4185 | 4168 |
4186 reinterpret_cast<FixedArray*>(obj)->set_map_no_write_barrier( | 4169 obj->set_map_no_write_barrier(fixed_array_map()); |
4187 fixed_array_map()); | |
4188 FixedArray::cast(obj)->set_length(length); | 4170 FixedArray::cast(obj)->set_length(length); |
4189 return obj; | 4171 return obj; |
4190 } | 4172 } |
4191 | 4173 |
4192 | 4174 |
4193 MaybeObject* Heap::AllocateUninitializedFixedDoubleArray( | 4175 AllocationResult Heap::AllocateUninitializedFixedDoubleArray( |
4194 int length, | 4176 int length, |
4195 PretenureFlag pretenure) { | 4177 PretenureFlag pretenure) { |
4196 if (length == 0) return empty_fixed_array(); | 4178 if (length == 0) return empty_fixed_array(); |
4197 | 4179 |
4198 Object* elements_object; | 4180 HeapObject* elements; |
4199 MaybeObject* maybe_obj = AllocateRawFixedDoubleArray(length, pretenure); | 4181 AllocationResult allocation = AllocateRawFixedDoubleArray(length, pretenure); |
4200 if (!maybe_obj->ToObject(&elements_object)) return maybe_obj; | 4182 if (!allocation.To(&elements)) return allocation; |
4201 FixedDoubleArray* elements = | |
4202 reinterpret_cast<FixedDoubleArray*>(elements_object); | |
4203 | 4183 |
4204 elements->set_map_no_write_barrier(fixed_double_array_map()); | 4184 elements->set_map_no_write_barrier(fixed_double_array_map()); |
4205 elements->set_length(length); | 4185 FixedDoubleArray::cast(elements)->set_length(length); |
4206 return elements; | 4186 return elements; |
4207 } | 4187 } |
4208 | 4188 |
4209 | 4189 |
4210 MaybeObject* Heap::AllocateRawFixedDoubleArray(int length, | 4190 AllocationResult Heap::AllocateRawFixedDoubleArray(int length, |
4211 PretenureFlag pretenure) { | 4191 PretenureFlag pretenure) { |
4212 if (length < 0 || length > FixedDoubleArray::kMaxLength) { | 4192 if (length < 0 || length > FixedDoubleArray::kMaxLength) { |
4213 v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true); | 4193 v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true); |
4214 } | 4194 } |
4215 int size = FixedDoubleArray::SizeFor(length); | 4195 int size = FixedDoubleArray::SizeFor(length); |
4216 #ifndef V8_HOST_ARCH_64_BIT | 4196 #ifndef V8_HOST_ARCH_64_BIT |
4217 size += kPointerSize; | 4197 size += kPointerSize; |
4218 #endif | 4198 #endif |
4219 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); | 4199 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); |
4220 | 4200 |
4221 HeapObject* object; | 4201 HeapObject* object; |
4222 { MaybeObject* maybe_object = AllocateRaw(size, space, OLD_DATA_SPACE); | 4202 { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); |
4223 if (!maybe_object->To<HeapObject>(&object)) return maybe_object; | 4203 if (!allocation.To(&object)) return allocation; |
4224 } | 4204 } |
4225 | 4205 |
4226 return EnsureDoubleAligned(this, object, size); | 4206 return EnsureDoubleAligned(this, object, size); |
4227 } | 4207 } |
4228 | 4208 |
4229 | 4209 |
4230 MaybeObject* Heap::AllocateConstantPoolArray(int number_of_int64_entries, | 4210 AllocationResult Heap::AllocateConstantPoolArray(int number_of_int64_entries, |
4231 int number_of_code_ptr_entries, | 4211 int number_of_code_ptr_entries, |
4232 int number_of_heap_ptr_entries, | 4212 int number_of_heap_ptr_entries, |
4233 int number_of_int32_entries) { | 4213 int number_of_int32_entries) { |
4234 CHECK(number_of_int64_entries >= 0 && | 4214 CHECK(number_of_int64_entries >= 0 && |
4235 number_of_int64_entries <= ConstantPoolArray::kMaxEntriesPerType && | 4215 number_of_int64_entries <= ConstantPoolArray::kMaxEntriesPerType && |
4236 number_of_code_ptr_entries >= 0 && | 4216 number_of_code_ptr_entries >= 0 && |
4237 number_of_code_ptr_entries <= ConstantPoolArray::kMaxEntriesPerType && | 4217 number_of_code_ptr_entries <= ConstantPoolArray::kMaxEntriesPerType && |
4238 number_of_heap_ptr_entries >= 0 && | 4218 number_of_heap_ptr_entries >= 0 && |
4239 number_of_heap_ptr_entries <= ConstantPoolArray::kMaxEntriesPerType && | 4219 number_of_heap_ptr_entries <= ConstantPoolArray::kMaxEntriesPerType && |
4240 number_of_int32_entries >= 0 && | 4220 number_of_int32_entries >= 0 && |
4241 number_of_int32_entries <= ConstantPoolArray::kMaxEntriesPerType); | 4221 number_of_int32_entries <= ConstantPoolArray::kMaxEntriesPerType); |
4242 int size = ConstantPoolArray::SizeFor(number_of_int64_entries, | 4222 int size = ConstantPoolArray::SizeFor(number_of_int64_entries, |
4243 number_of_code_ptr_entries, | 4223 number_of_code_ptr_entries, |
4244 number_of_heap_ptr_entries, | 4224 number_of_heap_ptr_entries, |
4245 number_of_int32_entries); | 4225 number_of_int32_entries); |
4246 #ifndef V8_HOST_ARCH_64_BIT | 4226 #ifndef V8_HOST_ARCH_64_BIT |
4247 size += kPointerSize; | 4227 size += kPointerSize; |
4248 #endif | 4228 #endif |
4249 AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, TENURED); | 4229 AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, TENURED); |
4250 | 4230 |
4251 HeapObject* object; | 4231 HeapObject* object; |
4252 { MaybeObject* maybe_object = AllocateRaw(size, space, OLD_POINTER_SPACE); | 4232 { AllocationResult allocation = AllocateRaw(size, space, OLD_POINTER_SPACE); |
4253 if (!maybe_object->To<HeapObject>(&object)) return maybe_object; | 4233 if (!allocation.To(&object)) return allocation; |
4254 } | 4234 } |
4255 object = EnsureDoubleAligned(this, object, size); | 4235 object = EnsureDoubleAligned(this, object, size); |
4256 HeapObject::cast(object)->set_map_no_write_barrier(constant_pool_array_map()); | 4236 object->set_map_no_write_barrier(constant_pool_array_map()); |
4257 | 4237 |
4258 ConstantPoolArray* constant_pool = | 4238 ConstantPoolArray* constant_pool = ConstantPoolArray::cast(object); |
4259 reinterpret_cast<ConstantPoolArray*>(object); | |
4260 constant_pool->Init(number_of_int64_entries, | 4239 constant_pool->Init(number_of_int64_entries, |
4261 number_of_code_ptr_entries, | 4240 number_of_code_ptr_entries, |
4262 number_of_heap_ptr_entries, | 4241 number_of_heap_ptr_entries, |
4263 number_of_int32_entries); | 4242 number_of_int32_entries); |
4264 if (number_of_code_ptr_entries > 0) { | 4243 if (number_of_code_ptr_entries > 0) { |
4265 int offset = | 4244 int offset = |
4266 constant_pool->OffsetOfElementAt(constant_pool->first_code_ptr_index()); | 4245 constant_pool->OffsetOfElementAt(constant_pool->first_code_ptr_index()); |
4267 MemsetPointer( | 4246 MemsetPointer( |
4268 reinterpret_cast<Address*>(HeapObject::RawField(constant_pool, offset)), | 4247 reinterpret_cast<Address*>(HeapObject::RawField(constant_pool, offset)), |
4269 isolate()->builtins()->builtin(Builtins::kIllegal)->entry(), | 4248 isolate()->builtins()->builtin(Builtins::kIllegal)->entry(), |
4270 number_of_code_ptr_entries); | 4249 number_of_code_ptr_entries); |
4271 } | 4250 } |
4272 if (number_of_heap_ptr_entries > 0) { | 4251 if (number_of_heap_ptr_entries > 0) { |
4273 int offset = | 4252 int offset = |
4274 constant_pool->OffsetOfElementAt(constant_pool->first_heap_ptr_index()); | 4253 constant_pool->OffsetOfElementAt(constant_pool->first_heap_ptr_index()); |
4275 MemsetPointer( | 4254 MemsetPointer( |
4276 HeapObject::RawField(constant_pool, offset), | 4255 HeapObject::RawField(constant_pool, offset), |
4277 undefined_value(), | 4256 undefined_value(), |
4278 number_of_heap_ptr_entries); | 4257 number_of_heap_ptr_entries); |
4279 } | 4258 } |
4280 return constant_pool; | 4259 return constant_pool; |
4281 } | 4260 } |
4282 | 4261 |
4283 | 4262 |
4284 MaybeObject* Heap::AllocateEmptyConstantPoolArray() { | 4263 AllocationResult Heap::AllocateEmptyConstantPoolArray() { |
4285 int size = ConstantPoolArray::SizeFor(0, 0, 0, 0); | 4264 int size = ConstantPoolArray::SizeFor(0, 0, 0, 0); |
4286 Object* result; | 4265 HeapObject* result; |
4287 { MaybeObject* maybe_result = | 4266 { AllocationResult allocation = |
4288 AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE); | 4267 AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE); |
4289 if (!maybe_result->ToObject(&result)) return maybe_result; | 4268 if (!allocation.To(&result)) return allocation; |
4290 } | 4269 } |
4291 HeapObject::cast(result)->set_map_no_write_barrier(constant_pool_array_map()); | 4270 result->set_map_no_write_barrier(constant_pool_array_map()); |
4292 ConstantPoolArray::cast(result)->Init(0, 0, 0, 0); | 4271 ConstantPoolArray::cast(result)->Init(0, 0, 0, 0); |
4293 return result; | 4272 return result; |
4294 } | 4273 } |
4295 | 4274 |
4296 | 4275 |
4297 MaybeObject* Heap::AllocateHashTable(int length, PretenureFlag pretenure) { | 4276 AllocationResult Heap::AllocateHashTable(int length, PretenureFlag pretenure) { |
4298 Object* result; | 4277 HeapObject* result; |
4299 { MaybeObject* maybe_result = AllocateFixedArray(length, pretenure); | 4278 { AllocationResult allocation = AllocateFixedArray(length, pretenure); |
4300 if (!maybe_result->ToObject(&result)) return maybe_result; | 4279 if (!allocation.To(&result)) return allocation; |
4301 } | 4280 } |
4302 reinterpret_cast<HeapObject*>(result)->set_map_no_write_barrier( | 4281 result->set_map_no_write_barrier(hash_table_map()); |
4303 hash_table_map()); | |
4304 ASSERT(result->IsHashTable()); | 4282 ASSERT(result->IsHashTable()); |
4305 return result; | 4283 return result; |
4306 } | 4284 } |
4307 | 4285 |
4308 | 4286 |
4309 MaybeObject* Heap::AllocateSymbol() { | 4287 AllocationResult Heap::AllocateSymbol() { |
4310 // Statically ensure that it is safe to allocate symbols in paged spaces. | 4288 // Statically ensure that it is safe to allocate symbols in paged spaces. |
4311 STATIC_ASSERT(Symbol::kSize <= Page::kMaxRegularHeapObjectSize); | 4289 STATIC_ASSERT(Symbol::kSize <= Page::kMaxRegularHeapObjectSize); |
4312 | 4290 |
4313 Object* result; | 4291 HeapObject* result; |
4314 MaybeObject* maybe = | 4292 AllocationResult allocation = |
4315 AllocateRaw(Symbol::kSize, OLD_POINTER_SPACE, OLD_POINTER_SPACE); | 4293 AllocateRaw(Symbol::kSize, OLD_POINTER_SPACE, OLD_POINTER_SPACE); |
4316 if (!maybe->ToObject(&result)) return maybe; | 4294 if (!allocation.To(&result)) return allocation; |
4317 | 4295 |
4318 HeapObject::cast(result)->set_map_no_write_barrier(symbol_map()); | 4296 result->set_map_no_write_barrier(symbol_map()); |
4319 | 4297 |
4320 // Generate a random hash value. | 4298 // Generate a random hash value. |
4321 int hash; | 4299 int hash; |
4322 int attempts = 0; | 4300 int attempts = 0; |
4323 do { | 4301 do { |
4324 hash = isolate()->random_number_generator()->NextInt() & Name::kHashBitMask; | 4302 hash = isolate()->random_number_generator()->NextInt() & Name::kHashBitMask; |
4325 attempts++; | 4303 attempts++; |
4326 } while (hash == 0 && attempts < 30); | 4304 } while (hash == 0 && attempts < 30); |
4327 if (hash == 0) hash = 1; // never return 0 | 4305 if (hash == 0) hash = 1; // never return 0 |
4328 | 4306 |
4329 Symbol::cast(result)->set_hash_field( | 4307 Symbol::cast(result)->set_hash_field( |
4330 Name::kIsNotArrayIndexMask | (hash << Name::kHashShift)); | 4308 Name::kIsNotArrayIndexMask | (hash << Name::kHashShift)); |
4331 Symbol::cast(result)->set_name(undefined_value()); | 4309 Symbol::cast(result)->set_name(undefined_value()); |
4332 Symbol::cast(result)->set_flags(Smi::FromInt(0)); | 4310 Symbol::cast(result)->set_flags(Smi::FromInt(0)); |
4333 | 4311 |
4334 ASSERT(!Symbol::cast(result)->is_private()); | 4312 ASSERT(!Symbol::cast(result)->is_private()); |
4335 return result; | 4313 return result; |
4336 } | 4314 } |
4337 | 4315 |
4338 | 4316 |
4339 MaybeObject* Heap::AllocatePrivateSymbol() { | 4317 AllocationResult Heap::AllocatePrivateSymbol() { |
4340 MaybeObject* maybe = AllocateSymbol(); | |
4341 Symbol* symbol; | 4318 Symbol* symbol; |
4342 if (!maybe->To(&symbol)) return maybe; | 4319 AllocationResult allocation = AllocateSymbol(); |
4320 if (!allocation.To(&symbol)) return allocation; | |
4343 symbol->set_is_private(true); | 4321 symbol->set_is_private(true); |
4344 return symbol; | 4322 return symbol; |
4345 } | 4323 } |
4346 | 4324 |
4347 | 4325 |
4348 MaybeObject* Heap::AllocateStruct(InstanceType type) { | 4326 AllocationResult Heap::AllocateStruct(InstanceType type) { |
4349 Map* map; | 4327 Map* map; |
4350 switch (type) { | 4328 switch (type) { |
4351 #define MAKE_CASE(NAME, Name, name) \ | 4329 #define MAKE_CASE(NAME, Name, name) \ |
4352 case NAME##_TYPE: map = name##_map(); break; | 4330 case NAME##_TYPE: map = name##_map(); break; |
4353 STRUCT_LIST(MAKE_CASE) | 4331 STRUCT_LIST(MAKE_CASE) |
4354 #undef MAKE_CASE | 4332 #undef MAKE_CASE |
4355 default: | 4333 default: |
4356 UNREACHABLE(); | 4334 UNREACHABLE(); |
4357 return exception(); | 4335 return exception(); |
4358 } | 4336 } |
4359 int size = map->instance_size(); | 4337 int size = map->instance_size(); |
4360 AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, TENURED); | 4338 AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, TENURED); |
4361 Object* result; | 4339 Struct* result; |
4362 { MaybeObject* maybe_result = Allocate(map, space); | 4340 { AllocationResult allocation = Allocate(map, space); |
4363 if (!maybe_result->ToObject(&result)) return maybe_result; | 4341 if (!allocation.To(&result)) return allocation; |
4364 } | 4342 } |
4365 Struct::cast(result)->InitializeBody(size); | 4343 result->InitializeBody(size); |
4366 return result; | 4344 return result; |
4367 } | 4345 } |
4368 | 4346 |
4369 | 4347 |
4370 bool Heap::IsHeapIterable() { | 4348 bool Heap::IsHeapIterable() { |
4371 return (!old_pointer_space()->was_swept_conservatively() && | 4349 return (!old_pointer_space()->was_swept_conservatively() && |
4372 !old_data_space()->was_swept_conservatively()); | 4350 !old_data_space()->was_swept_conservatively()); |
4373 } | 4351 } |
4374 | 4352 |
4375 | 4353 |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4647 case CODE_SPACE: | 4625 case CODE_SPACE: |
4648 return code_space_->Contains(addr); | 4626 return code_space_->Contains(addr); |
4649 case MAP_SPACE: | 4627 case MAP_SPACE: |
4650 return map_space_->Contains(addr); | 4628 return map_space_->Contains(addr); |
4651 case CELL_SPACE: | 4629 case CELL_SPACE: |
4652 return cell_space_->Contains(addr); | 4630 return cell_space_->Contains(addr); |
4653 case PROPERTY_CELL_SPACE: | 4631 case PROPERTY_CELL_SPACE: |
4654 return property_cell_space_->Contains(addr); | 4632 return property_cell_space_->Contains(addr); |
4655 case LO_SPACE: | 4633 case LO_SPACE: |
4656 return lo_space_->SlowContains(addr); | 4634 return lo_space_->SlowContains(addr); |
4635 case INVALID_SPACE: | |
Hannes Payer (out of office)
2014/04/30 07:07:07
Instead of case INVALID_SPACE we could also use de
Yang
2014/04/30 12:25:34
Done.
| |
4636 UNREACHABLE(); | |
4637 return false; | |
4657 } | 4638 } |
4658 | 4639 |
4659 return false; | 4640 return false; |
4660 } | 4641 } |
4661 | 4642 |
4662 | 4643 |
4663 #ifdef VERIFY_HEAP | 4644 #ifdef VERIFY_HEAP |
4664 void Heap::Verify() { | 4645 void Heap::Verify() { |
4665 CHECK(HasBeenSetUp()); | 4646 CHECK(HasBeenSetUp()); |
4666 HandleScope scope(isolate()); | 4647 HandleScope scope(isolate()); |
(...skipping 1839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6506 static_cast<int>(object_sizes_last_time_[index])); | 6487 static_cast<int>(object_sizes_last_time_[index])); |
6507 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) | 6488 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) |
6508 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 6489 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
6509 | 6490 |
6510 OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 6491 OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
6511 OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 6492 OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
6512 ClearObjectStats(); | 6493 ClearObjectStats(); |
6513 } | 6494 } |
6514 | 6495 |
6515 } } // namespace v8::internal | 6496 } } // namespace v8::internal |
OLD | NEW |