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

Unified 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, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/jsregexp.cc ('k') | src/objects.h » ('j') | src/objects-debug.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mark-compact.cc
===================================================================
--- src/mark-compact.cc (revision 8501)
+++ 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,68 @@
}
+ 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);
+ // Set a number in the 0-255 range to guarantee no smi overflow.
+ re->SetDataAtUnchecked(JSRegExp::code_index(is_ascii),
+ Smi::FromInt(heap->sweep_generation() & 0xff),
+ heap);
+ } else if (code->IsSmi()) {
+ int value = Smi::cast(code)->value();
+ // The regexp has not been compiled yet or there was a compilation error.
+ if (value == JSRegExp::kUninitializedValue ||
+ value == JSRegExp::kCompilationErrorValue) {
+ return;
+ }
+
+ // Check if we should flush now.
+ if (value == ((heap->sweep_generation() - kRegExpCodeThreshold) & 0xff)) {
+ 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 +897,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) {
« no previous file with comments | « src/jsregexp.cc ('k') | src/objects.h » ('j') | src/objects-debug.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698