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

Reply via email to