Commit 291781ed authored by erik.corry@gmail.com's avatar erik.corry@gmail.com

Limit the generation of regexp code with large inlined constants.

Review URL: http://codereview.chromium.org/6997015

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7845 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 944a3884
......@@ -605,7 +605,7 @@ void RegExpMacroAssemblerARM::Fail() {
}
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 @@ Handle<Object> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
Code::ComputeFlags(Code::REGEXP),
masm_->CodeObject());
PROFILE(Isolate::Current(), RegExpCodeCreateEvent(*code, *source));
return Handle<Object>::cast(code);
return Handle<HeapObject>::cast(code);
}
......
......@@ -82,7 +82,7 @@ class RegExpMacroAssemblerARM: public NativeRegExpMacroAssembler {
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);
......
......@@ -1214,6 +1214,11 @@ class Heap {
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 @@ class Heap {
SharedFunctionInfo* shared,
Object* prototype);
// Total RegExp code ever generated
double total_regexp_code_generated_;
GCTracer* tracer_;
......
......@@ -662,7 +662,7 @@ void RegExpMacroAssemblerIA32::Fail() {
}
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 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
Code::ComputeFlags(Code::REGEXP),
masm_->CodeObject());
PROFILE(masm_->isolate(), RegExpCodeCreateEvent(*code, *source));
return Handle<Object>::cast(code);
return Handle<HeapObject>::cast(code);
}
......
......@@ -80,7 +80,7 @@ class RegExpMacroAssemblerIA32: public NativeRegExpMacroAssembler {
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);
......
......@@ -858,12 +858,25 @@ RegExpEngine::CompilationResult RegExpCompiler::Assemble(
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 @@ RegExpEngine::CompilationResult RegExpCompiler::Assemble(
}
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) {
......
......@@ -176,6 +176,14 @@ class RegExpImpl {
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_;
......
......@@ -259,9 +259,9 @@ void RegExpMacroAssemblerMIPS::Fail() {
}
Handle<Object> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
UNIMPLEMENTED_MIPS();
return Handle<Object>::null();
return Handle<HeapObject>::null();
}
......
......@@ -81,7 +81,7 @@ class RegExpMacroAssemblerMIPS: public NativeRegExpMacroAssembler {
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);
......
......@@ -435,7 +435,8 @@ void RegExpMacroAssemblerIrregexp::IfRegisterEqPos(int register_index,
}
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());
......
......@@ -106,7 +106,7 @@ class RegExpMacroAssemblerIrregexp: public RegExpMacroAssembler {
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.
......
......@@ -365,7 +365,7 @@ RegExpMacroAssembler::IrregexpImplementation
}
Handle<Object> RegExpMacroAssemblerTracer::GetCode(Handle<String> source) {
Handle<HeapObject> RegExpMacroAssemblerTracer::GetCode(Handle<String> source) {
PrintF(" GetCode(%s);\n", *(source->ToCString()));
return assembler_->GetCode(source);
}
......
......@@ -71,7 +71,7 @@ class RegExpMacroAssemblerTracer: public RegExpMacroAssembler {
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);
......
......@@ -35,7 +35,7 @@
namespace v8 {
namespace internal {
RegExpMacroAssembler::RegExpMacroAssembler() {
RegExpMacroAssembler::RegExpMacroAssembler() : slow_safe_compiler_(false) {
}
......@@ -54,7 +54,8 @@ bool RegExpMacroAssembler::CanReadUnaligned() {
#ifndef V8_INTERPRETED_REGEXP // Avoid unused code, e.g., on ARM.
NativeRegExpMacroAssembler::NativeRegExpMacroAssembler() {
NativeRegExpMacroAssembler::NativeRegExpMacroAssembler()
: RegExpMacroAssembler() {
}
......@@ -64,7 +65,7 @@ NativeRegExpMacroAssembler::~NativeRegExpMacroAssembler() {
bool NativeRegExpMacroAssembler::CanReadUnaligned() {
#ifdef V8_TARGET_CAN_READ_UNALIGNED
return true;
return !slow_safe();
#else
return false;
#endif
......
......@@ -130,7 +130,7 @@ class RegExpMacroAssembler {
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 @@ class RegExpMacroAssembler {
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_;
};
......
......@@ -703,7 +703,7 @@ void RegExpMacroAssemblerX64::Fail() {
}
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 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
code_desc, Code::ComputeFlags(Code::REGEXP),
masm_.CodeObject());
PROFILE(isolate, RegExpCodeCreateEvent(*code, *source));
return Handle<Object>::cast(code);
return Handle<HeapObject>::cast(code);
}
......
......@@ -75,7 +75,7 @@ class RegExpMacroAssemblerX64: public NativeRegExpMacroAssembler {
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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment