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

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

Issue 7282026: Introduce code flushing of RegExp code. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 5 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 void>::Visit); 417 void>::Visit);
418 418
419 table_.Register(kVisitCode, &VisitCode); 419 table_.Register(kVisitCode, &VisitCode);
420 420
421 table_.Register(kVisitSharedFunctionInfo, 421 table_.Register(kVisitSharedFunctionInfo,
422 &VisitSharedFunctionInfoAndFlushCode); 422 &VisitSharedFunctionInfoAndFlushCode);
423 423
424 table_.Register(kVisitJSFunction, 424 table_.Register(kVisitJSFunction,
425 &VisitJSFunctionAndFlushCode); 425 &VisitJSFunctionAndFlushCode);
426 426
427 table_.Register(kVisitJSRegExp,
428 &VisitRegExpAndFlushCode);
429
427 table_.Register(kVisitPropertyCell, 430 table_.Register(kVisitPropertyCell,
428 &FixedBodyVisitor<StaticMarkingVisitor, 431 &FixedBodyVisitor<StaticMarkingVisitor,
429 JSGlobalPropertyCell::BodyDescriptor, 432 JSGlobalPropertyCell::BodyDescriptor,
430 void>::Visit); 433 void>::Visit);
431 434
432 table_.RegisterSpecializations<DataObjectVisitor, 435 table_.RegisterSpecializations<DataObjectVisitor,
433 kVisitDataObject, 436 kVisitDataObject,
434 kVisitDataObjectGeneric>(); 437 kVisitDataObjectGeneric>();
435 438
436 table_.RegisterSpecializations<JSObjectVisitor, 439 table_.RegisterSpecializations<JSObjectVisitor,
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 reinterpret_cast<Code*>(object)->CodeIterateBody<StaticMarkingVisitor>( 560 reinterpret_cast<Code*>(object)->CodeIterateBody<StaticMarkingVisitor>(
558 map->heap()); 561 map->heap());
559 } 562 }
560 563
561 // Code flushing support. 564 // Code flushing support.
562 565
563 // How many collections newly compiled code object will survive before being 566 // How many collections newly compiled code object will survive before being
564 // flushed. 567 // flushed.
565 static const int kCodeAgeThreshold = 5; 568 static const int kCodeAgeThreshold = 5;
566 569
570 static const int kRegExpCodeThreshold = 5;
571
567 inline static bool HasSourceCode(Heap* heap, SharedFunctionInfo* info) { 572 inline static bool HasSourceCode(Heap* heap, SharedFunctionInfo* info) {
568 Object* undefined = heap->raw_unchecked_undefined_value(); 573 Object* undefined = heap->raw_unchecked_undefined_value();
569 return (info->script() != undefined) && 574 return (info->script() != undefined) &&
570 (reinterpret_cast<Script*>(info->script())->source() != undefined); 575 (reinterpret_cast<Script*>(info->script())->source() != undefined);
571 } 576 }
572 577
573 578
574 inline static bool IsCompiled(JSFunction* function) { 579 inline static bool IsCompiled(JSFunction* function) {
575 return function->unchecked_code() != 580 return function->unchecked_code() !=
576 function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile); 581 function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(object); 698 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(object);
694 699
695 if (shared->IsInobjectSlackTrackingInProgress()) shared->DetachInitialMap(); 700 if (shared->IsInobjectSlackTrackingInProgress()) shared->DetachInitialMap();
696 701
697 FixedBodyVisitor<StaticMarkingVisitor, 702 FixedBodyVisitor<StaticMarkingVisitor,
698 SharedFunctionInfo::BodyDescriptor, 703 SharedFunctionInfo::BodyDescriptor,
699 void>::Visit(map, object); 704 void>::Visit(map, object);
700 } 705 }
701 706
702 707
708 static void UpdateRegExpCodeAgeAndFlush(Heap* heap,
709 JSRegExp* re,
710 bool is_ascii) {
711 // Make sure that the fixed array is in fact initialized on the RegExp.
712 // We could potentially trigger a GC when initializing the RegExp.
713 if (SafeMap(re->data())->instance_type() != FIXED_ARRAY_TYPE) return;
714
715 // Make sure this is a RegExp that actually contains code.
716 if (re->TypeTagUnchecked() != JSRegExp::IRREGEXP) return;
717
718 Object* code = re->DataAtUnchecked(JSRegExp::code_index(is_ascii));
719 if (!code->IsSmi() && SafeMap(code)->instance_type() == CODE_TYPE ) {
720 // Save a copy that can be reinstated if we need the code again.
721 re->SetDataAtUnchecked(JSRegExp::saved_code_index(is_ascii),
722 code,
723 heap);
724 re->SetDataAtUnchecked(JSRegExp::code_index(is_ascii),
725 Smi::FromInt(heap->sweep_generation() % 256),
726 heap);
727 } else if (code->IsSmi()) {
728 int value = Smi::cast(code)->value();
729 // The regexp has not been compiled yet.
730 if (value == JSRegExp::kUninitializedValue) return;
731
732 // Check if we should flush now.
733 if (value == (heap->sweep_generation() - kRegExpCodeThreshold) % 256) {
Erik Corry 2011/06/30 18:48:25 If the lhs is negative then according to the stand
Rico 2011/07/01 05:58:09 Done.
734 re->SetDataAtUnchecked(JSRegExp::code_index(is_ascii),
735 Smi::FromInt(JSRegExp::kUninitializedValue),
736 heap);
737 re->SetDataAtUnchecked(JSRegExp::saved_code_index(is_ascii),
738 Smi::FromInt(JSRegExp::kUninitializedValue),
739 heap);
740 }
741 }
742 }
743
744
745 // Works by setting the current sweep_generation (as a smi) in the
746 // code object place in the data array of the RegExp and keeps a copy
747 // around that can be reinstated if we reuse the RegExp before flushing.
748 // If we did not use the code for kRegExpCodeThreshold mark sweep GCs
749 // we flush the code.
750 static void VisitRegExpAndFlushCode(Map* map, HeapObject* object) {
751 Heap* heap = map->heap();
752 MarkCompactCollector* collector = heap->mark_compact_collector();
753 if (!collector->is_code_flushing_enabled()) {
754 VisitJSRegExpFields(map, object);
755 return;
756 }
757 JSRegExp* re = reinterpret_cast<JSRegExp*>(object);
758 // Flush code or set age on both ascii and two byte code.
759 UpdateRegExpCodeAgeAndFlush(heap, re, true);
760 UpdateRegExpCodeAgeAndFlush(heap, re, false);
761 // Visit the fields of the RegExp, including the updated FixedArray.
762 VisitJSRegExpFields(map, object);
763 }
764
765
703 static void VisitSharedFunctionInfoAndFlushCode(Map* map, 766 static void VisitSharedFunctionInfoAndFlushCode(Map* map,
704 HeapObject* object) { 767 HeapObject* object) {
705 MarkCompactCollector* collector = map->heap()->mark_compact_collector(); 768 MarkCompactCollector* collector = map->heap()->mark_compact_collector();
706 if (!collector->is_code_flushing_enabled()) { 769 if (!collector->is_code_flushing_enabled()) {
707 VisitSharedFunctionInfoGeneric(map, object); 770 VisitSharedFunctionInfoGeneric(map, object);
708 return; 771 return;
709 } 772 }
710 VisitSharedFunctionInfoAndFlushCodeGeneric(map, object, false); 773 VisitSharedFunctionInfoAndFlushCodeGeneric(map, object, false);
711 } 774 }
712 775
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 } 886 }
824 887
825 VisitPointers(heap, 888 VisitPointers(heap,
826 SLOT_ADDR(object, 889 SLOT_ADDR(object,
827 JSFunction::kCodeEntryOffset + kPointerSize), 890 JSFunction::kCodeEntryOffset + kPointerSize),
828 SLOT_ADDR(object, JSFunction::kNonWeakFieldsEndOffset)); 891 SLOT_ADDR(object, JSFunction::kNonWeakFieldsEndOffset));
829 892
830 // Don't visit the next function list field as it is a weak reference. 893 // Don't visit the next function list field as it is a weak reference.
831 } 894 }
832 895
896 static inline void VisitJSRegExpFields(Map* map,
897 HeapObject* object) {
898 int last_property_offset =
899 JSRegExp::kSize + kPointerSize * map->inobject_properties();
900 VisitPointers(map->heap(),
901 SLOT_ADDR(object, JSRegExp::kPropertiesOffset),
902 SLOT_ADDR(object, last_property_offset));
903 }
904
833 905
834 static void VisitSharedFunctionInfoFields(Heap* heap, 906 static void VisitSharedFunctionInfoFields(Heap* heap,
835 HeapObject* object, 907 HeapObject* object,
836 bool flush_code_candidate) { 908 bool flush_code_candidate) {
837 VisitPointer(heap, SLOT_ADDR(object, SharedFunctionInfo::kNameOffset)); 909 VisitPointer(heap, SLOT_ADDR(object, SharedFunctionInfo::kNameOffset));
838 910
839 if (!flush_code_candidate) { 911 if (!flush_code_candidate) {
840 VisitPointer(heap, SLOT_ADDR(object, SharedFunctionInfo::kCodeOffset)); 912 VisitPointer(heap, SLOT_ADDR(object, SharedFunctionInfo::kCodeOffset));
841 } 913 }
842 914
(...skipping 2294 matching lines...) Expand 10 before | Expand all | Expand 10 after
3137 } 3209 }
3138 3210
3139 3211
3140 void MarkCompactCollector::Initialize() { 3212 void MarkCompactCollector::Initialize() {
3141 StaticPointersToNewGenUpdatingVisitor::Initialize(); 3213 StaticPointersToNewGenUpdatingVisitor::Initialize();
3142 StaticMarkingVisitor::Initialize(); 3214 StaticMarkingVisitor::Initialize();
3143 } 3215 }
3144 3216
3145 3217
3146 } } // namespace v8::internal 3218 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698