Chromium Code Reviews| 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/v8.h" | 5 #include "src/v8.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/once.h" | 9 #include "src/base/once.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 new_space_(this), | 72 new_space_(this), |
| 73 old_pointer_space_(NULL), | 73 old_pointer_space_(NULL), |
| 74 old_data_space_(NULL), | 74 old_data_space_(NULL), |
| 75 code_space_(NULL), | 75 code_space_(NULL), |
| 76 map_space_(NULL), | 76 map_space_(NULL), |
| 77 cell_space_(NULL), | 77 cell_space_(NULL), |
| 78 property_cell_space_(NULL), | 78 property_cell_space_(NULL), |
| 79 lo_space_(NULL), | 79 lo_space_(NULL), |
| 80 gc_state_(NOT_IN_GC), | 80 gc_state_(NOT_IN_GC), |
| 81 gc_post_processing_depth_(0), | 81 gc_post_processing_depth_(0), |
| 82 allocations_count_(0), | |
| 83 raw_allocations_hash_(0), | |
| 84 dump_allocations_hash_countdown_(FLAG_dump_allocations_digest_at_alloc), | |
| 82 ms_count_(0), | 85 ms_count_(0), |
| 83 gc_count_(0), | 86 gc_count_(0), |
| 84 remembered_unmapped_pages_index_(0), | 87 remembered_unmapped_pages_index_(0), |
| 85 unflattened_strings_length_(0), | 88 unflattened_strings_length_(0), |
| 86 #ifdef DEBUG | 89 #ifdef DEBUG |
| 87 allocation_timeout_(0), | 90 allocation_timeout_(0), |
| 88 #endif // DEBUG | 91 #endif // DEBUG |
| 89 old_generation_allocation_limit_(kMinimumOldGenerationAllocationLimit), | 92 old_generation_allocation_limit_(kMinimumOldGenerationAllocationLimit), |
| 90 size_of_old_gen_at_last_old_space_gc_(0), | 93 size_of_old_gen_at_last_old_space_gc_(0), |
| 91 old_gen_exhausted_(false), | 94 old_gen_exhausted_(false), |
| (...skipping 1858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1950 int size)) { | 1953 int size)) { |
| 1951 // Copy the content of source to target. | 1954 // Copy the content of source to target. |
| 1952 heap->CopyBlock(target->address(), source->address(), size); | 1955 heap->CopyBlock(target->address(), source->address(), size); |
| 1953 | 1956 |
| 1954 // Set the forwarding address. | 1957 // Set the forwarding address. |
| 1955 source->set_map_word(MapWord::FromForwardingAddress(target)); | 1958 source->set_map_word(MapWord::FromForwardingAddress(target)); |
| 1956 | 1959 |
| 1957 if (logging_and_profiling_mode == LOGGING_AND_PROFILING_ENABLED) { | 1960 if (logging_and_profiling_mode == LOGGING_AND_PROFILING_ENABLED) { |
| 1958 // Update NewSpace stats if necessary. | 1961 // Update NewSpace stats if necessary. |
| 1959 RecordCopiedObject(heap, target); | 1962 RecordCopiedObject(heap, target); |
| 1960 Isolate* isolate = heap->isolate(); | 1963 heap->OnMoveEvent(target, source, size); |
| 1961 HeapProfiler* heap_profiler = isolate->heap_profiler(); | |
| 1962 if (heap_profiler->is_tracking_object_moves()) { | |
| 1963 heap_profiler->ObjectMoveEvent(source->address(), target->address(), | |
| 1964 size); | |
| 1965 } | |
| 1966 if (isolate->logger()->is_logging_code_events() || | |
| 1967 isolate->cpu_profiler()->is_profiling()) { | |
| 1968 if (target->IsSharedFunctionInfo()) { | |
| 1969 PROFILE(isolate, SharedFunctionInfoMoveEvent( | |
| 1970 source->address(), target->address())); | |
| 1971 } | |
| 1972 } | |
| 1973 } | 1964 } |
| 1974 | 1965 |
| 1975 if (marks_handling == TRANSFER_MARKS) { | 1966 if (marks_handling == TRANSFER_MARKS) { |
| 1976 if (Marking::TransferColor(source, target)) { | 1967 if (Marking::TransferColor(source, target)) { |
| 1977 MemoryChunk::IncrementLiveBytesFromGC(target->address(), size); | 1968 MemoryChunk::IncrementLiveBytesFromGC(target->address(), size); |
| 1978 } | 1969 } |
| 1979 } | 1970 } |
| 1980 } | 1971 } |
| 1981 | 1972 |
| 1982 | 1973 |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2217 LOGGING_AND_PROFILING_DISABLED>::Initialize(); | 2208 LOGGING_AND_PROFILING_DISABLED>::Initialize(); |
| 2218 ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_DISABLED>::Initialize(); | 2209 ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_DISABLED>::Initialize(); |
| 2219 ScavengingVisitor<TRANSFER_MARKS, | 2210 ScavengingVisitor<TRANSFER_MARKS, |
| 2220 LOGGING_AND_PROFILING_ENABLED>::Initialize(); | 2211 LOGGING_AND_PROFILING_ENABLED>::Initialize(); |
| 2221 ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_ENABLED>::Initialize(); | 2212 ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_ENABLED>::Initialize(); |
| 2222 } | 2213 } |
| 2223 | 2214 |
| 2224 | 2215 |
| 2225 void Heap::SelectScavengingVisitorsTable() { | 2216 void Heap::SelectScavengingVisitorsTable() { |
| 2226 bool logging_and_profiling = | 2217 bool logging_and_profiling = |
| 2218 FLAG_verify_predictable || | |
| 2227 isolate()->logger()->is_logging() || | 2219 isolate()->logger()->is_logging() || |
| 2228 isolate()->cpu_profiler()->is_profiling() || | 2220 isolate()->cpu_profiler()->is_profiling() || |
| 2229 (isolate()->heap_profiler() != NULL && | 2221 (isolate()->heap_profiler() != NULL && |
| 2230 isolate()->heap_profiler()->is_tracking_object_moves()); | 2222 isolate()->heap_profiler()->is_tracking_object_moves()); |
| 2231 | 2223 |
| 2232 if (!incremental_marking()->IsMarking()) { | 2224 if (!incremental_marking()->IsMarking()) { |
| 2233 if (!logging_and_profiling) { | 2225 if (!logging_and_profiling) { |
| 2234 scavenging_visitors_table_.CopyFrom( | 2226 scavenging_visitors_table_.CopyFrom( |
| 2235 ScavengingVisitor<IGNORE_MARKS, | 2227 ScavengingVisitor<IGNORE_MARKS, |
| 2236 LOGGING_AND_PROFILING_DISABLED>::GetTable()); | 2228 LOGGING_AND_PROFILING_DISABLED>::GetTable()); |
| (...skipping 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3331 } | 3323 } |
| 3332 | 3324 |
| 3333 object->set_map(MapForFixedTypedArray(array_type)); | 3325 object->set_map(MapForFixedTypedArray(array_type)); |
| 3334 FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(object); | 3326 FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(object); |
| 3335 elements->set_length(length); | 3327 elements->set_length(length); |
| 3336 memset(elements->DataPtr(), 0, elements->DataSize()); | 3328 memset(elements->DataPtr(), 0, elements->DataSize()); |
| 3337 return elements; | 3329 return elements; |
| 3338 } | 3330 } |
| 3339 | 3331 |
| 3340 | 3332 |
| 3341 AllocationResult Heap::AllocateCode(int object_size, | 3333 AllocationResult Heap::AllocateCode(int object_size, bool immovable) { |
| 3342 bool immovable) { | |
| 3343 ASSERT(IsAligned(static_cast<intptr_t>(object_size), kCodeAlignment)); | 3334 ASSERT(IsAligned(static_cast<intptr_t>(object_size), kCodeAlignment)); |
| 3344 AllocationResult allocation; | 3335 AllocationResult allocation; |
| 3345 // Large code objects and code objects which should stay at a fixed address | 3336 // Large code objects and code objects which should stay at a fixed address |
| 3346 // are allocated in large object space. | 3337 // are allocated in large object space. |
| 3347 HeapObject* result; | 3338 HeapObject* result; |
| 3348 bool force_lo_space = object_size > code_space()->AreaSize(); | 3339 bool force_lo_space = object_size > code_space()->AreaSize(); |
| 3349 if (force_lo_space) { | 3340 if (force_lo_space) { |
| 3350 allocation = lo_space_->AllocateRaw(object_size, EXECUTABLE); | 3341 allocation = lo_space_->AllocateRaw(object_size, EXECUTABLE); |
| 3342 if (!allocation.To(&result)) return allocation; | |
| 3343 OnAllocationEvent(result, object_size); | |
|
Hannes Payer (out of office)
2014/06/17 12:54:49
As discussed, offline: let's refactor large object
Igor Sheludko
2014/06/17 14:08:10
Done.
| |
| 3351 } else { | 3344 } else { |
| 3352 allocation = AllocateRaw(object_size, CODE_SPACE, CODE_SPACE); | 3345 allocation = AllocateRaw(object_size, CODE_SPACE, CODE_SPACE); |
| 3346 if (!allocation.To(&result)) return allocation; | |
| 3353 } | 3347 } |
| 3354 if (!allocation.To(&result)) return allocation; | |
| 3355 | 3348 |
| 3356 if (immovable && !force_lo_space && | 3349 if (immovable && !force_lo_space && |
| 3357 // Objects on the first page of each space are never moved. | 3350 // Objects on the first page of each space are never moved. |
| 3358 !code_space_->FirstPage()->Contains(result->address())) { | 3351 !code_space_->FirstPage()->Contains(result->address())) { |
| 3359 // Discard the first code allocation, which was on a page where it could be | 3352 // Discard the first code allocation, which was on a page where it could be |
| 3360 // moved. | 3353 // moved. |
| 3361 CreateFillerObjectAt(result->address(), object_size); | 3354 CreateFillerObjectAt(result->address(), object_size); |
| 3362 allocation = lo_space_->AllocateRaw(object_size, EXECUTABLE); | 3355 allocation = lo_space_->AllocateRaw(object_size, EXECUTABLE); |
| 3363 if (!allocation.To(&result)) return allocation; | 3356 if (!allocation.To(&result)) return allocation; |
| 3357 OnAllocationEvent(result, object_size); | |
| 3364 } | 3358 } |
| 3365 | 3359 |
| 3366 result->set_map_no_write_barrier(code_map()); | 3360 result->set_map_no_write_barrier(code_map()); |
| 3367 Code* code = Code::cast(result); | 3361 Code* code = Code::cast(result); |
| 3368 ASSERT(!isolate_->code_range()->exists() || | 3362 ASSERT(!isolate_->code_range()->exists() || |
| 3369 isolate_->code_range()->contains(code->address())); | 3363 isolate_->code_range()->contains(code->address())); |
| 3370 code->set_gc_metadata(Smi::FromInt(0)); | 3364 code->set_gc_metadata(Smi::FromInt(0)); |
| 3371 code->set_ic_age(global_ic_age_); | 3365 code->set_ic_age(global_ic_age_); |
| 3372 return code; | 3366 return code; |
| 3373 } | 3367 } |
| 3374 | 3368 |
| 3375 | 3369 |
| 3376 AllocationResult Heap::CopyCode(Code* code) { | 3370 AllocationResult Heap::CopyCode(Code* code) { |
| 3377 AllocationResult allocation; | 3371 AllocationResult allocation; |
| 3378 HeapObject* new_constant_pool; | 3372 HeapObject* new_constant_pool; |
| 3379 if (FLAG_enable_ool_constant_pool && | 3373 if (FLAG_enable_ool_constant_pool && |
| 3380 code->constant_pool() != empty_constant_pool_array()) { | 3374 code->constant_pool() != empty_constant_pool_array()) { |
| 3381 // Copy the constant pool, since edits to the copied code may modify | 3375 // Copy the constant pool, since edits to the copied code may modify |
| 3382 // the constant pool. | 3376 // the constant pool. |
| 3383 allocation = CopyConstantPoolArray(code->constant_pool()); | 3377 allocation = CopyConstantPoolArray(code->constant_pool()); |
| 3384 if (!allocation.To(&new_constant_pool)) return allocation; | 3378 if (!allocation.To(&new_constant_pool)) return allocation; |
| 3385 } else { | 3379 } else { |
| 3386 new_constant_pool = empty_constant_pool_array(); | 3380 new_constant_pool = empty_constant_pool_array(); |
| 3387 } | 3381 } |
| 3388 | 3382 |
| 3383 HeapObject* result; | |
| 3389 // Allocate an object the same size as the code object. | 3384 // Allocate an object the same size as the code object. |
| 3390 int obj_size = code->Size(); | 3385 int obj_size = code->Size(); |
| 3391 if (obj_size > code_space()->AreaSize()) { | 3386 if (obj_size > code_space()->AreaSize()) { |
| 3392 allocation = lo_space_->AllocateRaw(obj_size, EXECUTABLE); | 3387 allocation = lo_space_->AllocateRaw(obj_size, EXECUTABLE); |
| 3388 if (!allocation.To(&result)) return allocation; | |
| 3389 OnAllocationEvent(result, obj_size); | |
| 3393 } else { | 3390 } else { |
| 3394 allocation = AllocateRaw(obj_size, CODE_SPACE, CODE_SPACE); | 3391 allocation = AllocateRaw(obj_size, CODE_SPACE, CODE_SPACE); |
| 3392 if (!allocation.To(&result)) return allocation; | |
| 3395 } | 3393 } |
| 3396 | 3394 |
| 3397 HeapObject* result; | |
| 3398 if (!allocation.To(&result)) return allocation; | |
| 3399 | |
| 3400 // Copy code object. | 3395 // Copy code object. |
| 3401 Address old_addr = code->address(); | 3396 Address old_addr = code->address(); |
| 3402 Address new_addr = result->address(); | 3397 Address new_addr = result->address(); |
| 3403 CopyBlock(new_addr, old_addr, obj_size); | 3398 CopyBlock(new_addr, old_addr, obj_size); |
| 3404 Code* new_code = Code::cast(result); | 3399 Code* new_code = Code::cast(result); |
| 3405 | 3400 |
| 3406 // Update the constant pool. | 3401 // Update the constant pool. |
| 3407 new_code->set_constant_pool(new_constant_pool); | 3402 new_code->set_constant_pool(new_constant_pool); |
| 3408 | 3403 |
| 3409 // Relocate the copy. | 3404 // Relocate the copy. |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 3436 | 3431 |
| 3437 int new_body_size = RoundUp(code->instruction_size(), kObjectAlignment); | 3432 int new_body_size = RoundUp(code->instruction_size(), kObjectAlignment); |
| 3438 | 3433 |
| 3439 int new_obj_size = Code::SizeFor(new_body_size); | 3434 int new_obj_size = Code::SizeFor(new_body_size); |
| 3440 | 3435 |
| 3441 Address old_addr = code->address(); | 3436 Address old_addr = code->address(); |
| 3442 | 3437 |
| 3443 size_t relocation_offset = | 3438 size_t relocation_offset = |
| 3444 static_cast<size_t>(code->instruction_end() - old_addr); | 3439 static_cast<size_t>(code->instruction_end() - old_addr); |
| 3445 | 3440 |
| 3441 HeapObject* result; | |
| 3446 AllocationResult allocation; | 3442 AllocationResult allocation; |
| 3447 if (new_obj_size > code_space()->AreaSize()) { | 3443 if (new_obj_size > code_space()->AreaSize()) { |
| 3448 allocation = lo_space_->AllocateRaw(new_obj_size, EXECUTABLE); | 3444 allocation = lo_space_->AllocateRaw(new_obj_size, EXECUTABLE); |
| 3445 if (!allocation.To(&result)) return allocation; | |
| 3446 OnAllocationEvent(result, new_obj_size); | |
| 3449 } else { | 3447 } else { |
| 3450 allocation = AllocateRaw(new_obj_size, CODE_SPACE, CODE_SPACE); | 3448 allocation = AllocateRaw(new_obj_size, CODE_SPACE, CODE_SPACE); |
| 3449 if (!allocation.To(&result)) return allocation; | |
| 3451 } | 3450 } |
| 3452 | 3451 |
| 3453 HeapObject* result; | |
| 3454 if (!allocation.To(&result)) return allocation; | |
| 3455 | |
| 3456 // Copy code object. | 3452 // Copy code object. |
| 3457 Address new_addr = result->address(); | 3453 Address new_addr = result->address(); |
| 3458 | 3454 |
| 3459 // Copy header and instructions. | 3455 // Copy header and instructions. |
| 3460 CopyBytes(new_addr, old_addr, relocation_offset); | 3456 CopyBytes(new_addr, old_addr, relocation_offset); |
| 3461 | 3457 |
| 3462 Code* new_code = Code::cast(result); | 3458 Code* new_code = Code::cast(result); |
| 3463 new_code->set_relocation_info(reloc_info_array); | 3459 new_code->set_relocation_info(reloc_info_array); |
| 3464 | 3460 |
| 3465 // Update constant pool. | 3461 // Update constant pool. |
| (...skipping 1844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5310 map_space_->MaximumCommittedMemory()); | 5306 map_space_->MaximumCommittedMemory()); |
| 5311 PrintF("maximum_committed_by_cell_space=%" V8_PTR_PREFIX "d ", | 5307 PrintF("maximum_committed_by_cell_space=%" V8_PTR_PREFIX "d ", |
| 5312 cell_space_->MaximumCommittedMemory()); | 5308 cell_space_->MaximumCommittedMemory()); |
| 5313 PrintF("maximum_committed_by_property_space=%" V8_PTR_PREFIX "d ", | 5309 PrintF("maximum_committed_by_property_space=%" V8_PTR_PREFIX "d ", |
| 5314 property_cell_space_->MaximumCommittedMemory()); | 5310 property_cell_space_->MaximumCommittedMemory()); |
| 5315 PrintF("maximum_committed_by_lo_space=%" V8_PTR_PREFIX "d ", | 5311 PrintF("maximum_committed_by_lo_space=%" V8_PTR_PREFIX "d ", |
| 5316 lo_space_->MaximumCommittedMemory()); | 5312 lo_space_->MaximumCommittedMemory()); |
| 5317 PrintF("\n\n"); | 5313 PrintF("\n\n"); |
| 5318 } | 5314 } |
| 5319 | 5315 |
| 5316 if (FLAG_verify_predictable) { | |
| 5317 PrintAlloctionsHash(); | |
| 5318 } | |
| 5319 | |
| 5320 TearDownArrayBuffers(); | 5320 TearDownArrayBuffers(); |
| 5321 | 5321 |
| 5322 isolate_->global_handles()->TearDown(); | 5322 isolate_->global_handles()->TearDown(); |
| 5323 | 5323 |
| 5324 external_string_table_.TearDown(); | 5324 external_string_table_.TearDown(); |
| 5325 | 5325 |
| 5326 mark_compact_collector()->TearDown(); | 5326 mark_compact_collector()->TearDown(); |
| 5327 | 5327 |
| 5328 new_space_.TearDown(); | 5328 new_space_.TearDown(); |
| 5329 | 5329 |
| (...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6430 static_cast<int>(object_sizes_last_time_[index])); | 6430 static_cast<int>(object_sizes_last_time_[index])); |
| 6431 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) | 6431 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) |
| 6432 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 6432 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
| 6433 | 6433 |
| 6434 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 6434 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
| 6435 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 6435 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
| 6436 ClearObjectStats(); | 6436 ClearObjectStats(); |
| 6437 } | 6437 } |
| 6438 | 6438 |
| 6439 } } // namespace v8::internal | 6439 } } // namespace v8::internal |
| OLD | NEW |