Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: src/mark-compact.cc

Issue 188783003: Make maps in monomorphic IC stubs weak. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase, address comments Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mark-compact.h ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 if (!FLAG_collect_maps) ReattachInitialMaps(); 442 if (!FLAG_collect_maps) ReattachInitialMaps();
443 443
444 #ifdef DEBUG 444 #ifdef DEBUG
445 if (FLAG_verify_native_context_separation) { 445 if (FLAG_verify_native_context_separation) {
446 VerifyNativeContextSeparation(heap_); 446 VerifyNativeContextSeparation(heap_);
447 } 447 }
448 #endif 448 #endif
449 449
450 #ifdef VERIFY_HEAP 450 #ifdef VERIFY_HEAP
451 if (heap()->weak_embedded_objects_verification_enabled()) { 451 if (heap()->weak_embedded_objects_verification_enabled()) {
452 VerifyWeakEmbeddedObjectsInOptimizedCode(); 452 VerifyWeakEmbeddedObjectsInCode();
453 } 453 }
454 if (FLAG_collect_maps && FLAG_omit_map_checks_for_leaf_maps) { 454 if (FLAG_collect_maps && FLAG_omit_map_checks_for_leaf_maps) {
455 VerifyOmittedMapChecks(); 455 VerifyOmittedMapChecks();
456 } 456 }
457 #endif 457 #endif
458 458
459 Finish(); 459 Finish();
460 460
461 if (marking_parity_ == EVEN_MARKING_PARITY) { 461 if (marking_parity_ == EVEN_MARKING_PARITY) {
462 marking_parity_ = ODD_MARKING_PARITY; 462 marking_parity_ = ODD_MARKING_PARITY;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 503
504 LargeObjectIterator it(heap_->lo_space()); 504 LargeObjectIterator it(heap_->lo_space());
505 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 505 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
506 MarkBit mark_bit = Marking::MarkBitFrom(obj); 506 MarkBit mark_bit = Marking::MarkBitFrom(obj);
507 CHECK(Marking::IsWhite(mark_bit)); 507 CHECK(Marking::IsWhite(mark_bit));
508 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes()); 508 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes());
509 } 509 }
510 } 510 }
511 511
512 512
513 void MarkCompactCollector::VerifyWeakEmbeddedObjectsInOptimizedCode() { 513 void MarkCompactCollector::VerifyWeakEmbeddedObjectsInCode() {
514 HeapObjectIterator code_iterator(heap()->code_space()); 514 HeapObjectIterator code_iterator(heap()->code_space());
515 for (HeapObject* obj = code_iterator.Next(); 515 for (HeapObject* obj = code_iterator.Next();
516 obj != NULL; 516 obj != NULL;
517 obj = code_iterator.Next()) { 517 obj = code_iterator.Next()) {
518 Code* code = Code::cast(obj); 518 Code* code = Code::cast(obj);
519 if (code->kind() != Code::OPTIMIZED_FUNCTION) continue; 519 if (!code->is_optimized_code() && !code->is_weak_stub()) continue;
520 if (WillBeDeoptimized(code)) continue; 520 if (WillBeDeoptimized(code)) continue;
521 code->VerifyEmbeddedObjectsDependency(); 521 code->VerifyEmbeddedObjectsDependency();
522 } 522 }
523 } 523 }
524 524
525 525
526 void MarkCompactCollector::VerifyOmittedMapChecks() { 526 void MarkCompactCollector::VerifyOmittedMapChecks() {
527 HeapObjectIterator iterator(heap()->map_space()); 527 HeapObjectIterator iterator(heap()->map_space());
528 for (HeapObject* obj = iterator.Next(); 528 for (HeapObject* obj = iterator.Next();
529 obj != NULL; 529 obj != NULL;
(...skipping 2046 matching lines...) Expand 10 before | Expand all | Expand 10 after
2576 // Since it survived the GC, reattach it now. 2576 // Since it survived the GC, reattach it now.
2577 JSFunction::cast(map->constructor())->shared()->AttachInitialMap(map); 2577 JSFunction::cast(map->constructor())->shared()->AttachInitialMap(map);
2578 } 2578 }
2579 2579
2580 ClearNonLivePrototypeTransitions(map); 2580 ClearNonLivePrototypeTransitions(map);
2581 ClearNonLiveMapTransitions(map, map_mark); 2581 ClearNonLiveMapTransitions(map, map_mark);
2582 2582
2583 if (map_mark.Get()) { 2583 if (map_mark.Get()) {
2584 ClearNonLiveDependentCode(map->dependent_code()); 2584 ClearNonLiveDependentCode(map->dependent_code());
2585 } else { 2585 } else {
2586 ClearAndDeoptimizeDependentCode(map->dependent_code()); 2586 ClearDependentCode(map->dependent_code());
2587 map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array())); 2587 map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array()));
2588 } 2588 }
2589 } 2589 }
2590 2590
2591 // Iterate over property cell space, removing dependent code that is not 2591 // Iterate over property cell space, removing dependent code that is not
2592 // otherwise kept alive by strong references. 2592 // otherwise kept alive by strong references.
2593 HeapObjectIterator cell_iterator(heap_->property_cell_space()); 2593 HeapObjectIterator cell_iterator(heap_->property_cell_space());
2594 for (HeapObject* cell = cell_iterator.Next(); 2594 for (HeapObject* cell = cell_iterator.Next();
2595 cell != NULL; 2595 cell != NULL;
2596 cell = cell_iterator.Next()) { 2596 cell = cell_iterator.Next()) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2631 } 2631 }
2632 } 2632 }
2633 if (IsMarked(key)) { 2633 if (IsMarked(key)) {
2634 if (!IsMarked(value)) { 2634 if (!IsMarked(value)) {
2635 HeapObject* obj = HeapObject::cast(value); 2635 HeapObject* obj = HeapObject::cast(value);
2636 MarkBit mark = Marking::MarkBitFrom(obj); 2636 MarkBit mark = Marking::MarkBitFrom(obj);
2637 SetMark(obj, mark); 2637 SetMark(obj, mark);
2638 } 2638 }
2639 ClearNonLiveDependentCode(DependentCode::cast(value)); 2639 ClearNonLiveDependentCode(DependentCode::cast(value));
2640 } else { 2640 } else {
2641 ClearAndDeoptimizeDependentCode(DependentCode::cast(value)); 2641 ClearDependentCode(DependentCode::cast(value));
2642 table->set(key_index, heap_->the_hole_value()); 2642 table->set(key_index, heap_->the_hole_value());
2643 table->set(value_index, heap_->the_hole_value()); 2643 table->set(value_index, heap_->the_hole_value());
2644 } 2644 }
2645 } 2645 }
2646 } 2646 }
2647 } 2647 }
2648 2648
2649 2649
2650 void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) { 2650 void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) {
2651 int number_of_transitions = map->NumberOfProtoTransitions(); 2651 int number_of_transitions = map->NumberOfProtoTransitions();
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2701 // Follow back pointer, check whether we are dealing with a map transition 2701 // Follow back pointer, check whether we are dealing with a map transition
2702 // from a live map to a dead path and in case clear transitions of parent. 2702 // from a live map to a dead path and in case clear transitions of parent.
2703 bool current_is_alive = map_mark.Get(); 2703 bool current_is_alive = map_mark.Get();
2704 bool parent_is_alive = Marking::MarkBitFrom(parent).Get(); 2704 bool parent_is_alive = Marking::MarkBitFrom(parent).Get();
2705 if (!current_is_alive && parent_is_alive) { 2705 if (!current_is_alive && parent_is_alive) {
2706 parent->ClearNonLiveTransitions(heap()); 2706 parent->ClearNonLiveTransitions(heap());
2707 } 2707 }
2708 } 2708 }
2709 2709
2710 2710
2711 void MarkCompactCollector::ClearAndDeoptimizeDependentCode( 2711 void MarkCompactCollector::ClearDependentICList(Object* head) {
2712 Object* current = head;
2713 Object* undefined = heap()->undefined_value();
2714 while (current != undefined) {
2715 Code* code = Code::cast(current);
2716 if (IsMarked(code)) {
2717 ASSERT(code->is_weak_stub());
2718 IC::InvalidateMaps(code);
2719 }
2720 current = code->next_code_link();
2721 code->set_next_code_link(undefined);
2722 }
2723 }
2724
2725
2726 void MarkCompactCollector::ClearDependentCode(
2712 DependentCode* entries) { 2727 DependentCode* entries) {
2713 DisallowHeapAllocation no_allocation; 2728 DisallowHeapAllocation no_allocation;
2714 DependentCode::GroupStartIndexes starts(entries); 2729 DependentCode::GroupStartIndexes starts(entries);
2715 int number_of_entries = starts.number_of_entries(); 2730 int number_of_entries = starts.number_of_entries();
2716 if (number_of_entries == 0) return; 2731 if (number_of_entries == 0) return;
2717 for (int i = 0; i < number_of_entries; i++) { 2732 int g = DependentCode::kWeakICGroup;
2733 if (starts.at(g) != starts.at(g + 1)) {
2734 int i = starts.at(g);
2735 ASSERT(i + 1 == starts.at(g + 1));
2736 Object* head = entries->object_at(i);
2737 ClearDependentICList(head);
2738 }
2739 g = DependentCode::kWeakCodeGroup;
2740 for (int i = starts.at(g); i < starts.at(g + 1); i++) {
2718 // If the entry is compilation info then the map must be alive, 2741 // If the entry is compilation info then the map must be alive,
2719 // and ClearAndDeoptimizeDependentCode shouldn't be called. 2742 // and ClearDependentCode shouldn't be called.
2720 ASSERT(entries->is_code_at(i)); 2743 ASSERT(entries->is_code_at(i));
2721 Code* code = entries->code_at(i); 2744 Code* code = entries->code_at(i);
2722
2723 if (IsMarked(code) && !code->marked_for_deoptimization()) { 2745 if (IsMarked(code) && !code->marked_for_deoptimization()) {
2724 code->set_marked_for_deoptimization(true); 2746 code->set_marked_for_deoptimization(true);
2725 code->InvalidateEmbeddedObjects(); 2747 code->InvalidateEmbeddedObjects();
2726 have_code_to_deoptimize_ = true; 2748 have_code_to_deoptimize_ = true;
2727 } 2749 }
2750 }
2751 for (int i = 0; i < number_of_entries; i++) {
2728 entries->clear_at(i); 2752 entries->clear_at(i);
2729 } 2753 }
2730 } 2754 }
2731 2755
2732 2756
2757 int MarkCompactCollector::ClearNonLiveDependentCodeInGroup(
2758 DependentCode* entries, int group, int start, int end, int new_start) {
2759 int survived = 0;
2760 if (group == DependentCode::kWeakICGroup) {
2761 // Dependent weak IC stubs form a linked list and only the head is stored
2762 // in the dependent code array.
2763 if (start != end) {
2764 ASSERT(start + 1 == end);
2765 Object* old_head = entries->object_at(start);
2766 MarkCompactWeakObjectRetainer retainer;
2767 Object* head = VisitWeakList<Code>(heap(), old_head, &retainer, true);
2768 entries->set_object_at(new_start, head);
2769 Object** slot = entries->slot_at(new_start);
2770 RecordSlot(slot, slot, head);
2771 // We do not compact this group even if the head is undefined,
2772 // more dependent ICs are likely to be added later.
2773 survived = 1;
2774 }
2775 } else {
2776 for (int i = start; i < end; i++) {
2777 Object* obj = entries->object_at(i);
2778 ASSERT(obj->IsCode() || IsMarked(obj));
2779 if (IsMarked(obj) &&
2780 (!obj->IsCode() || !WillBeDeoptimized(Code::cast(obj)))) {
2781 if (new_start + survived != i) {
2782 entries->set_object_at(new_start + survived, obj);
2783 }
2784 Object** slot = entries->slot_at(new_start + survived);
2785 RecordSlot(slot, slot, obj);
2786 survived++;
2787 }
2788 }
2789 }
2790 entries->set_number_of_entries(
2791 static_cast<DependentCode::DependencyGroup>(group), survived);
2792 return survived;
2793 }
2794
2795
2733 void MarkCompactCollector::ClearNonLiveDependentCode(DependentCode* entries) { 2796 void MarkCompactCollector::ClearNonLiveDependentCode(DependentCode* entries) {
2734 DisallowHeapAllocation no_allocation; 2797 DisallowHeapAllocation no_allocation;
2735 DependentCode::GroupStartIndexes starts(entries); 2798 DependentCode::GroupStartIndexes starts(entries);
2736 int number_of_entries = starts.number_of_entries(); 2799 int number_of_entries = starts.number_of_entries();
2737 if (number_of_entries == 0) return; 2800 if (number_of_entries == 0) return;
2738 int new_number_of_entries = 0; 2801 int new_number_of_entries = 0;
2739 // Go through all groups, remove dead codes and compact. 2802 // Go through all groups, remove dead codes and compact.
2740 for (int g = 0; g < DependentCode::kGroupCount; g++) { 2803 for (int g = 0; g < DependentCode::kGroupCount; g++) {
2741 int group_number_of_entries = 0; 2804 int survived = ClearNonLiveDependentCodeInGroup(
2742 for (int i = starts.at(g); i < starts.at(g + 1); i++) { 2805 entries, g, starts.at(g), starts.at(g + 1), new_number_of_entries);
2743 Object* obj = entries->object_at(i); 2806 new_number_of_entries += survived;
2744 ASSERT(obj->IsCode() || IsMarked(obj));
2745 if (IsMarked(obj) &&
2746 (!obj->IsCode() || !WillBeDeoptimized(Code::cast(obj)))) {
2747 if (new_number_of_entries + group_number_of_entries != i) {
2748 entries->set_object_at(
2749 new_number_of_entries + group_number_of_entries, obj);
2750 }
2751 Object** slot = entries->slot_at(new_number_of_entries +
2752 group_number_of_entries);
2753 RecordSlot(slot, slot, obj);
2754 group_number_of_entries++;
2755 }
2756 }
2757 entries->set_number_of_entries(
2758 static_cast<DependentCode::DependencyGroup>(g),
2759 group_number_of_entries);
2760 new_number_of_entries += group_number_of_entries;
2761 } 2807 }
2762 for (int i = new_number_of_entries; i < number_of_entries; i++) { 2808 for (int i = new_number_of_entries; i < number_of_entries; i++) {
2763 entries->clear_at(i); 2809 entries->clear_at(i);
2764 } 2810 }
2765 } 2811 }
2766 2812
2767 2813
2768 void MarkCompactCollector::ProcessWeakCollections() { 2814 void MarkCompactCollector::ProcessWeakCollections() {
2769 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_WEAKCOLLECTION_PROCESS); 2815 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_WEAKCOLLECTION_PROCESS);
2770 Object* weak_collection_obj = encountered_weak_collections(); 2816 Object* weak_collection_obj = encountered_weak_collections();
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after
3407 MarkBit mark_bit = Marking::MarkBitFrom(code); 3453 MarkBit mark_bit = Marking::MarkBitFrom(code);
3408 if (Marking::IsWhite(mark_bit)) return; 3454 if (Marking::IsWhite(mark_bit)) return;
3409 3455
3410 invalidated_code_.Add(code); 3456 invalidated_code_.Add(code);
3411 } 3457 }
3412 } 3458 }
3413 3459
3414 3460
3415 // Return true if the given code is deoptimized or will be deoptimized. 3461 // Return true if the given code is deoptimized or will be deoptimized.
3416 bool MarkCompactCollector::WillBeDeoptimized(Code* code) { 3462 bool MarkCompactCollector::WillBeDeoptimized(Code* code) {
3417 return code->marked_for_deoptimization(); 3463 return code->is_optimized_code() && code->marked_for_deoptimization();
3418 } 3464 }
3419 3465
3420 3466
3421 bool MarkCompactCollector::MarkInvalidatedCode() { 3467 bool MarkCompactCollector::MarkInvalidatedCode() {
3422 bool code_marked = false; 3468 bool code_marked = false;
3423 3469
3424 int length = invalidated_code_.length(); 3470 int length = invalidated_code_.length();
3425 for (int i = 0; i < length; i++) { 3471 for (int i = 0; i < length; i++) {
3426 Code* code = invalidated_code_[i]; 3472 Code* code = invalidated_code_[i];
3427 3473
(...skipping 1101 matching lines...) Expand 10 before | Expand all | Expand 10 after
4529 while (buffer != NULL) { 4575 while (buffer != NULL) {
4530 SlotsBuffer* next_buffer = buffer->next(); 4576 SlotsBuffer* next_buffer = buffer->next();
4531 DeallocateBuffer(buffer); 4577 DeallocateBuffer(buffer);
4532 buffer = next_buffer; 4578 buffer = next_buffer;
4533 } 4579 }
4534 *buffer_address = NULL; 4580 *buffer_address = NULL;
4535 } 4581 }
4536 4582
4537 4583
4538 } } // namespace v8::internal 4584 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mark-compact.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698