OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 21 matching lines...) Expand all Loading... |
32 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
33 #include "codegen-inl.h" | 33 #include "codegen-inl.h" |
34 #include "compilation-cache.h" | 34 #include "compilation-cache.h" |
35 #include "debug.h" | 35 #include "debug.h" |
36 #include "heap-profiler.h" | 36 #include "heap-profiler.h" |
37 #include "global-handles.h" | 37 #include "global-handles.h" |
38 #include "mark-compact.h" | 38 #include "mark-compact.h" |
39 #include "natives.h" | 39 #include "natives.h" |
40 #include "scanner.h" | 40 #include "scanner.h" |
41 #include "scopeinfo.h" | 41 #include "scopeinfo.h" |
| 42 #include "snapshot.h" |
42 #include "v8threads.h" | 43 #include "v8threads.h" |
43 #if V8_TARGET_ARCH_ARM && V8_NATIVE_REGEXP | 44 #if V8_TARGET_ARCH_ARM && V8_NATIVE_REGEXP |
44 #include "regexp-macro-assembler.h" | 45 #include "regexp-macro-assembler.h" |
45 #endif | 46 #endif |
46 | 47 |
47 namespace v8 { | 48 namespace v8 { |
48 namespace internal { | 49 namespace internal { |
49 | 50 |
50 | 51 |
51 String* Heap::hidden_symbol_; | 52 String* Heap::hidden_symbol_; |
(...skipping 15 matching lines...) Expand all Loading... |
67 int Heap::old_gen_allocation_limit_ = kMinimumAllocationLimit; | 68 int Heap::old_gen_allocation_limit_ = kMinimumAllocationLimit; |
68 | 69 |
69 int Heap::old_gen_exhausted_ = false; | 70 int Heap::old_gen_exhausted_ = false; |
70 | 71 |
71 int Heap::amount_of_external_allocated_memory_ = 0; | 72 int Heap::amount_of_external_allocated_memory_ = 0; |
72 int Heap::amount_of_external_allocated_memory_at_last_global_gc_ = 0; | 73 int Heap::amount_of_external_allocated_memory_at_last_global_gc_ = 0; |
73 | 74 |
74 // semispace_size_ should be a power of 2 and old_generation_size_ should be | 75 // semispace_size_ should be a power of 2 and old_generation_size_ should be |
75 // a multiple of Page::kPageSize. | 76 // a multiple of Page::kPageSize. |
76 #if defined(ANDROID) | 77 #if defined(ANDROID) |
77 int Heap::semispace_size_ = 512*KB; | 78 int Heap::max_semispace_size_ = 512*KB; |
78 int Heap::old_generation_size_ = 128*MB; | 79 int Heap::max_old_generation_size_ = 128*MB; |
79 int Heap::initial_semispace_size_ = 128*KB; | 80 int Heap::initial_semispace_size_ = 128*KB; |
80 size_t Heap::code_range_size_ = 0; | 81 size_t Heap::code_range_size_ = 0; |
81 #elif defined(V8_TARGET_ARCH_X64) | 82 #elif defined(V8_TARGET_ARCH_X64) |
82 int Heap::semispace_size_ = 16*MB; | 83 int Heap::max_semispace_size_ = 16*MB; |
83 int Heap::old_generation_size_ = 1*GB; | 84 int Heap::max_old_generation_size_ = 1*GB; |
84 int Heap::initial_semispace_size_ = 1*MB; | 85 int Heap::initial_semispace_size_ = 1*MB; |
85 size_t Heap::code_range_size_ = 512*MB; | 86 size_t Heap::code_range_size_ = 512*MB; |
86 #else | 87 #else |
87 int Heap::semispace_size_ = 8*MB; | 88 int Heap::max_semispace_size_ = 8*MB; |
88 int Heap::old_generation_size_ = 512*MB; | 89 int Heap::max_old_generation_size_ = 512*MB; |
89 int Heap::initial_semispace_size_ = 512*KB; | 90 int Heap::initial_semispace_size_ = 512*KB; |
90 size_t Heap::code_range_size_ = 0; | 91 size_t Heap::code_range_size_ = 0; |
91 #endif | 92 #endif |
92 | 93 |
| 94 // The snapshot semispace size will be the default semispace size if |
| 95 // snapshotting is used and will be the requested semispace size as |
| 96 // set up by ConfigureHeap otherwise. |
| 97 int Heap::reserved_semispace_size_ = Heap::max_semispace_size_; |
| 98 |
93 GCCallback Heap::global_gc_prologue_callback_ = NULL; | 99 GCCallback Heap::global_gc_prologue_callback_ = NULL; |
94 GCCallback Heap::global_gc_epilogue_callback_ = NULL; | 100 GCCallback Heap::global_gc_epilogue_callback_ = NULL; |
95 | 101 |
96 // Variables set based on semispace_size_ and old_generation_size_ in | 102 // Variables set based on semispace_size_ and old_generation_size_ in |
97 // ConfigureHeap. | 103 // ConfigureHeap. |
98 int Heap::young_generation_size_ = 0; // Will be 2 * semispace_size_. | 104 |
| 105 // Will be 4 * reserved_semispace_size_ to ensure that young |
| 106 // generation can be aligned to its size. |
99 int Heap::survived_since_last_expansion_ = 0; | 107 int Heap::survived_since_last_expansion_ = 0; |
100 int Heap::external_allocation_limit_ = 0; | 108 int Heap::external_allocation_limit_ = 0; |
101 | 109 |
102 Heap::HeapState Heap::gc_state_ = NOT_IN_GC; | 110 Heap::HeapState Heap::gc_state_ = NOT_IN_GC; |
103 | 111 |
104 int Heap::mc_count_ = 0; | 112 int Heap::mc_count_ = 0; |
105 int Heap::gc_count_ = 0; | 113 int Heap::gc_count_ = 0; |
106 | 114 |
107 int Heap::always_allocate_scope_depth_ = 0; | 115 int Heap::always_allocate_scope_depth_ = 0; |
108 bool Heap::context_disposed_pending_ = false; | 116 bool Heap::context_disposed_pending_ = false; |
(...skipping 3088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3197 #undef SYNCHRONIZE_TAG | 3205 #undef SYNCHRONIZE_TAG |
3198 | 3206 |
3199 | 3207 |
3200 // Flag is set when the heap has been configured. The heap can be repeatedly | 3208 // Flag is set when the heap has been configured. The heap can be repeatedly |
3201 // configured through the API until it is setup. | 3209 // configured through the API until it is setup. |
3202 static bool heap_configured = false; | 3210 static bool heap_configured = false; |
3203 | 3211 |
3204 // TODO(1236194): Since the heap size is configurable on the command line | 3212 // TODO(1236194): Since the heap size is configurable on the command line |
3205 // and through the API, we should gracefully handle the case that the heap | 3213 // and through the API, we should gracefully handle the case that the heap |
3206 // size is not big enough to fit all the initial objects. | 3214 // size is not big enough to fit all the initial objects. |
3207 bool Heap::ConfigureHeap(int semispace_size, int old_gen_size) { | 3215 bool Heap::ConfigureHeap(int max_semispace_size, int max_old_gen_size) { |
3208 if (HasBeenSetup()) return false; | 3216 if (HasBeenSetup()) return false; |
3209 | 3217 |
3210 if (semispace_size > 0) semispace_size_ = semispace_size; | 3218 if (max_semispace_size > 0) max_semispace_size_ = max_semispace_size; |
3211 if (old_gen_size > 0) old_generation_size_ = old_gen_size; | 3219 |
| 3220 if (Snapshot::IsEnabled()) { |
| 3221 // If we are using a snapshot we always reserve the default amount |
| 3222 // of memory for each semispace because code in the snapshot has |
| 3223 // write-barrier code that relies on the size and alignment of new |
| 3224 // space. We therefore cannot use a larger max semispace size |
| 3225 // than the default reserved semispace size. |
| 3226 if (max_semispace_size_ > reserved_semispace_size_) { |
| 3227 max_semispace_size_ = reserved_semispace_size_; |
| 3228 } |
| 3229 } else { |
| 3230 // If we are not using snapshots we reserve space for the actual |
| 3231 // max semispace size. |
| 3232 reserved_semispace_size_ = max_semispace_size_; |
| 3233 } |
| 3234 |
| 3235 if (max_old_gen_size > 0) max_old_generation_size_ = max_old_gen_size; |
3212 | 3236 |
3213 // The new space size must be a power of two to support single-bit testing | 3237 // The new space size must be a power of two to support single-bit testing |
3214 // for containment. | 3238 // for containment. |
3215 semispace_size_ = RoundUpToPowerOf2(semispace_size_); | 3239 max_semispace_size_ = RoundUpToPowerOf2(max_semispace_size_); |
3216 initial_semispace_size_ = Min(initial_semispace_size_, semispace_size_); | 3240 reserved_semispace_size_ = RoundUpToPowerOf2(reserved_semispace_size_); |
3217 young_generation_size_ = 2 * semispace_size_; | 3241 initial_semispace_size_ = Min(initial_semispace_size_, max_semispace_size_); |
3218 external_allocation_limit_ = 10 * semispace_size_; | 3242 external_allocation_limit_ = 10 * max_semispace_size_; |
3219 | 3243 |
3220 // The old generation is paged. | 3244 // The old generation is paged. |
3221 old_generation_size_ = RoundUp(old_generation_size_, Page::kPageSize); | 3245 max_old_generation_size_ = RoundUp(max_old_generation_size_, Page::kPageSize); |
3222 | 3246 |
3223 heap_configured = true; | 3247 heap_configured = true; |
3224 return true; | 3248 return true; |
3225 } | 3249 } |
3226 | 3250 |
3227 | 3251 |
3228 bool Heap::ConfigureHeapDefault() { | 3252 bool Heap::ConfigureHeapDefault() { |
3229 return ConfigureHeap(FLAG_new_space_size, FLAG_old_space_size); | 3253 return ConfigureHeap(FLAG_max_new_space_size / 2, FLAG_max_old_space_size); |
3230 } | 3254 } |
3231 | 3255 |
3232 | 3256 |
3233 int Heap::PromotedSpaceSize() { | 3257 int Heap::PromotedSpaceSize() { |
3234 return old_pointer_space_->Size() | 3258 return old_pointer_space_->Size() |
3235 + old_data_space_->Size() | 3259 + old_data_space_->Size() |
3236 + code_space_->Size() | 3260 + code_space_->Size() |
3237 + map_space_->Size() | 3261 + map_space_->Size() |
3238 + cell_space_->Size() | 3262 + cell_space_->Size() |
3239 + lo_space_->Size(); | 3263 + lo_space_->Size(); |
(...skipping 15 matching lines...) Expand all Loading... |
3255 // | 3279 // |
3256 // If the heap is not yet configured (eg, through the API), configure it. | 3280 // If the heap is not yet configured (eg, through the API), configure it. |
3257 // Configuration is based on the flags new-space-size (really the semispace | 3281 // Configuration is based on the flags new-space-size (really the semispace |
3258 // size) and old-space-size if set or the initial values of semispace_size_ | 3282 // size) and old-space-size if set or the initial values of semispace_size_ |
3259 // and old_generation_size_ otherwise. | 3283 // and old_generation_size_ otherwise. |
3260 if (!heap_configured) { | 3284 if (!heap_configured) { |
3261 if (!ConfigureHeapDefault()) return false; | 3285 if (!ConfigureHeapDefault()) return false; |
3262 } | 3286 } |
3263 | 3287 |
3264 // Setup memory allocator and reserve a chunk of memory for new | 3288 // Setup memory allocator and reserve a chunk of memory for new |
3265 // space. The chunk is double the size of the new space to ensure | 3289 // space. The chunk is double the size of the requested reserved |
3266 // that we can find a pair of semispaces that are contiguous and | 3290 // new space size to ensure that we can find a pair of semispaces that |
3267 // aligned to their size. | 3291 // are contiguous and aligned to their size. |
3268 if (!MemoryAllocator::Setup(MaxCapacity())) return false; | 3292 if (!MemoryAllocator::Setup(MaxReserved())) return false; |
3269 void* chunk = | 3293 void* chunk = |
3270 MemoryAllocator::ReserveInitialChunk(2 * young_generation_size_); | 3294 MemoryAllocator::ReserveInitialChunk(4 * reserved_semispace_size_); |
3271 if (chunk == NULL) return false; | 3295 if (chunk == NULL) return false; |
3272 | 3296 |
3273 // Align the pair of semispaces to their size, which must be a power | 3297 // Align the pair of semispaces to their size, which must be a power |
3274 // of 2. | 3298 // of 2. |
3275 ASSERT(IsPowerOf2(young_generation_size_)); | |
3276 Address new_space_start = | 3299 Address new_space_start = |
3277 RoundUp(reinterpret_cast<byte*>(chunk), young_generation_size_); | 3300 RoundUp(reinterpret_cast<byte*>(chunk), 2 * reserved_semispace_size_); |
3278 if (!new_space_.Setup(new_space_start, young_generation_size_)) return false; | 3301 if (!new_space_.Setup(new_space_start, 2 * reserved_semispace_size_)) return f
alse; |
3279 | 3302 |
3280 // Initialize old pointer space. | 3303 // Initialize old pointer space. |
3281 old_pointer_space_ = | 3304 old_pointer_space_ = |
3282 new OldSpace(old_generation_size_, OLD_POINTER_SPACE, NOT_EXECUTABLE); | 3305 new OldSpace(max_old_generation_size_, OLD_POINTER_SPACE, NOT_EXECUTABLE); |
3283 if (old_pointer_space_ == NULL) return false; | 3306 if (old_pointer_space_ == NULL) return false; |
3284 if (!old_pointer_space_->Setup(NULL, 0)) return false; | 3307 if (!old_pointer_space_->Setup(NULL, 0)) return false; |
3285 | 3308 |
3286 // Initialize old data space. | 3309 // Initialize old data space. |
3287 old_data_space_ = | 3310 old_data_space_ = |
3288 new OldSpace(old_generation_size_, OLD_DATA_SPACE, NOT_EXECUTABLE); | 3311 new OldSpace(max_old_generation_size_, OLD_DATA_SPACE, NOT_EXECUTABLE); |
3289 if (old_data_space_ == NULL) return false; | 3312 if (old_data_space_ == NULL) return false; |
3290 if (!old_data_space_->Setup(NULL, 0)) return false; | 3313 if (!old_data_space_->Setup(NULL, 0)) return false; |
3291 | 3314 |
3292 // Initialize the code space, set its maximum capacity to the old | 3315 // Initialize the code space, set its maximum capacity to the old |
3293 // generation size. It needs executable memory. | 3316 // generation size. It needs executable memory. |
3294 // On 64-bit platform(s), we put all code objects in a 2 GB range of | 3317 // On 64-bit platform(s), we put all code objects in a 2 GB range of |
3295 // virtual address space, so that they can call each other with near calls. | 3318 // virtual address space, so that they can call each other with near calls. |
3296 if (code_range_size_ > 0) { | 3319 if (code_range_size_ > 0) { |
3297 if (!CodeRange::Setup(code_range_size_)) { | 3320 if (!CodeRange::Setup(code_range_size_)) { |
3298 return false; | 3321 return false; |
3299 } | 3322 } |
3300 } | 3323 } |
3301 | 3324 |
3302 code_space_ = | 3325 code_space_ = |
3303 new OldSpace(old_generation_size_, CODE_SPACE, EXECUTABLE); | 3326 new OldSpace(max_old_generation_size_, CODE_SPACE, EXECUTABLE); |
3304 if (code_space_ == NULL) return false; | 3327 if (code_space_ == NULL) return false; |
3305 if (!code_space_->Setup(NULL, 0)) return false; | 3328 if (!code_space_->Setup(NULL, 0)) return false; |
3306 | 3329 |
3307 // Initialize map space. | 3330 // Initialize map space. |
3308 map_space_ = new MapSpace(kMaxMapSpaceSize, MAP_SPACE); | 3331 map_space_ = new MapSpace(kMaxMapSpaceSize, MAP_SPACE); |
3309 if (map_space_ == NULL) return false; | 3332 if (map_space_ == NULL) return false; |
3310 if (!map_space_->Setup(NULL, 0)) return false; | 3333 if (!map_space_->Setup(NULL, 0)) return false; |
3311 | 3334 |
3312 // Initialize global property cell space. | 3335 // Initialize global property cell space. |
3313 cell_space_ = new CellSpace(old_generation_size_, CELL_SPACE); | 3336 cell_space_ = new CellSpace(max_old_generation_size_, CELL_SPACE); |
3314 if (cell_space_ == NULL) return false; | 3337 if (cell_space_ == NULL) return false; |
3315 if (!cell_space_->Setup(NULL, 0)) return false; | 3338 if (!cell_space_->Setup(NULL, 0)) return false; |
3316 | 3339 |
3317 // The large object code space may contain code or data. We set the memory | 3340 // The large object code space may contain code or data. We set the memory |
3318 // to be non-executable here for safety, but this means we need to enable it | 3341 // to be non-executable here for safety, but this means we need to enable it |
3319 // explicitly when allocating large code objects. | 3342 // explicitly when allocating large code objects. |
3320 lo_space_ = new LargeObjectSpace(LO_SPACE); | 3343 lo_space_ = new LargeObjectSpace(LO_SPACE); |
3321 if (lo_space_ == NULL) return false; | 3344 if (lo_space_ == NULL) return false; |
3322 if (!lo_space_->Setup()) return false; | 3345 if (!lo_space_->Setup()) return false; |
3323 | 3346 |
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3915 for (int i = 0; i < kNumberOfCaches; i++) { | 3938 for (int i = 0; i < kNumberOfCaches; i++) { |
3916 if (caches_[i] != NULL) { | 3939 if (caches_[i] != NULL) { |
3917 delete caches_[i]; | 3940 delete caches_[i]; |
3918 caches_[i] = NULL; | 3941 caches_[i] = NULL; |
3919 } | 3942 } |
3920 } | 3943 } |
3921 } | 3944 } |
3922 | 3945 |
3923 | 3946 |
3924 } } // namespace v8::internal | 3947 } } // namespace v8::internal |
OLD | NEW |