Chromium Code Reviews| Index: src/mark-compact.cc |
| =================================================================== |
| --- src/mark-compact.cc (revision 8431) |
| +++ src/mark-compact.cc (working copy) |
| @@ -424,6 +424,9 @@ |
| table_.Register(kVisitJSFunction, |
| &VisitJSFunctionAndFlushCode); |
| + table_.Register(kVisitJSRegExp, |
| + &VisitRegExpAndFlushCode); |
| + |
| table_.Register(kVisitPropertyCell, |
| &FixedBodyVisitor<StaticMarkingVisitor, |
| JSGlobalPropertyCell::BodyDescriptor, |
| @@ -564,6 +567,8 @@ |
| // flushed. |
| static const int kCodeAgeThreshold = 5; |
| + static const int kRegExpCodeThreshold = 5; |
| + |
| inline static bool HasSourceCode(Heap* heap, SharedFunctionInfo* info) { |
| Object* undefined = heap->raw_unchecked_undefined_value(); |
| return (info->script() != undefined) && |
| @@ -700,6 +705,64 @@ |
| } |
| + static void UpdateRegExpCodeAgeAndFlush(Heap* heap, |
| + JSRegExp* re, |
| + bool is_ascii) { |
| + // Make sure that the fixed array is in fact initialized on the RegExp. |
| + // We could potentially trigger a GC when initializing the RegExp. |
| + if (SafeMap(re->data())->instance_type() != FIXED_ARRAY_TYPE) return; |
| + |
| + // Make sure this is a RegExp that actually contains code. |
| + if (re->TypeTagUnchecked() != JSRegExp::IRREGEXP) return; |
| + |
| + Object* code = re->DataAtUnchecked(JSRegExp::code_index(is_ascii)); |
| + if (!code->IsSmi() && SafeMap(code)->instance_type() == CODE_TYPE ) { |
| + // Save a copy that can be reinstated if we need the code again. |
| + re->SetDataAtUnchecked(JSRegExp::saved_code_index(is_ascii), |
| + code, |
| + heap); |
| + re->SetDataAtUnchecked(JSRegExp::code_index(is_ascii), |
| + Smi::FromInt(heap->sweep_generation() % 256), |
| + heap); |
| + } else if (code->IsSmi()) { |
| + int value = Smi::cast(code)->value(); |
| + // The regexp has not been compiled yet. |
| + if (value == JSRegExp::kUninitializedValue) return; |
| + |
| + // Check if we should flush now. |
| + 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.
|
| + re->SetDataAtUnchecked(JSRegExp::code_index(is_ascii), |
| + Smi::FromInt(JSRegExp::kUninitializedValue), |
| + heap); |
| + re->SetDataAtUnchecked(JSRegExp::saved_code_index(is_ascii), |
| + Smi::FromInt(JSRegExp::kUninitializedValue), |
| + heap); |
| + } |
| + } |
| + } |
| + |
| + |
| + // Works by setting the current sweep_generation (as a smi) in the |
| + // code object place in the data array of the RegExp and keeps a copy |
| + // around that can be reinstated if we reuse the RegExp before flushing. |
| + // If we did not use the code for kRegExpCodeThreshold mark sweep GCs |
| + // we flush the code. |
| + static void VisitRegExpAndFlushCode(Map* map, HeapObject* object) { |
| + Heap* heap = map->heap(); |
| + MarkCompactCollector* collector = heap->mark_compact_collector(); |
| + if (!collector->is_code_flushing_enabled()) { |
| + VisitJSRegExpFields(map, object); |
| + return; |
| + } |
| + JSRegExp* re = reinterpret_cast<JSRegExp*>(object); |
| + // Flush code or set age on both ascii and two byte code. |
| + UpdateRegExpCodeAgeAndFlush(heap, re, true); |
| + UpdateRegExpCodeAgeAndFlush(heap, re, false); |
| + // Visit the fields of the RegExp, including the updated FixedArray. |
| + VisitJSRegExpFields(map, object); |
| + } |
| + |
| + |
| static void VisitSharedFunctionInfoAndFlushCode(Map* map, |
| HeapObject* object) { |
| MarkCompactCollector* collector = map->heap()->mark_compact_collector(); |
| @@ -830,7 +893,16 @@ |
| // Don't visit the next function list field as it is a weak reference. |
| } |
| + static inline void VisitJSRegExpFields(Map* map, |
| + HeapObject* object) { |
| + int last_property_offset = |
| + JSRegExp::kSize + kPointerSize * map->inobject_properties(); |
| + VisitPointers(map->heap(), |
| + SLOT_ADDR(object, JSRegExp::kPropertiesOffset), |
| + SLOT_ADDR(object, last_property_offset)); |
| + } |
| + |
| static void VisitSharedFunctionInfoFields(Heap* heap, |
| HeapObject* object, |
| bool flush_code_candidate) { |