| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 // a multiple of Page::kPageSize. | 72 // a multiple of Page::kPageSize. |
| 73 reserved_semispace_size_(8 * (kPointerSize / 4) * MB), | 73 reserved_semispace_size_(8 * (kPointerSize / 4) * MB), |
| 74 max_semispace_size_(8 * (kPointerSize / 4) * MB), | 74 max_semispace_size_(8 * (kPointerSize / 4) * MB), |
| 75 initial_semispace_size_(Page::kPageSize), | 75 initial_semispace_size_(Page::kPageSize), |
| 76 max_old_generation_size_(700ul * (kPointerSize / 4) * MB), | 76 max_old_generation_size_(700ul * (kPointerSize / 4) * MB), |
| 77 max_executable_size_(256ul * (kPointerSize / 4) * MB), | 77 max_executable_size_(256ul * (kPointerSize / 4) * MB), |
| 78 // Variables set based on semispace_size_ and old_generation_size_ in | 78 // Variables set based on semispace_size_ and old_generation_size_ in |
| 79 // ConfigureHeap (survived_since_last_expansion_, external_allocation_limit_) | 79 // ConfigureHeap (survived_since_last_expansion_, external_allocation_limit_) |
| 80 // Will be 4 * reserved_semispace_size_ to ensure that young | 80 // Will be 4 * reserved_semispace_size_ to ensure that young |
| 81 // generation can be aligned to its size. | 81 // generation can be aligned to its size. |
| 82 maximum_committed_(0), |
| 82 survived_since_last_expansion_(0), | 83 survived_since_last_expansion_(0), |
| 83 sweep_generation_(0), | 84 sweep_generation_(0), |
| 84 always_allocate_scope_depth_(0), | 85 always_allocate_scope_depth_(0), |
| 85 linear_allocation_scope_depth_(0), | 86 linear_allocation_scope_depth_(0), |
| 86 contexts_disposed_(0), | 87 contexts_disposed_(0), |
| 87 global_ic_age_(0), | 88 global_ic_age_(0), |
| 88 flush_monomorphic_ics_(false), | 89 flush_monomorphic_ics_(false), |
| 89 allocation_mementos_found_(0), | 90 allocation_mementos_found_(0), |
| 90 scan_on_scavenge_pages_(0), | 91 scan_on_scavenge_pages_(0), |
| 91 new_space_(this), | 92 new_space_(this), |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 } | 226 } |
| 226 | 227 |
| 227 | 228 |
| 228 intptr_t Heap::CommittedMemoryExecutable() { | 229 intptr_t Heap::CommittedMemoryExecutable() { |
| 229 if (!HasBeenSetUp()) return 0; | 230 if (!HasBeenSetUp()) return 0; |
| 230 | 231 |
| 231 return isolate()->memory_allocator()->SizeExecutable(); | 232 return isolate()->memory_allocator()->SizeExecutable(); |
| 232 } | 233 } |
| 233 | 234 |
| 234 | 235 |
| 236 void Heap::UpdateMaximumCommitted() { |
| 237 if (!HasBeenSetUp()) return; |
| 238 |
| 239 intptr_t current_committed_memory = CommittedMemory(); |
| 240 if (current_committed_memory > maximum_committed_) { |
| 241 maximum_committed_ = current_committed_memory; |
| 242 } |
| 243 } |
| 244 |
| 245 |
| 235 intptr_t Heap::Available() { | 246 intptr_t Heap::Available() { |
| 236 if (!HasBeenSetUp()) return 0; | 247 if (!HasBeenSetUp()) return 0; |
| 237 | 248 |
| 238 return new_space_.Available() + | 249 return new_space_.Available() + |
| 239 old_pointer_space_->Available() + | 250 old_pointer_space_->Available() + |
| 240 old_data_space_->Available() + | 251 old_data_space_->Available() + |
| 241 code_space_->Available() + | 252 code_space_->Available() + |
| 242 map_space_->Available() + | 253 map_space_->Available() + |
| 243 cell_space_->Available() + | 254 cell_space_->Available() + |
| 244 property_cell_space_->Available(); | 255 property_cell_space_->Available(); |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 mark_compact_collector()->EnableCodeFlushing(true); | 445 mark_compact_collector()->EnableCodeFlushing(true); |
| 435 } | 446 } |
| 436 | 447 |
| 437 #ifdef VERIFY_HEAP | 448 #ifdef VERIFY_HEAP |
| 438 if (FLAG_verify_heap) { | 449 if (FLAG_verify_heap) { |
| 439 Verify(); | 450 Verify(); |
| 440 } | 451 } |
| 441 #endif | 452 #endif |
| 442 } | 453 } |
| 443 | 454 |
| 455 UpdateMaximumCommitted(); |
| 456 |
| 444 #ifdef DEBUG | 457 #ifdef DEBUG |
| 445 ASSERT(!AllowHeapAllocation::IsAllowed() && gc_state_ == NOT_IN_GC); | 458 ASSERT(!AllowHeapAllocation::IsAllowed() && gc_state_ == NOT_IN_GC); |
| 446 | 459 |
| 447 if (FLAG_gc_verbose) Print(); | 460 if (FLAG_gc_verbose) Print(); |
| 448 | 461 |
| 449 ReportStatisticsBeforeGC(); | 462 ReportStatisticsBeforeGC(); |
| 450 #endif // DEBUG | 463 #endif // DEBUG |
| 451 | 464 |
| 452 store_buffer()->GCPrologue(); | 465 store_buffer()->GCPrologue(); |
| 453 | 466 |
| 454 if (FLAG_concurrent_osr) { | 467 if (FLAG_concurrent_osr) { |
| 455 isolate()->optimizing_compiler_thread()->AgeBufferedOsrJobs(); | 468 isolate()->optimizing_compiler_thread()->AgeBufferedOsrJobs(); |
| 456 } | 469 } |
| 457 } | 470 } |
| 458 | 471 |
| 459 | 472 |
| 460 intptr_t Heap::SizeOfObjects() { | 473 intptr_t Heap::SizeOfObjects() { |
| 461 intptr_t total = 0; | 474 intptr_t total = 0; |
| 462 AllSpaces spaces(this); | 475 AllSpaces spaces(this); |
| 463 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { | 476 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { |
| 464 total += space->SizeOfObjects(); | 477 total += space->SizeOfObjects(); |
| 465 } | 478 } |
| 466 return total; | 479 return total; |
| 467 } | 480 } |
| 468 | 481 |
| 469 | 482 |
| 483 void Heap::ClearAllICsByKind(Code::Kind kind) { |
| 484 HeapObjectIterator it(code_space()); |
| 485 |
| 486 for (Object* object = it.Next(); object != NULL; object = it.Next()) { |
| 487 Code* code = Code::cast(object); |
| 488 Code::Kind current_kind = code->kind(); |
| 489 if (current_kind == Code::FUNCTION || |
| 490 current_kind == Code::OPTIMIZED_FUNCTION) { |
| 491 code->ClearInlineCaches(kind); |
| 492 } |
| 493 } |
| 494 } |
| 495 |
| 496 |
| 470 void Heap::RepairFreeListsAfterBoot() { | 497 void Heap::RepairFreeListsAfterBoot() { |
| 471 PagedSpaces spaces(this); | 498 PagedSpaces spaces(this); |
| 472 for (PagedSpace* space = spaces.next(); | 499 for (PagedSpace* space = spaces.next(); |
| 473 space != NULL; | 500 space != NULL; |
| 474 space = spaces.next()) { | 501 space = spaces.next()) { |
| 475 space->RepairFreeListsAfterBoot(); | 502 space->RepairFreeListsAfterBoot(); |
| 476 } | 503 } |
| 477 } | 504 } |
| 478 | 505 |
| 479 | 506 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 499 if (FLAG_gc_verbose) Print(); | 526 if (FLAG_gc_verbose) Print(); |
| 500 if (FLAG_code_stats) ReportCodeStatistics("After GC"); | 527 if (FLAG_code_stats) ReportCodeStatistics("After GC"); |
| 501 #endif | 528 #endif |
| 502 if (FLAG_deopt_every_n_garbage_collections > 0) { | 529 if (FLAG_deopt_every_n_garbage_collections > 0) { |
| 503 if (++gcs_since_last_deopt_ == FLAG_deopt_every_n_garbage_collections) { | 530 if (++gcs_since_last_deopt_ == FLAG_deopt_every_n_garbage_collections) { |
| 504 Deoptimizer::DeoptimizeAll(isolate()); | 531 Deoptimizer::DeoptimizeAll(isolate()); |
| 505 gcs_since_last_deopt_ = 0; | 532 gcs_since_last_deopt_ = 0; |
| 506 } | 533 } |
| 507 } | 534 } |
| 508 | 535 |
| 536 UpdateMaximumCommitted(); |
| 537 |
| 509 isolate_->counters()->alive_after_last_gc()->Set( | 538 isolate_->counters()->alive_after_last_gc()->Set( |
| 510 static_cast<int>(SizeOfObjects())); | 539 static_cast<int>(SizeOfObjects())); |
| 511 | 540 |
| 512 isolate_->counters()->string_table_capacity()->Set( | 541 isolate_->counters()->string_table_capacity()->Set( |
| 513 string_table()->Capacity()); | 542 string_table()->Capacity()); |
| 514 isolate_->counters()->number_of_symbols()->Set( | 543 isolate_->counters()->number_of_symbols()->Set( |
| 515 string_table()->NumberOfElements()); | 544 string_table()->NumberOfElements()); |
| 516 | 545 |
| 517 if (full_codegen_bytes_generated_ + crankshaft_codegen_bytes_generated_ > 0) { | 546 if (full_codegen_bytes_generated_ + crankshaft_codegen_bytes_generated_ > 0) { |
| 518 isolate_->counters()->codegen_fraction_crankshaft()->AddSample( | 547 isolate_->counters()->codegen_fraction_crankshaft()->AddSample( |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 isolate_->counters()->heap_sample_map_space_committed()->AddSample( | 589 isolate_->counters()->heap_sample_map_space_committed()->AddSample( |
| 561 static_cast<int>(map_space()->CommittedMemory() / KB)); | 590 static_cast<int>(map_space()->CommittedMemory() / KB)); |
| 562 isolate_->counters()->heap_sample_cell_space_committed()->AddSample( | 591 isolate_->counters()->heap_sample_cell_space_committed()->AddSample( |
| 563 static_cast<int>(cell_space()->CommittedMemory() / KB)); | 592 static_cast<int>(cell_space()->CommittedMemory() / KB)); |
| 564 isolate_->counters()-> | 593 isolate_->counters()-> |
| 565 heap_sample_property_cell_space_committed()-> | 594 heap_sample_property_cell_space_committed()-> |
| 566 AddSample(static_cast<int>( | 595 AddSample(static_cast<int>( |
| 567 property_cell_space()->CommittedMemory() / KB)); | 596 property_cell_space()->CommittedMemory() / KB)); |
| 568 isolate_->counters()->heap_sample_code_space_committed()->AddSample( | 597 isolate_->counters()->heap_sample_code_space_committed()->AddSample( |
| 569 static_cast<int>(code_space()->CommittedMemory() / KB)); | 598 static_cast<int>(code_space()->CommittedMemory() / KB)); |
| 599 |
| 600 isolate_->counters()->heap_sample_maximum_committed()->AddSample( |
| 601 static_cast<int>(MaximumCommittedMemory() / KB)); |
| 570 } | 602 } |
| 571 | 603 |
| 572 #define UPDATE_COUNTERS_FOR_SPACE(space) \ | 604 #define UPDATE_COUNTERS_FOR_SPACE(space) \ |
| 573 isolate_->counters()->space##_bytes_available()->Set( \ | 605 isolate_->counters()->space##_bytes_available()->Set( \ |
| 574 static_cast<int>(space()->Available())); \ | 606 static_cast<int>(space()->Available())); \ |
| 575 isolate_->counters()->space##_bytes_committed()->Set( \ | 607 isolate_->counters()->space##_bytes_committed()->Set( \ |
| 576 static_cast<int>(space()->CommittedMemory())); \ | 608 static_cast<int>(space()->CommittedMemory())); \ |
| 577 isolate_->counters()->space##_bytes_used()->Set( \ | 609 isolate_->counters()->space##_bytes_used()->Set( \ |
| 578 static_cast<int>(space()->SizeOfObjects())); | 610 static_cast<int>(space()->SizeOfObjects())); |
| 579 #define UPDATE_FRAGMENTATION_FOR_SPACE(space) \ | 611 #define UPDATE_FRAGMENTATION_FOR_SPACE(space) \ |
| (...skipping 3612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4192 ASSERT(!isolate_->code_range()->exists() || | 4224 ASSERT(!isolate_->code_range()->exists() || |
| 4193 isolate_->code_range()->contains(code->address())); | 4225 isolate_->code_range()->contains(code->address())); |
| 4194 code->set_instruction_size(desc.instr_size); | 4226 code->set_instruction_size(desc.instr_size); |
| 4195 code->set_relocation_info(reloc_info); | 4227 code->set_relocation_info(reloc_info); |
| 4196 code->set_flags(flags); | 4228 code->set_flags(flags); |
| 4197 if (code->is_call_stub() || code->is_keyed_call_stub()) { | 4229 if (code->is_call_stub() || code->is_keyed_call_stub()) { |
| 4198 code->set_check_type(RECEIVER_MAP_CHECK); | 4230 code->set_check_type(RECEIVER_MAP_CHECK); |
| 4199 } | 4231 } |
| 4200 code->set_is_crankshafted(crankshafted); | 4232 code->set_is_crankshafted(crankshafted); |
| 4201 code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER); | 4233 code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER); |
| 4202 code->InitializeTypeFeedbackInfoNoWriteBarrier(undefined_value()); | 4234 code->set_raw_type_feedback_info(undefined_value()); |
| 4203 code->set_handler_table(empty_fixed_array(), SKIP_WRITE_BARRIER); | 4235 code->set_handler_table(empty_fixed_array(), SKIP_WRITE_BARRIER); |
| 4204 code->set_gc_metadata(Smi::FromInt(0)); | 4236 code->set_gc_metadata(Smi::FromInt(0)); |
| 4205 code->set_ic_age(global_ic_age_); | 4237 code->set_ic_age(global_ic_age_); |
| 4206 code->set_prologue_offset(prologue_offset); | 4238 code->set_prologue_offset(prologue_offset); |
| 4207 if (code->kind() == Code::OPTIMIZED_FUNCTION) { | 4239 if (code->kind() == Code::OPTIMIZED_FUNCTION) { |
| 4208 code->set_marked_for_deoptimization(false); | 4240 code->set_marked_for_deoptimization(false); |
| 4209 } | 4241 } |
| 4210 | 4242 |
| 4211 #ifdef ENABLE_DEBUGGER_SUPPORT | 4243 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 4212 if (code->kind() == Code::FUNCTION) { | 4244 if (code->kind() == Code::FUNCTION) { |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4368 function->initialize_elements(); | 4400 function->initialize_elements(); |
| 4369 function->set_shared(shared); | 4401 function->set_shared(shared); |
| 4370 function->set_code(shared->code()); | 4402 function->set_code(shared->code()); |
| 4371 function->set_prototype_or_initial_map(prototype); | 4403 function->set_prototype_or_initial_map(prototype); |
| 4372 function->set_context(undefined_value()); | 4404 function->set_context(undefined_value()); |
| 4373 function->set_literals_or_bindings(empty_fixed_array()); | 4405 function->set_literals_or_bindings(empty_fixed_array()); |
| 4374 function->set_next_function_link(undefined_value()); | 4406 function->set_next_function_link(undefined_value()); |
| 4375 } | 4407 } |
| 4376 | 4408 |
| 4377 | 4409 |
| 4378 MaybeObject* Heap::AllocateFunctionPrototype(JSFunction* function) { | |
| 4379 // Make sure to use globals from the function's context, since the function | |
| 4380 // can be from a different context. | |
| 4381 Context* native_context = function->context()->native_context(); | |
| 4382 Map* new_map; | |
| 4383 if (function->shared()->is_generator()) { | |
| 4384 // Generator prototypes can share maps since they don't have "constructor" | |
| 4385 // properties. | |
| 4386 new_map = native_context->generator_object_prototype_map(); | |
| 4387 } else { | |
| 4388 // Each function prototype gets a fresh map to avoid unwanted sharing of | |
| 4389 // maps between prototypes of different constructors. | |
| 4390 JSFunction* object_function = native_context->object_function(); | |
| 4391 ASSERT(object_function->has_initial_map()); | |
| 4392 MaybeObject* maybe_map = object_function->initial_map()->Copy(); | |
| 4393 if (!maybe_map->To(&new_map)) return maybe_map; | |
| 4394 } | |
| 4395 | |
| 4396 Object* prototype; | |
| 4397 MaybeObject* maybe_prototype = AllocateJSObjectFromMap(new_map); | |
| 4398 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; | |
| 4399 | |
| 4400 if (!function->shared()->is_generator()) { | |
| 4401 MaybeObject* maybe_failure = | |
| 4402 JSObject::cast(prototype)->SetLocalPropertyIgnoreAttributesTrampoline( | |
| 4403 constructor_string(), function, DONT_ENUM); | |
| 4404 if (maybe_failure->IsFailure()) return maybe_failure; | |
| 4405 } | |
| 4406 | |
| 4407 return prototype; | |
| 4408 } | |
| 4409 | |
| 4410 | |
| 4411 MaybeObject* Heap::AllocateFunction(Map* function_map, | 4410 MaybeObject* Heap::AllocateFunction(Map* function_map, |
| 4412 SharedFunctionInfo* shared, | 4411 SharedFunctionInfo* shared, |
| 4413 Object* prototype, | 4412 Object* prototype, |
| 4414 PretenureFlag pretenure) { | 4413 PretenureFlag pretenure) { |
| 4415 AllocationSpace space = | 4414 AllocationSpace space = |
| 4416 (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE; | 4415 (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE; |
| 4417 Object* result; | 4416 Object* result; |
| 4418 { MaybeObject* maybe_result = Allocate(function_map, space); | 4417 { MaybeObject* maybe_result = Allocate(function_map, space); |
| 4419 if (!maybe_result->ToObject(&result)) return maybe_result; | 4418 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 4420 } | 4419 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4472 } | 4471 } |
| 4473 | 4472 |
| 4474 // Check the state of the object | 4473 // Check the state of the object |
| 4475 ASSERT(JSObject::cast(result)->HasFastProperties()); | 4474 ASSERT(JSObject::cast(result)->HasFastProperties()); |
| 4476 ASSERT(JSObject::cast(result)->HasFastObjectElements()); | 4475 ASSERT(JSObject::cast(result)->HasFastObjectElements()); |
| 4477 | 4476 |
| 4478 return result; | 4477 return result; |
| 4479 } | 4478 } |
| 4480 | 4479 |
| 4481 | 4480 |
| 4482 MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) { | |
| 4483 ASSERT(!fun->has_initial_map()); | |
| 4484 | |
| 4485 // First create a new map with the size and number of in-object properties | |
| 4486 // suggested by the function. | |
| 4487 InstanceType instance_type; | |
| 4488 int instance_size; | |
| 4489 int in_object_properties; | |
| 4490 if (fun->shared()->is_generator()) { | |
| 4491 instance_type = JS_GENERATOR_OBJECT_TYPE; | |
| 4492 instance_size = JSGeneratorObject::kSize; | |
| 4493 in_object_properties = 0; | |
| 4494 } else { | |
| 4495 instance_type = JS_OBJECT_TYPE; | |
| 4496 instance_size = fun->shared()->CalculateInstanceSize(); | |
| 4497 in_object_properties = fun->shared()->CalculateInObjectProperties(); | |
| 4498 } | |
| 4499 Map* map; | |
| 4500 MaybeObject* maybe_map = AllocateMap(instance_type, instance_size); | |
| 4501 if (!maybe_map->To(&map)) return maybe_map; | |
| 4502 | |
| 4503 // Fetch or allocate prototype. | |
| 4504 Object* prototype; | |
| 4505 if (fun->has_instance_prototype()) { | |
| 4506 prototype = fun->instance_prototype(); | |
| 4507 } else { | |
| 4508 MaybeObject* maybe_prototype = AllocateFunctionPrototype(fun); | |
| 4509 if (!maybe_prototype->To(&prototype)) return maybe_prototype; | |
| 4510 } | |
| 4511 map->set_inobject_properties(in_object_properties); | |
| 4512 map->set_unused_property_fields(in_object_properties); | |
| 4513 map->set_prototype(prototype); | |
| 4514 ASSERT(map->has_fast_object_elements()); | |
| 4515 | |
| 4516 if (!fun->shared()->is_generator()) { | |
| 4517 fun->shared()->StartInobjectSlackTracking(map); | |
| 4518 } | |
| 4519 | |
| 4520 return map; | |
| 4521 } | |
| 4522 | |
| 4523 | |
| 4524 void Heap::InitializeJSObjectFromMap(JSObject* obj, | 4481 void Heap::InitializeJSObjectFromMap(JSObject* obj, |
| 4525 FixedArray* properties, | 4482 FixedArray* properties, |
| 4526 Map* map) { | 4483 Map* map) { |
| 4527 obj->set_properties(properties); | 4484 obj->set_properties(properties); |
| 4528 obj->initialize_elements(); | 4485 obj->initialize_elements(); |
| 4529 // TODO(1240798): Initialize the object's body using valid initial values | 4486 // TODO(1240798): Initialize the object's body using valid initial values |
| 4530 // according to the object's initial map. For example, if the map's | 4487 // according to the object's initial map. For example, if the map's |
| 4531 // instance type is JS_ARRAY_TYPE, the length field should be initialized | 4488 // instance type is JS_ARRAY_TYPE, the length field should be initialized |
| 4532 // to a number (e.g. Smi::FromInt(0)) and the elements initialized to a | 4489 // to a number (e.g. Smi::FromInt(0)) and the elements initialized to a |
| 4533 // fixed array (e.g. Heap::empty_fixed_array()). Currently, the object | 4490 // fixed array (e.g. Heap::empty_fixed_array()). Currently, the object |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4620 | 4577 |
| 4621 // Initialize the JSObject. | 4578 // Initialize the JSObject. |
| 4622 InitializeJSObjectFromMap(JSObject::cast(obj), properties, map); | 4579 InitializeJSObjectFromMap(JSObject::cast(obj), properties, map); |
| 4623 ASSERT(JSObject::cast(obj)->HasFastElements()); | 4580 ASSERT(JSObject::cast(obj)->HasFastElements()); |
| 4624 return obj; | 4581 return obj; |
| 4625 } | 4582 } |
| 4626 | 4583 |
| 4627 | 4584 |
| 4628 MaybeObject* Heap::AllocateJSObject(JSFunction* constructor, | 4585 MaybeObject* Heap::AllocateJSObject(JSFunction* constructor, |
| 4629 PretenureFlag pretenure) { | 4586 PretenureFlag pretenure) { |
| 4630 // Allocate the initial map if absent. | 4587 ASSERT(constructor->has_initial_map()); |
| 4631 if (!constructor->has_initial_map()) { | |
| 4632 Object* initial_map; | |
| 4633 { MaybeObject* maybe_initial_map = AllocateInitialMap(constructor); | |
| 4634 if (!maybe_initial_map->ToObject(&initial_map)) return maybe_initial_map; | |
| 4635 } | |
| 4636 constructor->set_initial_map(Map::cast(initial_map)); | |
| 4637 Map::cast(initial_map)->set_constructor(constructor); | |
| 4638 } | |
| 4639 // Allocate the object based on the constructors initial map. | 4588 // Allocate the object based on the constructors initial map. |
| 4640 MaybeObject* result = AllocateJSObjectFromMap( | 4589 MaybeObject* result = AllocateJSObjectFromMap( |
| 4641 constructor->initial_map(), pretenure); | 4590 constructor->initial_map(), pretenure); |
| 4642 #ifdef DEBUG | 4591 #ifdef DEBUG |
| 4643 // Make sure result is NOT a global object if valid. | 4592 // Make sure result is NOT a global object if valid. |
| 4644 Object* non_failure; | 4593 Object* non_failure; |
| 4645 ASSERT(!result->ToObject(&non_failure) || !non_failure->IsGlobalObject()); | 4594 ASSERT(!result->ToObject(&non_failure) || !non_failure->IsGlobalObject()); |
| 4646 #endif | 4595 #endif |
| 4647 return result; | 4596 return result; |
| 4648 } | 4597 } |
| 4649 | 4598 |
| 4650 | 4599 |
| 4651 MaybeObject* Heap::AllocateJSObjectWithAllocationSite(JSFunction* constructor, | 4600 MaybeObject* Heap::AllocateJSObjectWithAllocationSite(JSFunction* constructor, |
| 4652 Handle<AllocationSite> allocation_site) { | 4601 Handle<AllocationSite> allocation_site) { |
| 4653 // Allocate the initial map if absent. | 4602 ASSERT(constructor->has_initial_map()); |
| 4654 if (!constructor->has_initial_map()) { | |
| 4655 Object* initial_map; | |
| 4656 { MaybeObject* maybe_initial_map = AllocateInitialMap(constructor); | |
| 4657 if (!maybe_initial_map->ToObject(&initial_map)) return maybe_initial_map; | |
| 4658 } | |
| 4659 constructor->set_initial_map(Map::cast(initial_map)); | |
| 4660 Map::cast(initial_map)->set_constructor(constructor); | |
| 4661 } | |
| 4662 // Allocate the object based on the constructors initial map, or the payload | 4603 // Allocate the object based on the constructors initial map, or the payload |
| 4663 // advice | 4604 // advice |
| 4664 Map* initial_map = constructor->initial_map(); | 4605 Map* initial_map = constructor->initial_map(); |
| 4665 | 4606 |
| 4666 Smi* smi = Smi::cast(allocation_site->transition_info()); | 4607 Smi* smi = Smi::cast(allocation_site->transition_info()); |
| 4667 ElementsKind to_kind = static_cast<ElementsKind>(smi->value()); | 4608 ElementsKind to_kind = static_cast<ElementsKind>(smi->value()); |
| 4668 AllocationSiteMode mode = TRACK_ALLOCATION_SITE; | 4609 AllocationSiteMode mode = TRACK_ALLOCATION_SITE; |
| 4669 if (to_kind != initial_map->elements_kind()) { | 4610 if (to_kind != initial_map->elements_kind()) { |
| 4670 MaybeObject* maybe_new_map = initial_map->AsElementsKind(to_kind); | 4611 MaybeObject* maybe_new_map = initial_map->AsElementsKind(to_kind); |
| 4671 if (!maybe_new_map->To(&initial_map)) return maybe_new_map; | 4612 if (!maybe_new_map->To(&initial_map)) return maybe_new_map; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4683 } | 4624 } |
| 4684 #ifdef DEBUG | 4625 #ifdef DEBUG |
| 4685 // Make sure result is NOT a global object if valid. | 4626 // Make sure result is NOT a global object if valid. |
| 4686 Object* non_failure; | 4627 Object* non_failure; |
| 4687 ASSERT(!result->ToObject(&non_failure) || !non_failure->IsGlobalObject()); | 4628 ASSERT(!result->ToObject(&non_failure) || !non_failure->IsGlobalObject()); |
| 4688 #endif | 4629 #endif |
| 4689 return result; | 4630 return result; |
| 4690 } | 4631 } |
| 4691 | 4632 |
| 4692 | 4633 |
| 4693 MaybeObject* Heap::AllocateJSGeneratorObject(JSFunction *function) { | |
| 4694 ASSERT(function->shared()->is_generator()); | |
| 4695 Map *map; | |
| 4696 if (function->has_initial_map()) { | |
| 4697 map = function->initial_map(); | |
| 4698 } else { | |
| 4699 // Allocate the initial map if absent. | |
| 4700 MaybeObject* maybe_map = AllocateInitialMap(function); | |
| 4701 if (!maybe_map->To(&map)) return maybe_map; | |
| 4702 function->set_initial_map(map); | |
| 4703 map->set_constructor(function); | |
| 4704 } | |
| 4705 ASSERT(map->instance_type() == JS_GENERATOR_OBJECT_TYPE); | |
| 4706 return AllocateJSObjectFromMap(map); | |
| 4707 } | |
| 4708 | |
| 4709 | |
| 4710 MaybeObject* Heap::AllocateJSModule(Context* context, ScopeInfo* scope_info) { | 4634 MaybeObject* Heap::AllocateJSModule(Context* context, ScopeInfo* scope_info) { |
| 4711 // Allocate a fresh map. Modules do not have a prototype. | 4635 // Allocate a fresh map. Modules do not have a prototype. |
| 4712 Map* map; | 4636 Map* map; |
| 4713 MaybeObject* maybe_map = AllocateMap(JS_MODULE_TYPE, JSModule::kSize); | 4637 MaybeObject* maybe_map = AllocateMap(JS_MODULE_TYPE, JSModule::kSize); |
| 4714 if (!maybe_map->To(&map)) return maybe_map; | 4638 if (!maybe_map->To(&map)) return maybe_map; |
| 4715 // Allocate the object based on the map. | 4639 // Allocate the object based on the map. |
| 4716 JSModule* module; | 4640 JSModule* module; |
| 4717 MaybeObject* maybe_module = AllocateJSObjectFromMap(map, TENURED); | 4641 MaybeObject* maybe_module = AllocateJSObjectFromMap(map, TENURED); |
| 4718 if (!maybe_module->To(&module)) return maybe_module; | 4642 if (!maybe_module->To(&module)) return maybe_module; |
| 4719 module->set_context(context); | 4643 module->set_context(context); |
| (...skipping 2090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6810 } | 6734 } |
| 6811 | 6735 |
| 6812 | 6736 |
| 6813 void Heap::TearDown() { | 6737 void Heap::TearDown() { |
| 6814 #ifdef VERIFY_HEAP | 6738 #ifdef VERIFY_HEAP |
| 6815 if (FLAG_verify_heap) { | 6739 if (FLAG_verify_heap) { |
| 6816 Verify(); | 6740 Verify(); |
| 6817 } | 6741 } |
| 6818 #endif | 6742 #endif |
| 6819 | 6743 |
| 6744 UpdateMaximumCommitted(); |
| 6745 |
| 6820 if (FLAG_print_cumulative_gc_stat) { | 6746 if (FLAG_print_cumulative_gc_stat) { |
| 6821 PrintF("\n"); | 6747 PrintF("\n"); |
| 6822 PrintF("gc_count=%d ", gc_count_); | 6748 PrintF("gc_count=%d ", gc_count_); |
| 6823 PrintF("mark_sweep_count=%d ", ms_count_); | 6749 PrintF("mark_sweep_count=%d ", ms_count_); |
| 6824 PrintF("max_gc_pause=%.1f ", get_max_gc_pause()); | 6750 PrintF("max_gc_pause=%.1f ", get_max_gc_pause()); |
| 6825 PrintF("total_gc_time=%.1f ", total_gc_time_ms_); | 6751 PrintF("total_gc_time=%.1f ", total_gc_time_ms_); |
| 6826 PrintF("min_in_mutator=%.1f ", get_min_in_mutator()); | 6752 PrintF("min_in_mutator=%.1f ", get_min_in_mutator()); |
| 6827 PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ", | 6753 PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ", |
| 6828 get_max_alive_after_gc()); | 6754 get_max_alive_after_gc()); |
| 6829 PrintF("total_marking_time=%.1f ", marking_time()); | 6755 PrintF("total_marking_time=%.1f ", marking_time()); |
| 6830 PrintF("total_sweeping_time=%.1f ", sweeping_time()); | 6756 PrintF("total_sweeping_time=%.1f ", sweeping_time()); |
| 6831 PrintF("\n\n"); | 6757 PrintF("\n\n"); |
| 6832 } | 6758 } |
| 6833 | 6759 |
| 6760 if (FLAG_print_max_heap_committed) { |
| 6761 PrintF("\n"); |
| 6762 PrintF("maximum_committed_by_heap=%" V8_PTR_PREFIX "d ", |
| 6763 MaximumCommittedMemory()); |
| 6764 PrintF("maximum_committed_by_new_space=%" V8_PTR_PREFIX "d ", |
| 6765 new_space_.MaximumCommittedMemory()); |
| 6766 PrintF("maximum_committed_by_old_pointer_space=%" V8_PTR_PREFIX "d ", |
| 6767 old_data_space_->MaximumCommittedMemory()); |
| 6768 PrintF("maximum_committed_by_old_data_space=%" V8_PTR_PREFIX "d ", |
| 6769 old_pointer_space_->MaximumCommittedMemory()); |
| 6770 PrintF("maximum_committed_by_old_data_space=%" V8_PTR_PREFIX "d ", |
| 6771 old_pointer_space_->MaximumCommittedMemory()); |
| 6772 PrintF("maximum_committed_by_code_space=%" V8_PTR_PREFIX "d ", |
| 6773 code_space_->MaximumCommittedMemory()); |
| 6774 PrintF("maximum_committed_by_map_space=%" V8_PTR_PREFIX "d ", |
| 6775 map_space_->MaximumCommittedMemory()); |
| 6776 PrintF("maximum_committed_by_cell_space=%" V8_PTR_PREFIX "d ", |
| 6777 cell_space_->MaximumCommittedMemory()); |
| 6778 PrintF("maximum_committed_by_property_space=%" V8_PTR_PREFIX "d ", |
| 6779 property_cell_space_->MaximumCommittedMemory()); |
| 6780 PrintF("maximum_committed_by_lo_space=%" V8_PTR_PREFIX "d ", |
| 6781 lo_space_->MaximumCommittedMemory()); |
| 6782 PrintF("\n\n"); |
| 6783 } |
| 6784 |
| 6834 TearDownArrayBuffers(); | 6785 TearDownArrayBuffers(); |
| 6835 | 6786 |
| 6836 isolate_->global_handles()->TearDown(); | 6787 isolate_->global_handles()->TearDown(); |
| 6837 | 6788 |
| 6838 external_string_table_.TearDown(); | 6789 external_string_table_.TearDown(); |
| 6839 | 6790 |
| 6840 mark_compact_collector()->TearDown(); | 6791 mark_compact_collector()->TearDown(); |
| 6841 | 6792 |
| 6842 new_space_.TearDown(); | 6793 new_space_.TearDown(); |
| 6843 | 6794 |
| (...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7942 counters->count_of_FIXED_ARRAY_##name()->Increment( \ | 7893 counters->count_of_FIXED_ARRAY_##name()->Increment( \ |
| 7943 static_cast<int>(object_counts_[index])); \ | 7894 static_cast<int>(object_counts_[index])); \ |
| 7944 counters->count_of_FIXED_ARRAY_##name()->Decrement( \ | 7895 counters->count_of_FIXED_ARRAY_##name()->Decrement( \ |
| 7945 static_cast<int>(object_counts_last_time_[index])); \ | 7896 static_cast<int>(object_counts_last_time_[index])); \ |
| 7946 counters->size_of_FIXED_ARRAY_##name()->Increment( \ | 7897 counters->size_of_FIXED_ARRAY_##name()->Increment( \ |
| 7947 static_cast<int>(object_sizes_[index])); \ | 7898 static_cast<int>(object_sizes_[index])); \ |
| 7948 counters->size_of_FIXED_ARRAY_##name()->Decrement( \ | 7899 counters->size_of_FIXED_ARRAY_##name()->Decrement( \ |
| 7949 static_cast<int>(object_sizes_last_time_[index])); | 7900 static_cast<int>(object_sizes_last_time_[index])); |
| 7950 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) | 7901 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) |
| 7951 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 7902 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
| 7952 #define ADJUST_LAST_TIME_OBJECT_COUNT(name) \ | 7903 #define ADJUST_LAST_TIME_OBJECT_COUNT(name) \ |
| 7953 index = FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge; \ | 7904 index = \ |
| 7954 counters->count_of_CODE_AGE_##name()->Increment( \ | 7905 FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge - Code::kFirstCodeAge; \ |
| 7955 static_cast<int>(object_counts_[index])); \ | 7906 counters->count_of_CODE_AGE_##name()->Increment( \ |
| 7956 counters->count_of_CODE_AGE_##name()->Decrement( \ | 7907 static_cast<int>(object_counts_[index])); \ |
| 7957 static_cast<int>(object_counts_last_time_[index])); \ | 7908 counters->count_of_CODE_AGE_##name()->Decrement( \ |
| 7958 counters->size_of_CODE_AGE_##name()->Increment( \ | 7909 static_cast<int>(object_counts_last_time_[index])); \ |
| 7959 static_cast<int>(object_sizes_[index])); \ | 7910 counters->size_of_CODE_AGE_##name()->Increment( \ |
| 7960 counters->size_of_CODE_AGE_##name()->Decrement( \ | 7911 static_cast<int>(object_sizes_[index])); \ |
| 7912 counters->size_of_CODE_AGE_##name()->Decrement( \ |
| 7961 static_cast<int>(object_sizes_last_time_[index])); | 7913 static_cast<int>(object_sizes_last_time_[index])); |
| 7962 CODE_AGE_LIST_WITH_NO_AGE(ADJUST_LAST_TIME_OBJECT_COUNT) | 7914 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) |
| 7963 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 7915 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
| 7964 | 7916 |
| 7965 OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 7917 OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
| 7966 OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 7918 OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
| 7967 ClearObjectStats(); | 7919 ClearObjectStats(); |
| 7968 } | 7920 } |
| 7969 | 7921 |
| 7970 | 7922 |
| 7971 Heap::RelocationLock::RelocationLock(Heap* heap) : heap_(heap) { | 7923 Heap::RelocationLock::RelocationLock(Heap* heap) : heap_(heap) { |
| 7972 if (FLAG_concurrent_recompilation) { | 7924 if (FLAG_concurrent_recompilation) { |
| 7973 heap_->relocation_mutex_->Lock(); | 7925 heap_->relocation_mutex_->Lock(); |
| 7974 #ifdef DEBUG | 7926 #ifdef DEBUG |
| 7975 heap_->relocation_mutex_locked_by_optimizer_thread_ = | 7927 heap_->relocation_mutex_locked_by_optimizer_thread_ = |
| 7976 heap_->isolate()->optimizing_compiler_thread()->IsOptimizerThread(); | 7928 heap_->isolate()->optimizing_compiler_thread()->IsOptimizerThread(); |
| 7977 #endif // DEBUG | 7929 #endif // DEBUG |
| 7978 } | 7930 } |
| 7979 } | 7931 } |
| 7980 | 7932 |
| 7981 } } // namespace v8::internal | 7933 } } // namespace v8::internal |
| OLD | NEW |