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 "src/heap/heap.h" | 5 #include "src/heap/heap.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
(...skipping 1050 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1061 for (auto& chunk : *reservation) { | 1061 for (auto& chunk : *reservation) { |
1062 AllocationResult allocation; | 1062 AllocationResult allocation; |
1063 int size = chunk.size; | 1063 int size = chunk.size; |
1064 DCHECK_LE(size, MemoryAllocator::PageAreaSize( | 1064 DCHECK_LE(size, MemoryAllocator::PageAreaSize( |
1065 static_cast<AllocationSpace>(space))); | 1065 static_cast<AllocationSpace>(space))); |
1066 if (space == NEW_SPACE) { | 1066 if (space == NEW_SPACE) { |
1067 allocation = new_space()->AllocateRawUnaligned(size); | 1067 allocation = new_space()->AllocateRawUnaligned(size); |
1068 } else { | 1068 } else { |
1069 allocation = paged_space(space)->AllocateRawUnaligned(size); | 1069 allocation = paged_space(space)->AllocateRawUnaligned(size); |
1070 } | 1070 } |
1071 HeapObject* free_space; | 1071 HeapObject* free_space = nullptr; |
1072 if (allocation.To(&free_space)) { | 1072 if (allocation.To(&free_space)) { |
1073 // Mark with a free list node, in case we have a GC before | 1073 // Mark with a free list node, in case we have a GC before |
1074 // deserializing. | 1074 // deserializing. |
1075 Address free_space_address = free_space->address(); | 1075 Address free_space_address = free_space->address(); |
1076 CreateFillerObjectAt(free_space_address, size); | 1076 CreateFillerObjectAt(free_space_address, size); |
1077 DCHECK(space < Serializer::kNumberOfPreallocatedSpaces); | 1077 DCHECK(space < Serializer::kNumberOfPreallocatedSpaces); |
1078 chunk.start = free_space_address; | 1078 chunk.start = free_space_address; |
1079 chunk.end = free_space_address + size; | 1079 chunk.end = free_space_address + size; |
1080 } else { | 1080 } else { |
1081 perform_gc = true; | 1081 perform_gc = true; |
(...skipping 1494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2576 Map::Counter::encode(Map::kRetainingCounterStart); | 2576 Map::Counter::encode(Map::kRetainingCounterStart); |
2577 reinterpret_cast<Map*>(result)->set_bit_field3(bit_field3); | 2577 reinterpret_cast<Map*>(result)->set_bit_field3(bit_field3); |
2578 reinterpret_cast<Map*>(result)->set_weak_cell_cache(Smi::FromInt(0)); | 2578 reinterpret_cast<Map*>(result)->set_weak_cell_cache(Smi::FromInt(0)); |
2579 return result; | 2579 return result; |
2580 } | 2580 } |
2581 | 2581 |
2582 | 2582 |
2583 AllocationResult Heap::AllocateMap(InstanceType instance_type, | 2583 AllocationResult Heap::AllocateMap(InstanceType instance_type, |
2584 int instance_size, | 2584 int instance_size, |
2585 ElementsKind elements_kind) { | 2585 ElementsKind elements_kind) { |
2586 HeapObject* result; | 2586 HeapObject* result = nullptr; |
2587 AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE, MAP_SPACE); | 2587 AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE, MAP_SPACE); |
2588 if (!allocation.To(&result)) return allocation; | 2588 if (!allocation.To(&result)) return allocation; |
2589 | 2589 |
2590 result->set_map_no_write_barrier(meta_map()); | 2590 result->set_map_no_write_barrier(meta_map()); |
2591 Map* map = Map::cast(result); | 2591 Map* map = Map::cast(result); |
2592 map->set_instance_type(instance_type); | 2592 map->set_instance_type(instance_type); |
2593 map->set_prototype(null_value(), SKIP_WRITE_BARRIER); | 2593 map->set_prototype(null_value(), SKIP_WRITE_BARRIER); |
2594 map->set_constructor_or_backpointer(null_value(), SKIP_WRITE_BARRIER); | 2594 map->set_constructor_or_backpointer(null_value(), SKIP_WRITE_BARRIER); |
2595 map->set_instance_size(instance_size); | 2595 map->set_instance_size(instance_size); |
2596 map->clear_unused(); | 2596 map->clear_unused(); |
(...skipping 18 matching lines...) Expand all Loading... |
2615 Map::Counter::encode(Map::kRetainingCounterStart); | 2615 Map::Counter::encode(Map::kRetainingCounterStart); |
2616 map->set_bit_field3(bit_field3); | 2616 map->set_bit_field3(bit_field3); |
2617 map->set_elements_kind(elements_kind); | 2617 map->set_elements_kind(elements_kind); |
2618 | 2618 |
2619 return map; | 2619 return map; |
2620 } | 2620 } |
2621 | 2621 |
2622 | 2622 |
2623 AllocationResult Heap::AllocateFillerObject(int size, bool double_align, | 2623 AllocationResult Heap::AllocateFillerObject(int size, bool double_align, |
2624 AllocationSpace space) { | 2624 AllocationSpace space) { |
2625 HeapObject* obj; | 2625 HeapObject* obj = nullptr; |
2626 { | 2626 { |
2627 AllocationAlignment align = double_align ? kDoubleAligned : kWordAligned; | 2627 AllocationAlignment align = double_align ? kDoubleAligned : kWordAligned; |
2628 AllocationResult allocation = AllocateRaw(size, space, space, align); | 2628 AllocationResult allocation = AllocateRaw(size, space, space, align); |
2629 if (!allocation.To(&obj)) return allocation; | 2629 if (!allocation.To(&obj)) return allocation; |
2630 } | 2630 } |
2631 #ifdef DEBUG | 2631 #ifdef DEBUG |
2632 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); | 2632 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); |
2633 DCHECK(chunk->owner()->identity() == space); | 2633 DCHECK(chunk->owner()->identity() == space); |
2634 #endif | 2634 #endif |
2635 CreateFillerObjectAt(obj->address(), size); | 2635 CreateFillerObjectAt(obj->address(), size); |
(...skipping 23 matching lines...) Expand all Loading... |
2659 const Heap::StructTable Heap::struct_table[] = { | 2659 const Heap::StructTable Heap::struct_table[] = { |
2660 #define STRUCT_TABLE_ELEMENT(NAME, Name, name) \ | 2660 #define STRUCT_TABLE_ELEMENT(NAME, Name, name) \ |
2661 { NAME##_TYPE, Name::kSize, k##Name##MapRootIndex } \ | 2661 { NAME##_TYPE, Name::kSize, k##Name##MapRootIndex } \ |
2662 , | 2662 , |
2663 STRUCT_LIST(STRUCT_TABLE_ELEMENT) | 2663 STRUCT_LIST(STRUCT_TABLE_ELEMENT) |
2664 #undef STRUCT_TABLE_ELEMENT | 2664 #undef STRUCT_TABLE_ELEMENT |
2665 }; | 2665 }; |
2666 | 2666 |
2667 | 2667 |
2668 bool Heap::CreateInitialMaps() { | 2668 bool Heap::CreateInitialMaps() { |
2669 HeapObject* obj; | 2669 HeapObject* obj = nullptr; |
2670 { | 2670 { |
2671 AllocationResult allocation = AllocatePartialMap(MAP_TYPE, Map::kSize); | 2671 AllocationResult allocation = AllocatePartialMap(MAP_TYPE, Map::kSize); |
2672 if (!allocation.To(&obj)) return false; | 2672 if (!allocation.To(&obj)) return false; |
2673 } | 2673 } |
2674 // Map::cast cannot be used due to uninitialized map field. | 2674 // Map::cast cannot be used due to uninitialized map field. |
2675 Map* new_meta_map = reinterpret_cast<Map*>(obj); | 2675 Map* new_meta_map = reinterpret_cast<Map*>(obj); |
2676 set_meta_map(new_meta_map); | 2676 set_meta_map(new_meta_map); |
2677 new_meta_map->set_map(new_meta_map); | 2677 new_meta_map->set_map(new_meta_map); |
2678 | 2678 |
2679 { // Partial map allocation | 2679 { // Partial map allocation |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2895 #undef ALLOCATE_VARSIZE_MAP | 2895 #undef ALLOCATE_VARSIZE_MAP |
2896 #undef ALLOCATE_MAP | 2896 #undef ALLOCATE_MAP |
2897 } | 2897 } |
2898 | 2898 |
2899 { // Empty arrays | 2899 { // Empty arrays |
2900 { | 2900 { |
2901 ByteArray* byte_array; | 2901 ByteArray* byte_array; |
2902 if (!AllocateByteArray(0, TENURED).To(&byte_array)) return false; | 2902 if (!AllocateByteArray(0, TENURED).To(&byte_array)) return false; |
2903 set_empty_byte_array(byte_array); | 2903 set_empty_byte_array(byte_array); |
2904 | 2904 |
2905 BytecodeArray* bytecode_array; | 2905 BytecodeArray* bytecode_array = nullptr; |
2906 AllocationResult allocation = | 2906 AllocationResult allocation = |
2907 AllocateBytecodeArray(0, nullptr, 0, 0, empty_fixed_array()); | 2907 AllocateBytecodeArray(0, nullptr, 0, 0, empty_fixed_array()); |
2908 if (!allocation.To(&bytecode_array)) { | 2908 if (!allocation.To(&bytecode_array)) { |
2909 return false; | 2909 return false; |
2910 } | 2910 } |
2911 set_empty_bytecode_array(bytecode_array); | 2911 set_empty_bytecode_array(bytecode_array); |
2912 } | 2912 } |
2913 | 2913 |
2914 #define ALLOCATE_EMPTY_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \ | 2914 #define ALLOCATE_EMPTY_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \ |
2915 { \ | 2915 { \ |
(...skipping 13 matching lines...) Expand all Loading... |
2929 | 2929 |
2930 AllocationResult Heap::AllocateHeapNumber(double value, MutableMode mode, | 2930 AllocationResult Heap::AllocateHeapNumber(double value, MutableMode mode, |
2931 PretenureFlag pretenure) { | 2931 PretenureFlag pretenure) { |
2932 // Statically ensure that it is safe to allocate heap numbers in paged | 2932 // Statically ensure that it is safe to allocate heap numbers in paged |
2933 // spaces. | 2933 // spaces. |
2934 int size = HeapNumber::kSize; | 2934 int size = HeapNumber::kSize; |
2935 STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxRegularHeapObjectSize); | 2935 STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxRegularHeapObjectSize); |
2936 | 2936 |
2937 AllocationSpace space = SelectSpace(size, pretenure); | 2937 AllocationSpace space = SelectSpace(size, pretenure); |
2938 | 2938 |
2939 HeapObject* result; | 2939 HeapObject* result = nullptr; |
2940 { | 2940 { |
2941 AllocationResult allocation = | 2941 AllocationResult allocation = |
2942 AllocateRaw(size, space, OLD_SPACE, kDoubleUnaligned); | 2942 AllocateRaw(size, space, OLD_SPACE, kDoubleUnaligned); |
2943 if (!allocation.To(&result)) return allocation; | 2943 if (!allocation.To(&result)) return allocation; |
2944 } | 2944 } |
2945 | 2945 |
2946 Map* map = mode == MUTABLE ? mutable_heap_number_map() : heap_number_map(); | 2946 Map* map = mode == MUTABLE ? mutable_heap_number_map() : heap_number_map(); |
2947 HeapObject::cast(result)->set_map_no_write_barrier(map); | 2947 HeapObject::cast(result)->set_map_no_write_barrier(map); |
2948 HeapNumber::cast(result)->set_value(value); | 2948 HeapNumber::cast(result)->set_value(value); |
2949 return result; | 2949 return result; |
2950 } | 2950 } |
2951 | 2951 |
2952 #define SIMD_ALLOCATE_DEFINITION(TYPE, Type, type, lane_count, lane_type) \ | 2952 #define SIMD_ALLOCATE_DEFINITION(TYPE, Type, type, lane_count, lane_type) \ |
2953 AllocationResult Heap::Allocate##Type(lane_type lanes[lane_count], \ | 2953 AllocationResult Heap::Allocate##Type(lane_type lanes[lane_count], \ |
2954 PretenureFlag pretenure) { \ | 2954 PretenureFlag pretenure) { \ |
2955 int size = Type::kSize; \ | 2955 int size = Type::kSize; \ |
2956 STATIC_ASSERT(Type::kSize <= Page::kMaxRegularHeapObjectSize); \ | 2956 STATIC_ASSERT(Type::kSize <= Page::kMaxRegularHeapObjectSize); \ |
2957 \ | 2957 \ |
2958 AllocationSpace space = SelectSpace(size, pretenure); \ | 2958 AllocationSpace space = SelectSpace(size, pretenure); \ |
2959 \ | 2959 \ |
2960 HeapObject* result; \ | 2960 HeapObject* result = nullptr; \ |
2961 { \ | 2961 { \ |
2962 AllocationResult allocation = \ | 2962 AllocationResult allocation = \ |
2963 AllocateRaw(size, space, OLD_SPACE, kSimd128Unaligned); \ | 2963 AllocateRaw(size, space, OLD_SPACE, kSimd128Unaligned); \ |
2964 if (!allocation.To(&result)) return allocation; \ | 2964 if (!allocation.To(&result)) return allocation; \ |
2965 } \ | 2965 } \ |
2966 \ | 2966 \ |
2967 result->set_map_no_write_barrier(type##_map()); \ | 2967 result->set_map_no_write_barrier(type##_map()); \ |
2968 Type* instance = Type::cast(result); \ | 2968 Type* instance = Type::cast(result); \ |
2969 for (int i = 0; i < lane_count; i++) { \ | 2969 for (int i = 0; i < lane_count; i++) { \ |
2970 instance->set_lane(i, lanes[i]); \ | 2970 instance->set_lane(i, lanes[i]); \ |
2971 } \ | 2971 } \ |
2972 return result; \ | 2972 return result; \ |
2973 } | 2973 } |
2974 SIMD128_TYPES(SIMD_ALLOCATE_DEFINITION) | 2974 SIMD128_TYPES(SIMD_ALLOCATE_DEFINITION) |
2975 #undef SIMD_ALLOCATE_DEFINITION | 2975 #undef SIMD_ALLOCATE_DEFINITION |
2976 | 2976 |
2977 | 2977 |
2978 AllocationResult Heap::AllocateCell(Object* value) { | 2978 AllocationResult Heap::AllocateCell(Object* value) { |
2979 int size = Cell::kSize; | 2979 int size = Cell::kSize; |
2980 STATIC_ASSERT(Cell::kSize <= Page::kMaxRegularHeapObjectSize); | 2980 STATIC_ASSERT(Cell::kSize <= Page::kMaxRegularHeapObjectSize); |
2981 | 2981 |
2982 HeapObject* result; | 2982 HeapObject* result = nullptr; |
2983 { | 2983 { |
2984 AllocationResult allocation = AllocateRaw(size, OLD_SPACE, OLD_SPACE); | 2984 AllocationResult allocation = AllocateRaw(size, OLD_SPACE, OLD_SPACE); |
2985 if (!allocation.To(&result)) return allocation; | 2985 if (!allocation.To(&result)) return allocation; |
2986 } | 2986 } |
2987 result->set_map_no_write_barrier(cell_map()); | 2987 result->set_map_no_write_barrier(cell_map()); |
2988 Cell::cast(result)->set_value(value); | 2988 Cell::cast(result)->set_value(value); |
2989 return result; | 2989 return result; |
2990 } | 2990 } |
2991 | 2991 |
2992 | 2992 |
2993 AllocationResult Heap::AllocatePropertyCell() { | 2993 AllocationResult Heap::AllocatePropertyCell() { |
2994 int size = PropertyCell::kSize; | 2994 int size = PropertyCell::kSize; |
2995 STATIC_ASSERT(PropertyCell::kSize <= Page::kMaxRegularHeapObjectSize); | 2995 STATIC_ASSERT(PropertyCell::kSize <= Page::kMaxRegularHeapObjectSize); |
2996 | 2996 |
2997 HeapObject* result; | 2997 HeapObject* result = nullptr; |
2998 AllocationResult allocation = AllocateRaw(size, OLD_SPACE, OLD_SPACE); | 2998 AllocationResult allocation = AllocateRaw(size, OLD_SPACE, OLD_SPACE); |
2999 if (!allocation.To(&result)) return allocation; | 2999 if (!allocation.To(&result)) return allocation; |
3000 | 3000 |
3001 result->set_map_no_write_barrier(global_property_cell_map()); | 3001 result->set_map_no_write_barrier(global_property_cell_map()); |
3002 PropertyCell* cell = PropertyCell::cast(result); | 3002 PropertyCell* cell = PropertyCell::cast(result); |
3003 cell->set_dependent_code(DependentCode::cast(empty_fixed_array()), | 3003 cell->set_dependent_code(DependentCode::cast(empty_fixed_array()), |
3004 SKIP_WRITE_BARRIER); | 3004 SKIP_WRITE_BARRIER); |
3005 cell->set_property_details(PropertyDetails(Smi::FromInt(0))); | 3005 cell->set_property_details(PropertyDetails(Smi::FromInt(0))); |
3006 cell->set_value(the_hole_value()); | 3006 cell->set_value(the_hole_value()); |
3007 return result; | 3007 return result; |
3008 } | 3008 } |
3009 | 3009 |
3010 | 3010 |
3011 AllocationResult Heap::AllocateWeakCell(HeapObject* value) { | 3011 AllocationResult Heap::AllocateWeakCell(HeapObject* value) { |
3012 int size = WeakCell::kSize; | 3012 int size = WeakCell::kSize; |
3013 STATIC_ASSERT(WeakCell::kSize <= Page::kMaxRegularHeapObjectSize); | 3013 STATIC_ASSERT(WeakCell::kSize <= Page::kMaxRegularHeapObjectSize); |
3014 HeapObject* result = NULL; | 3014 HeapObject* result = nullptr; |
3015 { | 3015 { |
3016 AllocationResult allocation = AllocateRaw(size, OLD_SPACE, OLD_SPACE); | 3016 AllocationResult allocation = AllocateRaw(size, OLD_SPACE, OLD_SPACE); |
3017 if (!allocation.To(&result)) return allocation; | 3017 if (!allocation.To(&result)) return allocation; |
3018 } | 3018 } |
3019 result->set_map_no_write_barrier(weak_cell_map()); | 3019 result->set_map_no_write_barrier(weak_cell_map()); |
3020 WeakCell::cast(result)->initialize(value); | 3020 WeakCell::cast(result)->initialize(value); |
3021 WeakCell::cast(result)->clear_next(this); | 3021 WeakCell::cast(result)->clear_next(this); |
3022 return result; | 3022 return result; |
3023 } | 3023 } |
3024 | 3024 |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3473 return FixedTypedArrayBase::cast( | 3473 return FixedTypedArrayBase::cast( |
3474 roots_[RootIndexForEmptyFixedTypedArray(map->elements_kind())]); | 3474 roots_[RootIndexForEmptyFixedTypedArray(map->elements_kind())]); |
3475 } | 3475 } |
3476 | 3476 |
3477 | 3477 |
3478 AllocationResult Heap::AllocateForeign(Address address, | 3478 AllocationResult Heap::AllocateForeign(Address address, |
3479 PretenureFlag pretenure) { | 3479 PretenureFlag pretenure) { |
3480 // Statically ensure that it is safe to allocate foreigns in paged spaces. | 3480 // Statically ensure that it is safe to allocate foreigns in paged spaces. |
3481 STATIC_ASSERT(Foreign::kSize <= Page::kMaxRegularHeapObjectSize); | 3481 STATIC_ASSERT(Foreign::kSize <= Page::kMaxRegularHeapObjectSize); |
3482 AllocationSpace space = (pretenure == TENURED) ? OLD_SPACE : NEW_SPACE; | 3482 AllocationSpace space = (pretenure == TENURED) ? OLD_SPACE : NEW_SPACE; |
3483 Foreign* result; | 3483 Foreign* result = nullptr; |
3484 AllocationResult allocation = Allocate(foreign_map(), space); | 3484 AllocationResult allocation = Allocate(foreign_map(), space); |
3485 if (!allocation.To(&result)) return allocation; | 3485 if (!allocation.To(&result)) return allocation; |
3486 result->set_foreign_address(address); | 3486 result->set_foreign_address(address); |
3487 return result; | 3487 return result; |
3488 } | 3488 } |
3489 | 3489 |
3490 | 3490 |
3491 AllocationResult Heap::AllocateByteArray(int length, PretenureFlag pretenure) { | 3491 AllocationResult Heap::AllocateByteArray(int length, PretenureFlag pretenure) { |
3492 if (length < 0 || length > ByteArray::kMaxLength) { | 3492 if (length < 0 || length > ByteArray::kMaxLength) { |
3493 v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true); | 3493 v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true); |
3494 } | 3494 } |
3495 int size = ByteArray::SizeFor(length); | 3495 int size = ByteArray::SizeFor(length); |
3496 AllocationSpace space = SelectSpace(size, pretenure); | 3496 AllocationSpace space = SelectSpace(size, pretenure); |
3497 HeapObject* result; | 3497 HeapObject* result = nullptr; |
3498 { | 3498 { |
3499 AllocationResult allocation = AllocateRaw(size, space, OLD_SPACE); | 3499 AllocationResult allocation = AllocateRaw(size, space, OLD_SPACE); |
3500 if (!allocation.To(&result)) return allocation; | 3500 if (!allocation.To(&result)) return allocation; |
3501 } | 3501 } |
3502 | 3502 |
3503 result->set_map_no_write_barrier(byte_array_map()); | 3503 result->set_map_no_write_barrier(byte_array_map()); |
3504 ByteArray::cast(result)->set_length(length); | 3504 ByteArray::cast(result)->set_length(length); |
3505 return result; | 3505 return result; |
3506 } | 3506 } |
3507 | 3507 |
3508 | 3508 |
3509 AllocationResult Heap::AllocateBytecodeArray(int length, | 3509 AllocationResult Heap::AllocateBytecodeArray(int length, |
3510 const byte* const raw_bytecodes, | 3510 const byte* const raw_bytecodes, |
3511 int frame_size, | 3511 int frame_size, |
3512 int parameter_count, | 3512 int parameter_count, |
3513 FixedArray* constant_pool) { | 3513 FixedArray* constant_pool) { |
3514 if (length < 0 || length > BytecodeArray::kMaxLength) { | 3514 if (length < 0 || length > BytecodeArray::kMaxLength) { |
3515 v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true); | 3515 v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true); |
3516 } | 3516 } |
3517 // Bytecode array is pretenured, so constant pool array should be to. | 3517 // Bytecode array is pretenured, so constant pool array should be to. |
3518 DCHECK(!InNewSpace(constant_pool)); | 3518 DCHECK(!InNewSpace(constant_pool)); |
3519 | 3519 |
3520 int size = BytecodeArray::SizeFor(length); | 3520 int size = BytecodeArray::SizeFor(length); |
3521 HeapObject* result; | 3521 HeapObject* result = nullptr; |
3522 { | 3522 { |
3523 AllocationResult allocation = AllocateRaw(size, OLD_SPACE, OLD_SPACE); | 3523 AllocationResult allocation = AllocateRaw(size, OLD_SPACE, OLD_SPACE); |
3524 if (!allocation.To(&result)) return allocation; | 3524 if (!allocation.To(&result)) return allocation; |
3525 } | 3525 } |
3526 | 3526 |
3527 result->set_map_no_write_barrier(bytecode_array_map()); | 3527 result->set_map_no_write_barrier(bytecode_array_map()); |
3528 BytecodeArray* instance = BytecodeArray::cast(result); | 3528 BytecodeArray* instance = BytecodeArray::cast(result); |
3529 instance->set_length(length); | 3529 instance->set_length(length); |
3530 instance->set_frame_size(frame_size); | 3530 instance->set_frame_size(frame_size); |
3531 instance->set_parameter_count(parameter_count); | 3531 instance->set_parameter_count(parameter_count); |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3698 profiler->UpdateObjectSizeEvent(object->address(), object->Size()); | 3698 profiler->UpdateObjectSizeEvent(object->address(), object->Size()); |
3699 } | 3699 } |
3700 } | 3700 } |
3701 | 3701 |
3702 | 3702 |
3703 AllocationResult Heap::AllocateFixedTypedArrayWithExternalPointer( | 3703 AllocationResult Heap::AllocateFixedTypedArrayWithExternalPointer( |
3704 int length, ExternalArrayType array_type, void* external_pointer, | 3704 int length, ExternalArrayType array_type, void* external_pointer, |
3705 PretenureFlag pretenure) { | 3705 PretenureFlag pretenure) { |
3706 int size = FixedTypedArrayBase::kHeaderSize; | 3706 int size = FixedTypedArrayBase::kHeaderSize; |
3707 AllocationSpace space = SelectSpace(size, pretenure); | 3707 AllocationSpace space = SelectSpace(size, pretenure); |
3708 HeapObject* result; | 3708 HeapObject* result = nullptr; |
3709 { | 3709 { |
3710 AllocationResult allocation = AllocateRaw(size, space, OLD_SPACE); | 3710 AllocationResult allocation = AllocateRaw(size, space, OLD_SPACE); |
3711 if (!allocation.To(&result)) return allocation; | 3711 if (!allocation.To(&result)) return allocation; |
3712 } | 3712 } |
3713 | 3713 |
3714 result->set_map_no_write_barrier(MapForFixedTypedArray(array_type)); | 3714 result->set_map_no_write_barrier(MapForFixedTypedArray(array_type)); |
3715 FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(result); | 3715 FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(result); |
3716 elements->set_base_pointer(Smi::FromInt(0), SKIP_WRITE_BARRIER); | 3716 elements->set_base_pointer(Smi::FromInt(0), SKIP_WRITE_BARRIER); |
3717 elements->set_external_pointer(external_pointer, SKIP_WRITE_BARRIER); | 3717 elements->set_external_pointer(external_pointer, SKIP_WRITE_BARRIER); |
3718 elements->set_length(length); | 3718 elements->set_length(length); |
(...skipping 24 matching lines...) Expand all Loading... |
3743 ExternalArrayType array_type, | 3743 ExternalArrayType array_type, |
3744 bool initialize, | 3744 bool initialize, |
3745 PretenureFlag pretenure) { | 3745 PretenureFlag pretenure) { |
3746 int element_size; | 3746 int element_size; |
3747 ElementsKind elements_kind; | 3747 ElementsKind elements_kind; |
3748 ForFixedTypedArray(array_type, &element_size, &elements_kind); | 3748 ForFixedTypedArray(array_type, &element_size, &elements_kind); |
3749 int size = OBJECT_POINTER_ALIGN(length * element_size + | 3749 int size = OBJECT_POINTER_ALIGN(length * element_size + |
3750 FixedTypedArrayBase::kDataOffset); | 3750 FixedTypedArrayBase::kDataOffset); |
3751 AllocationSpace space = SelectSpace(size, pretenure); | 3751 AllocationSpace space = SelectSpace(size, pretenure); |
3752 | 3752 |
3753 HeapObject* object; | 3753 HeapObject* object = nullptr; |
3754 AllocationResult allocation = AllocateRaw( | 3754 AllocationResult allocation = AllocateRaw( |
3755 size, space, OLD_SPACE, | 3755 size, space, OLD_SPACE, |
3756 array_type == kExternalFloat64Array ? kDoubleAligned : kWordAligned); | 3756 array_type == kExternalFloat64Array ? kDoubleAligned : kWordAligned); |
3757 if (!allocation.To(&object)) return allocation; | 3757 if (!allocation.To(&object)) return allocation; |
3758 | 3758 |
3759 object->set_map_no_write_barrier(MapForFixedTypedArray(array_type)); | 3759 object->set_map_no_write_barrier(MapForFixedTypedArray(array_type)); |
3760 FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(object); | 3760 FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(object); |
3761 elements->set_base_pointer(elements, SKIP_WRITE_BARRIER); | 3761 elements->set_base_pointer(elements, SKIP_WRITE_BARRIER); |
3762 elements->set_external_pointer( | 3762 elements->set_external_pointer( |
3763 ExternalReference::fixed_typed_array_base_data_offset().address(), | 3763 ExternalReference::fixed_typed_array_base_data_offset().address(), |
3764 SKIP_WRITE_BARRIER); | 3764 SKIP_WRITE_BARRIER); |
3765 elements->set_length(length); | 3765 elements->set_length(length); |
3766 if (initialize) memset(elements->DataPtr(), 0, elements->DataSize()); | 3766 if (initialize) memset(elements->DataPtr(), 0, elements->DataSize()); |
3767 return elements; | 3767 return elements; |
3768 } | 3768 } |
3769 | 3769 |
3770 | 3770 |
3771 AllocationResult Heap::AllocateCode(int object_size, bool immovable) { | 3771 AllocationResult Heap::AllocateCode(int object_size, bool immovable) { |
3772 DCHECK(IsAligned(static_cast<intptr_t>(object_size), kCodeAlignment)); | 3772 DCHECK(IsAligned(static_cast<intptr_t>(object_size), kCodeAlignment)); |
3773 AllocationResult allocation = | 3773 AllocationResult allocation = |
3774 AllocateRaw(object_size, CODE_SPACE, CODE_SPACE); | 3774 AllocateRaw(object_size, CODE_SPACE, CODE_SPACE); |
3775 | 3775 |
3776 HeapObject* result; | 3776 HeapObject* result = nullptr; |
3777 if (!allocation.To(&result)) return allocation; | 3777 if (!allocation.To(&result)) return allocation; |
3778 | 3778 |
3779 if (immovable) { | 3779 if (immovable) { |
3780 Address address = result->address(); | 3780 Address address = result->address(); |
3781 // Code objects which should stay at a fixed address are allocated either | 3781 // Code objects which should stay at a fixed address are allocated either |
3782 // in the first page of code space (objects on the first page of each space | 3782 // in the first page of code space (objects on the first page of each space |
3783 // are never moved) or in large object space. | 3783 // are never moved) or in large object space. |
3784 if (!code_space_->FirstPage()->Contains(address) && | 3784 if (!code_space_->FirstPage()->Contains(address) && |
3785 MemoryChunk::FromAddress(address)->owner()->identity() != LO_SPACE) { | 3785 MemoryChunk::FromAddress(address)->owner()->identity() != LO_SPACE) { |
3786 // Discard the first code allocation, which was on a page where it could | 3786 // Discard the first code allocation, which was on a page where it could |
(...skipping 13 matching lines...) Expand all Loading... |
3800 object_size <= code_space()->AreaSize()); | 3800 object_size <= code_space()->AreaSize()); |
3801 code->set_gc_metadata(Smi::FromInt(0)); | 3801 code->set_gc_metadata(Smi::FromInt(0)); |
3802 code->set_ic_age(global_ic_age_); | 3802 code->set_ic_age(global_ic_age_); |
3803 return code; | 3803 return code; |
3804 } | 3804 } |
3805 | 3805 |
3806 | 3806 |
3807 AllocationResult Heap::CopyCode(Code* code) { | 3807 AllocationResult Heap::CopyCode(Code* code) { |
3808 AllocationResult allocation; | 3808 AllocationResult allocation; |
3809 | 3809 |
3810 HeapObject* result = NULL; | 3810 HeapObject* result = nullptr; |
3811 // Allocate an object the same size as the code object. | 3811 // Allocate an object the same size as the code object. |
3812 int obj_size = code->Size(); | 3812 int obj_size = code->Size(); |
3813 allocation = AllocateRaw(obj_size, CODE_SPACE, CODE_SPACE); | 3813 allocation = AllocateRaw(obj_size, CODE_SPACE, CODE_SPACE); |
3814 if (!allocation.To(&result)) return allocation; | 3814 if (!allocation.To(&result)) return allocation; |
3815 | 3815 |
3816 // Copy code object. | 3816 // Copy code object. |
3817 Address old_addr = code->address(); | 3817 Address old_addr = code->address(); |
3818 Address new_addr = result->address(); | 3818 Address new_addr = result->address(); |
3819 CopyBlock(new_addr, old_addr, obj_size); | 3819 CopyBlock(new_addr, old_addr, obj_size); |
3820 Code* new_code = Code::cast(result); | 3820 Code* new_code = Code::cast(result); |
3821 | 3821 |
3822 // Relocate the copy. | 3822 // Relocate the copy. |
3823 DCHECK(IsAligned(bit_cast<intptr_t>(new_code->address()), kCodeAlignment)); | 3823 DCHECK(IsAligned(bit_cast<intptr_t>(new_code->address()), kCodeAlignment)); |
3824 DCHECK(isolate_->code_range() == NULL || !isolate_->code_range()->valid() || | 3824 DCHECK(isolate_->code_range() == NULL || !isolate_->code_range()->valid() || |
3825 isolate_->code_range()->contains(code->address()) || | 3825 isolate_->code_range()->contains(code->address()) || |
3826 obj_size <= code_space()->AreaSize()); | 3826 obj_size <= code_space()->AreaSize()); |
3827 new_code->Relocate(new_addr - old_addr); | 3827 new_code->Relocate(new_addr - old_addr); |
3828 return new_code; | 3828 return new_code; |
3829 } | 3829 } |
3830 | 3830 |
3831 | 3831 |
3832 AllocationResult Heap::CopyCode(Code* code, Vector<byte> reloc_info) { | 3832 AllocationResult Heap::CopyCode(Code* code, Vector<byte> reloc_info) { |
3833 // Allocate ByteArray before the Code object, so that we do not risk | 3833 // Allocate ByteArray before the Code object, so that we do not risk |
3834 // leaving uninitialized Code object (and breaking the heap). | 3834 // leaving uninitialized Code object (and breaking the heap). |
3835 ByteArray* reloc_info_array; | 3835 ByteArray* reloc_info_array = nullptr; |
3836 { | 3836 { |
3837 AllocationResult allocation = | 3837 AllocationResult allocation = |
3838 AllocateByteArray(reloc_info.length(), TENURED); | 3838 AllocateByteArray(reloc_info.length(), TENURED); |
3839 if (!allocation.To(&reloc_info_array)) return allocation; | 3839 if (!allocation.To(&reloc_info_array)) return allocation; |
3840 } | 3840 } |
3841 | 3841 |
3842 int new_body_size = RoundUp(code->instruction_size(), kObjectAlignment); | 3842 int new_body_size = RoundUp(code->instruction_size(), kObjectAlignment); |
3843 | 3843 |
3844 int new_obj_size = Code::SizeFor(new_body_size); | 3844 int new_obj_size = Code::SizeFor(new_body_size); |
3845 | 3845 |
3846 Address old_addr = code->address(); | 3846 Address old_addr = code->address(); |
3847 | 3847 |
3848 size_t relocation_offset = | 3848 size_t relocation_offset = |
3849 static_cast<size_t>(code->instruction_end() - old_addr); | 3849 static_cast<size_t>(code->instruction_end() - old_addr); |
3850 | 3850 |
3851 HeapObject* result; | 3851 HeapObject* result = nullptr; |
3852 AllocationResult allocation = | 3852 AllocationResult allocation = |
3853 AllocateRaw(new_obj_size, CODE_SPACE, CODE_SPACE); | 3853 AllocateRaw(new_obj_size, CODE_SPACE, CODE_SPACE); |
3854 if (!allocation.To(&result)) return allocation; | 3854 if (!allocation.To(&result)) return allocation; |
3855 | 3855 |
3856 // Copy code object. | 3856 // Copy code object. |
3857 Address new_addr = result->address(); | 3857 Address new_addr = result->address(); |
3858 | 3858 |
3859 // Copy header and instructions. | 3859 // Copy header and instructions. |
3860 CopyBytes(new_addr, old_addr, relocation_offset); | 3860 CopyBytes(new_addr, old_addr, relocation_offset); |
3861 | 3861 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3896 AllocationSite* allocation_site) { | 3896 AllocationSite* allocation_site) { |
3897 DCHECK(gc_state_ == NOT_IN_GC); | 3897 DCHECK(gc_state_ == NOT_IN_GC); |
3898 DCHECK(map->instance_type() != MAP_TYPE); | 3898 DCHECK(map->instance_type() != MAP_TYPE); |
3899 // If allocation failures are disallowed, we may allocate in a different | 3899 // If allocation failures are disallowed, we may allocate in a different |
3900 // space when new space is full and the object is not a large object. | 3900 // space when new space is full and the object is not a large object. |
3901 AllocationSpace retry_space = (space != NEW_SPACE) ? space : OLD_SPACE; | 3901 AllocationSpace retry_space = (space != NEW_SPACE) ? space : OLD_SPACE; |
3902 int size = map->instance_size(); | 3902 int size = map->instance_size(); |
3903 if (allocation_site != NULL) { | 3903 if (allocation_site != NULL) { |
3904 size += AllocationMemento::kSize; | 3904 size += AllocationMemento::kSize; |
3905 } | 3905 } |
3906 HeapObject* result; | 3906 HeapObject* result = nullptr; |
3907 AllocationResult allocation = AllocateRaw(size, space, retry_space); | 3907 AllocationResult allocation = AllocateRaw(size, space, retry_space); |
3908 if (!allocation.To(&result)) return allocation; | 3908 if (!allocation.To(&result)) return allocation; |
3909 // No need for write barrier since object is white and map is in old space. | 3909 // No need for write barrier since object is white and map is in old space. |
3910 result->set_map_no_write_barrier(map); | 3910 result->set_map_no_write_barrier(map); |
3911 if (allocation_site != NULL) { | 3911 if (allocation_site != NULL) { |
3912 AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>( | 3912 AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>( |
3913 reinterpret_cast<Address>(result) + map->instance_size()); | 3913 reinterpret_cast<Address>(result) + map->instance_size()); |
3914 InitializeAllocationMemento(alloc_memento, allocation_site); | 3914 InitializeAllocationMemento(alloc_memento, allocation_site); |
3915 } | 3915 } |
3916 return result; | 3916 return result; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3958 // AllocateGlobalObject to be properly initialized. | 3958 // AllocateGlobalObject to be properly initialized. |
3959 DCHECK(map->instance_type() != JS_GLOBAL_OBJECT_TYPE); | 3959 DCHECK(map->instance_type() != JS_GLOBAL_OBJECT_TYPE); |
3960 DCHECK(map->instance_type() != JS_BUILTINS_OBJECT_TYPE); | 3960 DCHECK(map->instance_type() != JS_BUILTINS_OBJECT_TYPE); |
3961 | 3961 |
3962 // Allocate the backing storage for the properties. | 3962 // Allocate the backing storage for the properties. |
3963 FixedArray* properties = empty_fixed_array(); | 3963 FixedArray* properties = empty_fixed_array(); |
3964 | 3964 |
3965 // Allocate the JSObject. | 3965 // Allocate the JSObject. |
3966 int size = map->instance_size(); | 3966 int size = map->instance_size(); |
3967 AllocationSpace space = SelectSpace(size, pretenure); | 3967 AllocationSpace space = SelectSpace(size, pretenure); |
3968 JSObject* js_obj; | 3968 JSObject* js_obj = nullptr; |
3969 AllocationResult allocation = Allocate(map, space, allocation_site); | 3969 AllocationResult allocation = Allocate(map, space, allocation_site); |
3970 if (!allocation.To(&js_obj)) return allocation; | 3970 if (!allocation.To(&js_obj)) return allocation; |
3971 | 3971 |
3972 // Initialize the JSObject. | 3972 // Initialize the JSObject. |
3973 InitializeJSObjectFromMap(js_obj, properties, map); | 3973 InitializeJSObjectFromMap(js_obj, properties, map); |
3974 DCHECK(js_obj->HasFastElements() || js_obj->HasFixedTypedArrayElements()); | 3974 DCHECK(js_obj->HasFastElements() || js_obj->HasFixedTypedArrayElements()); |
3975 return js_obj; | 3975 return js_obj; |
3976 } | 3976 } |
3977 | 3977 |
3978 | 3978 |
3979 AllocationResult Heap::AllocateJSObject(JSFunction* constructor, | 3979 AllocationResult Heap::AllocateJSObject(JSFunction* constructor, |
3980 PretenureFlag pretenure, | 3980 PretenureFlag pretenure, |
3981 AllocationSite* allocation_site) { | 3981 AllocationSite* allocation_site) { |
3982 DCHECK(constructor->has_initial_map()); | 3982 DCHECK(constructor->has_initial_map()); |
3983 | 3983 |
3984 // Allocate the object based on the constructors initial map. | 3984 // Allocate the object based on the constructors initial map. |
3985 AllocationResult allocation = AllocateJSObjectFromMap( | 3985 AllocationResult allocation = AllocateJSObjectFromMap( |
3986 constructor->initial_map(), pretenure, allocation_site); | 3986 constructor->initial_map(), pretenure, allocation_site); |
3987 #ifdef DEBUG | 3987 #ifdef DEBUG |
3988 // Make sure result is NOT a global object if valid. | 3988 // Make sure result is NOT a global object if valid. |
3989 HeapObject* obj; | 3989 HeapObject* obj = nullptr; |
3990 DCHECK(!allocation.To(&obj) || !obj->IsGlobalObject()); | 3990 DCHECK(!allocation.To(&obj) || !obj->IsGlobalObject()); |
3991 #endif | 3991 #endif |
3992 return allocation; | 3992 return allocation; |
3993 } | 3993 } |
3994 | 3994 |
3995 | 3995 |
3996 AllocationResult Heap::CopyJSObject(JSObject* source, AllocationSite* site) { | 3996 AllocationResult Heap::CopyJSObject(JSObject* source, AllocationSite* site) { |
3997 // Make the clone. | 3997 // Make the clone. |
3998 Map* map = source->map(); | 3998 Map* map = source->map(); |
3999 | 3999 |
4000 // We can only clone normal objects or arrays. Copying anything else | 4000 // We can only clone normal objects or arrays. Copying anything else |
4001 // will break invariants. | 4001 // will break invariants. |
4002 CHECK(map->instance_type() == JS_OBJECT_TYPE || | 4002 CHECK(map->instance_type() == JS_OBJECT_TYPE || |
4003 map->instance_type() == JS_ARRAY_TYPE); | 4003 map->instance_type() == JS_ARRAY_TYPE); |
4004 | 4004 |
4005 int object_size = map->instance_size(); | 4005 int object_size = map->instance_size(); |
4006 HeapObject* clone; | 4006 HeapObject* clone = nullptr; |
4007 | 4007 |
4008 DCHECK(site == NULL || AllocationSite::CanTrack(map->instance_type())); | 4008 DCHECK(site == NULL || AllocationSite::CanTrack(map->instance_type())); |
4009 | 4009 |
4010 WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER; | 4010 WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER; |
4011 | 4011 |
4012 // If we're forced to always allocate, we use the general allocation | 4012 // If we're forced to always allocate, we use the general allocation |
4013 // functions which may leave us with an object in old space. | 4013 // functions which may leave us with an object in old space. |
4014 if (always_allocate()) { | 4014 if (always_allocate()) { |
4015 { | 4015 { |
4016 AllocationResult allocation = | 4016 AllocationResult allocation = |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4067 InitializeAllocationMemento(alloc_memento, site); | 4067 InitializeAllocationMemento(alloc_memento, site); |
4068 } | 4068 } |
4069 } | 4069 } |
4070 | 4070 |
4071 SLOW_DCHECK(JSObject::cast(clone)->GetElementsKind() == | 4071 SLOW_DCHECK(JSObject::cast(clone)->GetElementsKind() == |
4072 source->GetElementsKind()); | 4072 source->GetElementsKind()); |
4073 FixedArrayBase* elements = FixedArrayBase::cast(source->elements()); | 4073 FixedArrayBase* elements = FixedArrayBase::cast(source->elements()); |
4074 FixedArray* properties = FixedArray::cast(source->properties()); | 4074 FixedArray* properties = FixedArray::cast(source->properties()); |
4075 // Update elements if necessary. | 4075 // Update elements if necessary. |
4076 if (elements->length() > 0) { | 4076 if (elements->length() > 0) { |
4077 FixedArrayBase* elem; | 4077 FixedArrayBase* elem = nullptr; |
4078 { | 4078 { |
4079 AllocationResult allocation; | 4079 AllocationResult allocation; |
4080 if (elements->map() == fixed_cow_array_map()) { | 4080 if (elements->map() == fixed_cow_array_map()) { |
4081 allocation = FixedArray::cast(elements); | 4081 allocation = FixedArray::cast(elements); |
4082 } else if (source->HasFastDoubleElements()) { | 4082 } else if (source->HasFastDoubleElements()) { |
4083 allocation = CopyFixedDoubleArray(FixedDoubleArray::cast(elements)); | 4083 allocation = CopyFixedDoubleArray(FixedDoubleArray::cast(elements)); |
4084 } else { | 4084 } else { |
4085 allocation = CopyFixedArray(FixedArray::cast(elements)); | 4085 allocation = CopyFixedArray(FixedArray::cast(elements)); |
4086 } | 4086 } |
4087 if (!allocation.To(&elem)) return allocation; | 4087 if (!allocation.To(&elem)) return allocation; |
4088 } | 4088 } |
4089 JSObject::cast(clone)->set_elements(elem, wb_mode); | 4089 JSObject::cast(clone)->set_elements(elem, wb_mode); |
4090 } | 4090 } |
4091 // Update properties if necessary. | 4091 // Update properties if necessary. |
4092 if (properties->length() > 0) { | 4092 if (properties->length() > 0) { |
4093 FixedArray* prop; | 4093 FixedArray* prop = nullptr; |
4094 { | 4094 { |
4095 AllocationResult allocation = CopyFixedArray(properties); | 4095 AllocationResult allocation = CopyFixedArray(properties); |
4096 if (!allocation.To(&prop)) return allocation; | 4096 if (!allocation.To(&prop)) return allocation; |
4097 } | 4097 } |
4098 JSObject::cast(clone)->set_properties(prop, wb_mode); | 4098 JSObject::cast(clone)->set_properties(prop, wb_mode); |
4099 } | 4099 } |
4100 // Return the new clone. | 4100 // Return the new clone. |
4101 return clone; | 4101 return clone; |
4102 } | 4102 } |
4103 | 4103 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4161 if (is_one_byte) { | 4161 if (is_one_byte) { |
4162 map = one_byte_internalized_string_map(); | 4162 map = one_byte_internalized_string_map(); |
4163 size = SeqOneByteString::SizeFor(chars); | 4163 size = SeqOneByteString::SizeFor(chars); |
4164 } else { | 4164 } else { |
4165 map = internalized_string_map(); | 4165 map = internalized_string_map(); |
4166 size = SeqTwoByteString::SizeFor(chars); | 4166 size = SeqTwoByteString::SizeFor(chars); |
4167 } | 4167 } |
4168 AllocationSpace space = SelectSpace(size, TENURED); | 4168 AllocationSpace space = SelectSpace(size, TENURED); |
4169 | 4169 |
4170 // Allocate string. | 4170 // Allocate string. |
4171 HeapObject* result; | 4171 HeapObject* result = nullptr; |
4172 { | 4172 { |
4173 AllocationResult allocation = AllocateRaw(size, space, OLD_SPACE); | 4173 AllocationResult allocation = AllocateRaw(size, space, OLD_SPACE); |
4174 if (!allocation.To(&result)) return allocation; | 4174 if (!allocation.To(&result)) return allocation; |
4175 } | 4175 } |
4176 | 4176 |
4177 result->set_map_no_write_barrier(map); | 4177 result->set_map_no_write_barrier(map); |
4178 // Set length and hash fields of the allocated string. | 4178 // Set length and hash fields of the allocated string. |
4179 String* answer = String::cast(result); | 4179 String* answer = String::cast(result); |
4180 answer->set_length(chars); | 4180 answer->set_length(chars); |
4181 answer->set_hash_field(hash_field); | 4181 answer->set_hash_field(hash_field); |
(...skipping 21 matching lines...) Expand all Loading... |
4203 | 4203 |
4204 | 4204 |
4205 AllocationResult Heap::AllocateRawOneByteString(int length, | 4205 AllocationResult Heap::AllocateRawOneByteString(int length, |
4206 PretenureFlag pretenure) { | 4206 PretenureFlag pretenure) { |
4207 DCHECK_LE(0, length); | 4207 DCHECK_LE(0, length); |
4208 DCHECK_GE(String::kMaxLength, length); | 4208 DCHECK_GE(String::kMaxLength, length); |
4209 int size = SeqOneByteString::SizeFor(length); | 4209 int size = SeqOneByteString::SizeFor(length); |
4210 DCHECK(size <= SeqOneByteString::kMaxSize); | 4210 DCHECK(size <= SeqOneByteString::kMaxSize); |
4211 AllocationSpace space = SelectSpace(size, pretenure); | 4211 AllocationSpace space = SelectSpace(size, pretenure); |
4212 | 4212 |
4213 HeapObject* result; | 4213 HeapObject* result = nullptr; |
4214 { | 4214 { |
4215 AllocationResult allocation = AllocateRaw(size, space, OLD_SPACE); | 4215 AllocationResult allocation = AllocateRaw(size, space, OLD_SPACE); |
4216 if (!allocation.To(&result)) return allocation; | 4216 if (!allocation.To(&result)) return allocation; |
4217 } | 4217 } |
4218 | 4218 |
4219 // Partially initialize the object. | 4219 // Partially initialize the object. |
4220 result->set_map_no_write_barrier(one_byte_string_map()); | 4220 result->set_map_no_write_barrier(one_byte_string_map()); |
4221 String::cast(result)->set_length(length); | 4221 String::cast(result)->set_length(length); |
4222 String::cast(result)->set_hash_field(String::kEmptyHashField); | 4222 String::cast(result)->set_hash_field(String::kEmptyHashField); |
4223 DCHECK_EQ(size, HeapObject::cast(result)->Size()); | 4223 DCHECK_EQ(size, HeapObject::cast(result)->Size()); |
4224 | 4224 |
4225 return result; | 4225 return result; |
4226 } | 4226 } |
4227 | 4227 |
4228 | 4228 |
4229 AllocationResult Heap::AllocateRawTwoByteString(int length, | 4229 AllocationResult Heap::AllocateRawTwoByteString(int length, |
4230 PretenureFlag pretenure) { | 4230 PretenureFlag pretenure) { |
4231 DCHECK_LE(0, length); | 4231 DCHECK_LE(0, length); |
4232 DCHECK_GE(String::kMaxLength, length); | 4232 DCHECK_GE(String::kMaxLength, length); |
4233 int size = SeqTwoByteString::SizeFor(length); | 4233 int size = SeqTwoByteString::SizeFor(length); |
4234 DCHECK(size <= SeqTwoByteString::kMaxSize); | 4234 DCHECK(size <= SeqTwoByteString::kMaxSize); |
4235 AllocationSpace space = SelectSpace(size, pretenure); | 4235 AllocationSpace space = SelectSpace(size, pretenure); |
4236 | 4236 |
4237 HeapObject* result; | 4237 HeapObject* result = nullptr; |
4238 { | 4238 { |
4239 AllocationResult allocation = AllocateRaw(size, space, OLD_SPACE); | 4239 AllocationResult allocation = AllocateRaw(size, space, OLD_SPACE); |
4240 if (!allocation.To(&result)) return allocation; | 4240 if (!allocation.To(&result)) return allocation; |
4241 } | 4241 } |
4242 | 4242 |
4243 // Partially initialize the object. | 4243 // Partially initialize the object. |
4244 result->set_map_no_write_barrier(string_map()); | 4244 result->set_map_no_write_barrier(string_map()); |
4245 String::cast(result)->set_length(length); | 4245 String::cast(result)->set_length(length); |
4246 String::cast(result)->set_hash_field(String::kEmptyHashField); | 4246 String::cast(result)->set_hash_field(String::kEmptyHashField); |
4247 DCHECK_EQ(size, HeapObject::cast(result)->Size()); | 4247 DCHECK_EQ(size, HeapObject::cast(result)->Size()); |
4248 return result; | 4248 return result; |
4249 } | 4249 } |
4250 | 4250 |
4251 | 4251 |
4252 AllocationResult Heap::AllocateEmptyFixedArray() { | 4252 AllocationResult Heap::AllocateEmptyFixedArray() { |
4253 int size = FixedArray::SizeFor(0); | 4253 int size = FixedArray::SizeFor(0); |
4254 HeapObject* result; | 4254 HeapObject* result = nullptr; |
4255 { | 4255 { |
4256 AllocationResult allocation = AllocateRaw(size, OLD_SPACE, OLD_SPACE); | 4256 AllocationResult allocation = AllocateRaw(size, OLD_SPACE, OLD_SPACE); |
4257 if (!allocation.To(&result)) return allocation; | 4257 if (!allocation.To(&result)) return allocation; |
4258 } | 4258 } |
4259 // Initialize the object. | 4259 // Initialize the object. |
4260 result->set_map_no_write_barrier(fixed_array_map()); | 4260 result->set_map_no_write_barrier(fixed_array_map()); |
4261 FixedArray::cast(result)->set_length(0); | 4261 FixedArray::cast(result)->set_length(0); |
4262 return result; | 4262 return result; |
4263 } | 4263 } |
4264 | 4264 |
4265 | 4265 |
4266 AllocationResult Heap::CopyAndTenureFixedCOWArray(FixedArray* src) { | 4266 AllocationResult Heap::CopyAndTenureFixedCOWArray(FixedArray* src) { |
4267 if (!InNewSpace(src)) { | 4267 if (!InNewSpace(src)) { |
4268 return src; | 4268 return src; |
4269 } | 4269 } |
4270 | 4270 |
4271 int len = src->length(); | 4271 int len = src->length(); |
4272 HeapObject* obj; | 4272 HeapObject* obj = nullptr; |
4273 { | 4273 { |
4274 AllocationResult allocation = AllocateRawFixedArray(len, TENURED); | 4274 AllocationResult allocation = AllocateRawFixedArray(len, TENURED); |
4275 if (!allocation.To(&obj)) return allocation; | 4275 if (!allocation.To(&obj)) return allocation; |
4276 } | 4276 } |
4277 obj->set_map_no_write_barrier(fixed_array_map()); | 4277 obj->set_map_no_write_barrier(fixed_array_map()); |
4278 FixedArray* result = FixedArray::cast(obj); | 4278 FixedArray* result = FixedArray::cast(obj); |
4279 result->set_length(len); | 4279 result->set_length(len); |
4280 | 4280 |
4281 // Copy the content. | 4281 // Copy the content. |
4282 DisallowHeapAllocation no_gc; | 4282 DisallowHeapAllocation no_gc; |
(...skipping 12 matching lines...) Expand all Loading... |
4295 ExternalArrayType array_type) { | 4295 ExternalArrayType array_type) { |
4296 return AllocateFixedTypedArray(0, array_type, false, TENURED); | 4296 return AllocateFixedTypedArray(0, array_type, false, TENURED); |
4297 } | 4297 } |
4298 | 4298 |
4299 | 4299 |
4300 AllocationResult Heap::CopyFixedArrayAndGrow(FixedArray* src, int grow_by, | 4300 AllocationResult Heap::CopyFixedArrayAndGrow(FixedArray* src, int grow_by, |
4301 PretenureFlag pretenure) { | 4301 PretenureFlag pretenure) { |
4302 int old_len = src->length(); | 4302 int old_len = src->length(); |
4303 int new_len = old_len + grow_by; | 4303 int new_len = old_len + grow_by; |
4304 DCHECK(new_len >= old_len); | 4304 DCHECK(new_len >= old_len); |
4305 HeapObject* obj; | 4305 HeapObject* obj = nullptr; |
4306 { | 4306 { |
4307 AllocationResult allocation = AllocateRawFixedArray(new_len, pretenure); | 4307 AllocationResult allocation = AllocateRawFixedArray(new_len, pretenure); |
4308 if (!allocation.To(&obj)) return allocation; | 4308 if (!allocation.To(&obj)) return allocation; |
4309 } | 4309 } |
4310 obj->set_map_no_write_barrier(fixed_array_map()); | 4310 obj->set_map_no_write_barrier(fixed_array_map()); |
4311 FixedArray* result = FixedArray::cast(obj); | 4311 FixedArray* result = FixedArray::cast(obj); |
4312 result->set_length(new_len); | 4312 result->set_length(new_len); |
4313 | 4313 |
4314 // Copy the content. | 4314 // Copy the content. |
4315 DisallowHeapAllocation no_gc; | 4315 DisallowHeapAllocation no_gc; |
4316 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 4316 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
4317 for (int i = 0; i < old_len; i++) result->set(i, src->get(i), mode); | 4317 for (int i = 0; i < old_len; i++) result->set(i, src->get(i), mode); |
4318 MemsetPointer(result->data_start() + old_len, undefined_value(), grow_by); | 4318 MemsetPointer(result->data_start() + old_len, undefined_value(), grow_by); |
4319 return result; | 4319 return result; |
4320 } | 4320 } |
4321 | 4321 |
4322 | 4322 |
4323 AllocationResult Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) { | 4323 AllocationResult Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) { |
4324 int len = src->length(); | 4324 int len = src->length(); |
4325 HeapObject* obj; | 4325 HeapObject* obj = nullptr; |
4326 { | 4326 { |
4327 AllocationResult allocation = AllocateRawFixedArray(len, NOT_TENURED); | 4327 AllocationResult allocation = AllocateRawFixedArray(len, NOT_TENURED); |
4328 if (!allocation.To(&obj)) return allocation; | 4328 if (!allocation.To(&obj)) return allocation; |
4329 } | 4329 } |
4330 if (InNewSpace(obj)) { | 4330 if (InNewSpace(obj)) { |
4331 obj->set_map_no_write_barrier(map); | 4331 obj->set_map_no_write_barrier(map); |
4332 CopyBlock(obj->address() + kPointerSize, src->address() + kPointerSize, | 4332 CopyBlock(obj->address() + kPointerSize, src->address() + kPointerSize, |
4333 FixedArray::SizeFor(len) - kPointerSize); | 4333 FixedArray::SizeFor(len) - kPointerSize); |
4334 return obj; | 4334 return obj; |
4335 } | 4335 } |
4336 obj->set_map_no_write_barrier(map); | 4336 obj->set_map_no_write_barrier(map); |
4337 FixedArray* result = FixedArray::cast(obj); | 4337 FixedArray* result = FixedArray::cast(obj); |
4338 result->set_length(len); | 4338 result->set_length(len); |
4339 | 4339 |
4340 // Copy the content. | 4340 // Copy the content. |
4341 DisallowHeapAllocation no_gc; | 4341 DisallowHeapAllocation no_gc; |
4342 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 4342 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
4343 for (int i = 0; i < len; i++) result->set(i, src->get(i), mode); | 4343 for (int i = 0; i < len; i++) result->set(i, src->get(i), mode); |
4344 return result; | 4344 return result; |
4345 } | 4345 } |
4346 | 4346 |
4347 | 4347 |
4348 AllocationResult Heap::CopyFixedDoubleArrayWithMap(FixedDoubleArray* src, | 4348 AllocationResult Heap::CopyFixedDoubleArrayWithMap(FixedDoubleArray* src, |
4349 Map* map) { | 4349 Map* map) { |
4350 int len = src->length(); | 4350 int len = src->length(); |
4351 HeapObject* obj; | 4351 HeapObject* obj = nullptr; |
4352 { | 4352 { |
4353 AllocationResult allocation = AllocateRawFixedDoubleArray(len, NOT_TENURED); | 4353 AllocationResult allocation = AllocateRawFixedDoubleArray(len, NOT_TENURED); |
4354 if (!allocation.To(&obj)) return allocation; | 4354 if (!allocation.To(&obj)) return allocation; |
4355 } | 4355 } |
4356 obj->set_map_no_write_barrier(map); | 4356 obj->set_map_no_write_barrier(map); |
4357 CopyBlock(obj->address() + FixedDoubleArray::kLengthOffset, | 4357 CopyBlock(obj->address() + FixedDoubleArray::kLengthOffset, |
4358 src->address() + FixedDoubleArray::kLengthOffset, | 4358 src->address() + FixedDoubleArray::kLengthOffset, |
4359 FixedDoubleArray::SizeFor(len) - FixedDoubleArray::kLengthOffset); | 4359 FixedDoubleArray::SizeFor(len) - FixedDoubleArray::kLengthOffset); |
4360 return obj; | 4360 return obj; |
4361 } | 4361 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4396 | 4396 |
4397 | 4397 |
4398 AllocationResult Heap::AllocateFixedArray(int length, PretenureFlag pretenure) { | 4398 AllocationResult Heap::AllocateFixedArray(int length, PretenureFlag pretenure) { |
4399 return AllocateFixedArrayWithFiller(length, pretenure, undefined_value()); | 4399 return AllocateFixedArrayWithFiller(length, pretenure, undefined_value()); |
4400 } | 4400 } |
4401 | 4401 |
4402 | 4402 |
4403 AllocationResult Heap::AllocateUninitializedFixedArray(int length) { | 4403 AllocationResult Heap::AllocateUninitializedFixedArray(int length) { |
4404 if (length == 0) return empty_fixed_array(); | 4404 if (length == 0) return empty_fixed_array(); |
4405 | 4405 |
4406 HeapObject* obj; | 4406 HeapObject* obj = nullptr; |
4407 { | 4407 { |
4408 AllocationResult allocation = AllocateRawFixedArray(length, NOT_TENURED); | 4408 AllocationResult allocation = AllocateRawFixedArray(length, NOT_TENURED); |
4409 if (!allocation.To(&obj)) return allocation; | 4409 if (!allocation.To(&obj)) return allocation; |
4410 } | 4410 } |
4411 | 4411 |
4412 obj->set_map_no_write_barrier(fixed_array_map()); | 4412 obj->set_map_no_write_barrier(fixed_array_map()); |
4413 FixedArray::cast(obj)->set_length(length); | 4413 FixedArray::cast(obj)->set_length(length); |
4414 return obj; | 4414 return obj; |
4415 } | 4415 } |
4416 | 4416 |
4417 | 4417 |
4418 AllocationResult Heap::AllocateUninitializedFixedDoubleArray( | 4418 AllocationResult Heap::AllocateUninitializedFixedDoubleArray( |
4419 int length, PretenureFlag pretenure) { | 4419 int length, PretenureFlag pretenure) { |
4420 if (length == 0) return empty_fixed_array(); | 4420 if (length == 0) return empty_fixed_array(); |
4421 | 4421 |
4422 HeapObject* elements; | 4422 HeapObject* elements = nullptr; |
4423 AllocationResult allocation = AllocateRawFixedDoubleArray(length, pretenure); | 4423 AllocationResult allocation = AllocateRawFixedDoubleArray(length, pretenure); |
4424 if (!allocation.To(&elements)) return allocation; | 4424 if (!allocation.To(&elements)) return allocation; |
4425 | 4425 |
4426 elements->set_map_no_write_barrier(fixed_double_array_map()); | 4426 elements->set_map_no_write_barrier(fixed_double_array_map()); |
4427 FixedDoubleArray::cast(elements)->set_length(length); | 4427 FixedDoubleArray::cast(elements)->set_length(length); |
4428 return elements; | 4428 return elements; |
4429 } | 4429 } |
4430 | 4430 |
4431 | 4431 |
4432 AllocationResult Heap::AllocateRawFixedDoubleArray(int length, | 4432 AllocationResult Heap::AllocateRawFixedDoubleArray(int length, |
4433 PretenureFlag pretenure) { | 4433 PretenureFlag pretenure) { |
4434 if (length < 0 || length > FixedDoubleArray::kMaxLength) { | 4434 if (length < 0 || length > FixedDoubleArray::kMaxLength) { |
4435 v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", | 4435 v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", |
4436 kDoubleAligned); | 4436 kDoubleAligned); |
4437 } | 4437 } |
4438 int size = FixedDoubleArray::SizeFor(length); | 4438 int size = FixedDoubleArray::SizeFor(length); |
4439 AllocationSpace space = SelectSpace(size, pretenure); | 4439 AllocationSpace space = SelectSpace(size, pretenure); |
4440 | 4440 |
4441 HeapObject* object; | 4441 HeapObject* object = nullptr; |
4442 { | 4442 { |
4443 AllocationResult allocation = | 4443 AllocationResult allocation = |
4444 AllocateRaw(size, space, OLD_SPACE, kDoubleAligned); | 4444 AllocateRaw(size, space, OLD_SPACE, kDoubleAligned); |
4445 if (!allocation.To(&object)) return allocation; | 4445 if (!allocation.To(&object)) return allocation; |
4446 } | 4446 } |
4447 | 4447 |
4448 return object; | 4448 return object; |
4449 } | 4449 } |
4450 | 4450 |
4451 | 4451 |
4452 AllocationResult Heap::AllocateSymbol() { | 4452 AllocationResult Heap::AllocateSymbol() { |
4453 // Statically ensure that it is safe to allocate symbols in paged spaces. | 4453 // Statically ensure that it is safe to allocate symbols in paged spaces. |
4454 STATIC_ASSERT(Symbol::kSize <= Page::kMaxRegularHeapObjectSize); | 4454 STATIC_ASSERT(Symbol::kSize <= Page::kMaxRegularHeapObjectSize); |
4455 | 4455 |
4456 HeapObject* result = NULL; | 4456 HeapObject* result = nullptr; |
4457 AllocationResult allocation = | 4457 AllocationResult allocation = |
4458 AllocateRaw(Symbol::kSize, OLD_SPACE, OLD_SPACE); | 4458 AllocateRaw(Symbol::kSize, OLD_SPACE, OLD_SPACE); |
4459 if (!allocation.To(&result)) return allocation; | 4459 if (!allocation.To(&result)) return allocation; |
4460 | 4460 |
4461 result->set_map_no_write_barrier(symbol_map()); | 4461 result->set_map_no_write_barrier(symbol_map()); |
4462 | 4462 |
4463 // Generate a random hash value. | 4463 // Generate a random hash value. |
4464 int hash; | 4464 int hash; |
4465 int attempts = 0; | 4465 int attempts = 0; |
4466 do { | 4466 do { |
(...skipping 20 matching lines...) Expand all Loading... |
4487 map = name##_map(); \ | 4487 map = name##_map(); \ |
4488 break; | 4488 break; |
4489 STRUCT_LIST(MAKE_CASE) | 4489 STRUCT_LIST(MAKE_CASE) |
4490 #undef MAKE_CASE | 4490 #undef MAKE_CASE |
4491 default: | 4491 default: |
4492 UNREACHABLE(); | 4492 UNREACHABLE(); |
4493 return exception(); | 4493 return exception(); |
4494 } | 4494 } |
4495 int size = map->instance_size(); | 4495 int size = map->instance_size(); |
4496 AllocationSpace space = SelectSpace(size, TENURED); | 4496 AllocationSpace space = SelectSpace(size, TENURED); |
4497 Struct* result; | 4497 Struct* result = nullptr; |
4498 { | 4498 { |
4499 AllocationResult allocation = Allocate(map, space); | 4499 AllocationResult allocation = Allocate(map, space); |
4500 if (!allocation.To(&result)) return allocation; | 4500 if (!allocation.To(&result)) return allocation; |
4501 } | 4501 } |
4502 result->InitializeBody(size); | 4502 result->InitializeBody(size); |
4503 return result; | 4503 return result; |
4504 } | 4504 } |
4505 | 4505 |
4506 | 4506 |
4507 bool Heap::IsHeapIterable() { | 4507 bool Heap::IsHeapIterable() { |
(...skipping 2163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6671 *object_sub_type = "CODE_AGE/" #name; \ | 6671 *object_sub_type = "CODE_AGE/" #name; \ |
6672 return true; | 6672 return true; |
6673 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) | 6673 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) |
6674 #undef COMPARE_AND_RETURN_NAME | 6674 #undef COMPARE_AND_RETURN_NAME |
6675 } | 6675 } |
6676 return false; | 6676 return false; |
6677 } | 6677 } |
6678 | 6678 |
6679 } // namespace internal | 6679 } // namespace internal |
6680 } // namespace v8 | 6680 } // namespace v8 |
OLD | NEW |