Reviewers: Søren Gjesse,
Description:
Limit the generation of regexp code with large inlined constants.
Please review this at http://codereview.chromium.org/6997015/
SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/
Affected files:
M src/arm/regexp-macro-assembler-arm.h
M src/arm/regexp-macro-assembler-arm.cc
M src/heap.h
M src/ia32/regexp-macro-assembler-ia32.h
M src/ia32/regexp-macro-assembler-ia32.cc
M src/jsregexp.h
M src/jsregexp.cc
M src/mips/regexp-macro-assembler-mips.h
M src/mips/regexp-macro-assembler-mips.cc
M src/regexp-macro-assembler-irregexp.h
M src/regexp-macro-assembler-irregexp.cc
M src/regexp-macro-assembler-tracer.h
M src/regexp-macro-assembler-tracer.cc
M src/regexp-macro-assembler.h
M src/regexp-macro-assembler.cc
M src/x64/regexp-macro-assembler-x64.h
M src/x64/regexp-macro-assembler-x64.cc
Index: src/arm/regexp-macro-assembler-arm.cc
===================================================================
--- src/arm/regexp-macro-assembler-arm.cc (revision 7820)
+++ src/arm/regexp-macro-assembler-arm.cc (working copy)
@@ -605,7 +605,7 @@
}
-Handle<Object> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
+Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source)
{
// Finalize code - write the entry point code now we know how many
// registers we need.
@@ -813,7 +813,7 @@
Code::ComputeFlags(Code::REGEXP),
masm_->CodeObject());
PROFILE(Isolate::Current(), RegExpCodeCreateEvent(*code, *source));
- return Handle<Object>::cast(code);
+ return Handle<HeapObject>::cast(code);
}
Index: src/arm/regexp-macro-assembler-arm.h
===================================================================
--- src/arm/regexp-macro-assembler-arm.h (revision 7820)
+++ src/arm/regexp-macro-assembler-arm.h (working copy)
@@ -82,7 +82,7 @@
virtual bool CheckSpecialCharacterClass(uc16 type,
Label* on_no_match);
virtual void Fail();
- virtual Handle<Object> GetCode(Handle<String> source);
+ virtual Handle<HeapObject> GetCode(Handle<String> source);
virtual void GoTo(Label* label);
virtual void IfRegisterGE(int reg, int comparand, Label* if_ge);
virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
Index: src/heap.h
===================================================================
--- src/heap.h (revision 7820)
+++ src/heap.h (working copy)
@@ -1214,6 +1214,11 @@
GCTracer* tracer() { return tracer_; }
+ double total_regexp_code_generated() { return
total_regexp_code_generated_; }
+ void IncreaseTotalRegexpCodeGenerated(int size) {
+ total_regexp_code_generated_ += size;
+ }
+
// Returns maximum GC pause.
int get_max_gc_pause() { return max_gc_pause_; }
@@ -1497,6 +1502,9 @@
SharedFunctionInfo* shared,
Object* prototype);
+ // Total RegExp code ever generated
+ double total_regexp_code_generated_;
+
GCTracer* tracer_;
Index: src/ia32/regexp-macro-assembler-ia32.cc
===================================================================
--- src/ia32/regexp-macro-assembler-ia32.cc (revision 7820)
+++ src/ia32/regexp-macro-assembler-ia32.cc (working copy)
@@ -662,7 +662,7 @@
}
-Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
+Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String>
source) {
// Finalize code - write the entry point code now we know how many
// registers we need.
@@ -879,7 +879,7 @@
Code::ComputeFlags(Code::REGEXP),
masm_->CodeObject());
PROFILE(masm_->isolate(), RegExpCodeCreateEvent(*code, *source));
- return Handle<Object>::cast(code);
+ return Handle<HeapObject>::cast(code);
}
Index: src/ia32/regexp-macro-assembler-ia32.h
===================================================================
--- src/ia32/regexp-macro-assembler-ia32.h (revision 7820)
+++ src/ia32/regexp-macro-assembler-ia32.h (working copy)
@@ -80,7 +80,7 @@
virtual void CheckPosition(int cp_offset, Label* on_outside_input);
virtual bool CheckSpecialCharacterClass(uc16 type, Label* on_no_match);
virtual void Fail();
- virtual Handle<Object> GetCode(Handle<String> source);
+ virtual Handle<HeapObject> GetCode(Handle<String> source);
virtual void GoTo(Label* label);
virtual void IfRegisterGE(int reg, int comparand, Label* if_ge);
virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
Index: src/jsregexp.cc
===================================================================
--- src/jsregexp.cc (revision 7820)
+++ src/jsregexp.cc (working copy)
@@ -858,12 +858,25 @@
RegExpNode* start,
int capture_count,
Handle<String> pattern) {
+ Heap* heap = pattern->GetHeap();
+
+ bool use_slow_safe_regexp_compiler = false;
+ if (heap->total_regexp_code_generated() >
+ RegExpImpl::kRegWxpCompiledLimit &&
+ heap->isolate()->memory_allocator()->SizeExecutable() >
+ RegExpImpl::kRegExpExecutableMemoryLimit) {
+ use_slow_safe_regexp_compiler = true;
+ }
+
+ macro_assembler->set_slow_safe(use_slow_safe_regexp_compiler);
+
#ifdef DEBUG
if (FLAG_trace_regexp_assembler)
macro_assembler_ = new RegExpMacroAssemblerTracer(macro_assembler);
else
#endif
macro_assembler_ = macro_assembler;
+
List <RegExpNode*> work_list(0);
work_list_ = &work_list;
Label fail;
@@ -877,7 +890,8 @@
}
if (reg_exp_too_big_) return IrregexpRegExpTooBig();
- Handle<Object> code = macro_assembler_->GetCode(pattern);
+ Handle<HeapObject> code = macro_assembler_->GetCode(pattern);
+ heap->IncreaseTotalRegexpCodeGenerated(code->Size());
work_list_ = NULL;
#ifdef DEBUG
if (FLAG_print_code) {
Index: src/jsregexp.h
===================================================================
--- src/jsregexp.h (revision 7820)
+++ src/jsregexp.h (working copy)
@@ -176,6 +176,14 @@
static ByteArray* IrregexpByteCode(FixedArray* re, bool is_ascii);
static Code* IrregexpNativeCode(FixedArray* re, bool is_ascii);
+ // Limit the space regexps take up on the heap. In order to limit this
we
+ // would like to keep track of the amount of regexp code on the heap.
This
+ // is not tracked, however. As a conservative approximation we track the
+ // total regexp code compiled including code that has subsequently been
freed
+ // and the total executable memory at any point.
+ static const int kRegExpExecutableMemoryLimit = 16 * MB;
+ static const int kRegWxpCompiledLimit = 1 * MB;
+
private:
static String* last_ascii_string_;
static String* two_byte_cached_string_;
Index: src/mips/regexp-macro-assembler-mips.cc
===================================================================
--- src/mips/regexp-macro-assembler-mips.cc (revision 7820)
+++ src/mips/regexp-macro-assembler-mips.cc (working copy)
@@ -259,9 +259,9 @@
}
-Handle<Object> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
+Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String>
source) {
UNIMPLEMENTED_MIPS();
- return Handle<Object>::null();
+ return Handle<HeapObject>::null();
}
Index: src/mips/regexp-macro-assembler-mips.h
===================================================================
--- src/mips/regexp-macro-assembler-mips.h (revision 7820)
+++ src/mips/regexp-macro-assembler-mips.h (working copy)
@@ -81,7 +81,7 @@
virtual bool CheckSpecialCharacterClass(uc16 type,
Label* on_no_match);
virtual void Fail();
- virtual Handle<Object> GetCode(Handle<String> source);
+ virtual Handle<HeapObject> GetCode(Handle<String> source);
virtual void GoTo(Label* label);
virtual void IfRegisterGE(int reg, int comparand, Label* if_ge);
virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
Index: src/regexp-macro-assembler-irregexp.cc
===================================================================
--- src/regexp-macro-assembler-irregexp.cc (revision 7820)
+++ src/regexp-macro-assembler-irregexp.cc (working copy)
@@ -435,7 +435,8 @@
}
-Handle<Object> RegExpMacroAssemblerIrregexp::GetCode(Handle<String>
source) {
+Handle<HeapObject> RegExpMacroAssemblerIrregexp::GetCode(
+ Handle<String> source) {
Bind(&backtrack_);
Emit(BC_POP_BT, 0);
Handle<ByteArray> array = FACTORY->NewByteArray(length());
Index: src/regexp-macro-assembler-irregexp.h
===================================================================
--- src/regexp-macro-assembler-irregexp.h (revision 7820)
+++ src/regexp-macro-assembler-irregexp.h (working copy)
@@ -106,7 +106,7 @@
virtual void IfRegisterEqPos(int register_index, Label* if_eq);
virtual IrregexpImplementation Implementation();
- virtual Handle<Object> GetCode(Handle<String> source);
+ virtual Handle<HeapObject> GetCode(Handle<String> source);
private:
void Expand();
// Code and bitmap emission.
Index: src/regexp-macro-assembler-tracer.cc
===================================================================
--- src/regexp-macro-assembler-tracer.cc (revision 7820)
+++ src/regexp-macro-assembler-tracer.cc (working copy)
@@ -365,7 +365,7 @@
}
-Handle<Object> RegExpMacroAssemblerTracer::GetCode(Handle<String> source) {
+Handle<HeapObject> RegExpMacroAssemblerTracer::GetCode(Handle<String>
source) {
PrintF(" GetCode(%s);\n", *(source->ToCString()));
return assembler_->GetCode(source);
}
Index: src/regexp-macro-assembler-tracer.h
===================================================================
--- src/regexp-macro-assembler-tracer.h (revision 7820)
+++ src/regexp-macro-assembler-tracer.h (working copy)
@@ -71,7 +71,7 @@
virtual bool CheckSpecialCharacterClass(uc16 type,
Label* on_no_match);
virtual void Fail();
- virtual Handle<Object> GetCode(Handle<String> source);
+ virtual Handle<HeapObject> GetCode(Handle<String> source);
virtual void GoTo(Label* label);
virtual void IfRegisterGE(int reg, int comparand, Label* if_ge);
virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
Index: src/regexp-macro-assembler.cc
===================================================================
--- src/regexp-macro-assembler.cc (revision 7820)
+++ src/regexp-macro-assembler.cc (working copy)
@@ -35,7 +35,7 @@
namespace v8 {
namespace internal {
-RegExpMacroAssembler::RegExpMacroAssembler() {
+RegExpMacroAssembler::RegExpMacroAssembler() : slow_safe_compiler_(false) {
}
@@ -54,7 +54,8 @@
#ifndef V8_INTERPRETED_REGEXP // Avoid unused code, e.g., on ARM.
-NativeRegExpMacroAssembler::NativeRegExpMacroAssembler() {
+NativeRegExpMacroAssembler::NativeRegExpMacroAssembler()
+ : RegExpMacroAssembler() {
}
@@ -64,7 +65,7 @@
bool NativeRegExpMacroAssembler::CanReadUnaligned() {
#ifdef V8_TARGET_CAN_READ_UNALIGNED
- return true;
+ return !slow_safe();
#else
return false;
#endif
Index: src/regexp-macro-assembler.h
===================================================================
--- src/regexp-macro-assembler.h (revision 7820)
+++ src/regexp-macro-assembler.h (working copy)
@@ -130,7 +130,7 @@
return false;
}
virtual void Fail() = 0;
- virtual Handle<Object> GetCode(Handle<String> source) = 0;
+ virtual Handle<HeapObject> GetCode(Handle<String> source) = 0;
virtual void GoTo(Label* label) = 0;
// Check whether a register is >= a given constant and go to a label if
it
// is. Backtracks instead if the label is NULL.
@@ -162,6 +162,13 @@
virtual void WriteCurrentPositionToRegister(int reg, int cp_offset) = 0;
virtual void ClearRegisters(int reg_from, int reg_to) = 0;
virtual void WriteStackPointerToRegister(int reg) = 0;
+
+ // Controls the generation of large inlined constants in the code.
+ void set_slow_safe(bool ssc) { slow_safe_compiler_ = ssc; }
+ bool slow_safe() { return slow_safe_compiler_; }
+
+ private:
+ bool slow_safe_compiler_;
};
Index: src/x64/regexp-macro-assembler-x64.cc
===================================================================
--- src/x64/regexp-macro-assembler-x64.cc (revision 7820)
+++ src/x64/regexp-macro-assembler-x64.cc (working copy)
@@ -703,7 +703,7 @@
}
-Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
+Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source)
{
// Finalize code - write the entry point code now we know how many
// registers we need.
// Entry code:
@@ -972,7 +972,7 @@
code_desc, Code::ComputeFlags(Code::REGEXP),
masm_.CodeObject());
PROFILE(isolate, RegExpCodeCreateEvent(*code, *source));
- return Handle<Object>::cast(code);
+ return Handle<HeapObject>::cast(code);
}
Index: src/x64/regexp-macro-assembler-x64.h
===================================================================
--- src/x64/regexp-macro-assembler-x64.h (revision 7820)
+++ src/x64/regexp-macro-assembler-x64.h (working copy)
@@ -75,7 +75,7 @@
virtual bool CheckSpecialCharacterClass(uc16 type,
Label* on_no_match);
virtual void Fail();
- virtual Handle<Object> GetCode(Handle<String> source);
+ virtual Handle<HeapObject> GetCode(Handle<String> source);
virtual void GoTo(Label* label);
virtual void IfRegisterGE(int reg, int comparand, Label* if_ge);
virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev