Author: [EMAIL PROTECTED]
Date: Thu Oct 30 04:12:08 2008
New Revision: 650

Modified:
    branches/bleeding_edge/src/builtins.cc
    branches/bleeding_edge/src/factory.cc
    branches/bleeding_edge/src/jsregexp.cc

Log:
Fix 3 places where we were doing retry after GC without using the macros  
that
were defined for that purpose.
Review URL: http://codereview.chromium.org/8734

Modified: branches/bleeding_edge/src/builtins.cc
==============================================================================
--- branches/bleeding_edge/src/builtins.cc      (original)
+++ branches/bleeding_edge/src/builtins.cc      Thu Oct 30 04:12:08 2008
@@ -642,13 +642,12 @@
        CodeDesc desc;
        masm.GetCode(&desc);
        Code::Flags flags =  functions[i].flags;
-      Object* code = Heap::CreateCode(desc, NULL, flags);
-      if (code->IsFailure()) {
-        if (code->IsRetryAfterGC()) {
-          CHECK(Heap::CollectGarbage(Failure::cast(code)->requested(),
-                                      
Failure::cast(code)->allocation_space()));
-          code = Heap::CreateCode(desc, NULL, flags);
-        }
+      Object* code;
+      {
+        // During startup it's OK to always allocate and defer GC to later.
+        // This simplifies things because we don't need to retry.
+        AlwaysAllocateScope __scope__;
+        code = Heap::CreateCode(desc, NULL, flags);
          if (code->IsFailure()) {
            v8::internal::V8::FatalProcessOutOfMemory("CreateCode");
          }

Modified: branches/bleeding_edge/src/factory.cc
==============================================================================
--- branches/bleeding_edge/src/factory.cc       (original)
+++ branches/bleeding_edge/src/factory.cc       Thu Oct 30 04:12:08 2008
@@ -452,6 +452,7 @@
    return function;
  }

+
  Handle<Code> Factory::NewCode(const CodeDesc& desc, ScopeInfo<>* sinfo,
                                Code::Flags flags) {
    CALL_HEAP_FUNCTION(Heap::CreateCode(desc, sinfo, flags), Code);
@@ -463,41 +464,25 @@
  }


-#define CALL_GC(RETRY)                                                      
\
-  do {                                                                      
\
-    if (!Heap::CollectGarbage(Failure::cast(RETRY)->requested(),            
\
-                              Failure::cast(RETRY)->allocation_space())) {  
\
-      /* TODO(1181417): Fix this. */                                        
\
-      V8::FatalProcessOutOfMemory("Factory CALL_GC");                       
\
-    }                                                                       
\
-  } while (false)
+static inline Object* DoCopyInsert(DescriptorArray* array,
+                                   String* key,
+                                   Object* value,
+                                   PropertyAttributes attributes) {
+  CallbacksDescriptor desc(key, value, attributes);
+  Object* obj = array->CopyInsert(&desc, REMOVE_TRANSITIONS);
+  return obj;
+}


-// Allocate the new array. We cannot use the CALL_HEAP_FUNCTION macro here,
-// because the stack-allocated CallbacksDescriptor instance is not GC safe.
+// Allocate the new array.
  Handle<DescriptorArray> Factory::CopyAppendProxyDescriptor(
      Handle<DescriptorArray> array,
      Handle<String> key,
      Handle<Object> value,
      PropertyAttributes attributes) {
-  GC_GREEDY_CHECK();
-  CallbacksDescriptor desc(*key, *value, attributes);
-  Object* obj = array->CopyInsert(&desc, REMOVE_TRANSITIONS);
-  if (obj->IsFailure()) {
-    if (obj->IsRetryAfterGC()) {
-      CALL_GC(obj);
-      CallbacksDescriptor desc(*key, *value, attributes);
-      obj = array->CopyInsert(&desc, REMOVE_TRANSITIONS);
-    }
-    if (obj->IsFailure()) {
-      // TODO(1181417): Fix this.
-      V8::FatalProcessOutOfMemory("CopyAppendProxyDescriptor");
-    }
-  }
-  return Handle<DescriptorArray>(DescriptorArray::cast(obj));
+  CALL_HEAP_FUNCTION(DoCopyInsert(*array, *key, *value, attributes),
+                     DescriptorArray);
  }
-
-#undef CALL_GC


  Handle<String> Factory::SymbolFromString(Handle<String> value) {

Modified: branches/bleeding_edge/src/jsregexp.cc
==============================================================================
--- branches/bleeding_edge/src/jsregexp.cc      (original)
+++ branches/bleeding_edge/src/jsregexp.cc      Thu Oct 30 04:12:08 2008
@@ -307,15 +307,55 @@
  }


-Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re,
-                                       Handle<String> pattern,
-                                       JSRegExp::Flags flags) {
+static inline Object* DoCompile(String* pattern,
+                                JSRegExp::Flags flags,
+                                unsigned* number_of_captures,
+                                const char** error_message,
+                                JscreRegExp** code) {
    JSRegExpIgnoreCaseOption case_option = flags.is_ignore_case()
      ? JSRegExpIgnoreCase
      : JSRegExpDoNotIgnoreCase;
    JSRegExpMultilineOption multiline_option = flags.is_multiline()
      ? JSRegExpMultiline
      : JSRegExpSingleLine;
+  *error_message = NULL;
+  malloc_failure = Failure::Exception();
+  *code = jsRegExpCompile(pattern->GetTwoByteData(),
+                          pattern->length(),
+                          case_option,
+                          multiline_option,
+                          number_of_captures,
+                          error_message,
+                          &JSREMalloc,
+                          &JSREFree);
+  if (code == NULL && (malloc_failure->IsRetryAfterGC() ||
+                       malloc_failure->IsOutOfMemoryFailure())) {
+    return malloc_failure;
+  } else {
+    // It doesn't matter which object we return here, we just need to  
return
+    // a non-failure to indicate to the GC-retry code that there was no
+    // allocation failure.
+    return pattern;
+  }
+}
+
+
+void CompileWithRetryAfterGC(Handle<String> pattern,
+                             JSRegExp::Flags flags,
+                             unsigned* number_of_captures,
+                             const char** error_message,
+                             JscreRegExp** code) {
+  CALL_HEAP_FUNCTION_VOID(DoCompile(*pattern,
+                                    flags,
+                                    number_of_captures,
+                                    error_message,
+                                    code));
+}
+
+
+Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re,
+                                       Handle<String> pattern,
+                                       JSRegExp::Flags flags) {

    Handle<String> two_byte_pattern = StringToTwoByte(pattern);

@@ -325,52 +365,33 @@
    JscreRegExp* code = NULL;
    FlattenString(pattern);

-  bool first_time = true;
+  CompileWithRetryAfterGC(two_byte_pattern,
+                          flags,
+                          &number_of_captures,
+                          &error_message,
+                          &code);
+
+  if (code == NULL) {
+    // Throw an exception.
+    Handle<JSArray> array = Factory::NewJSArray(2);
+    SetElement(array, 0, pattern);
+    SetElement(array, 1, Factory::NewStringFromUtf8(CStrVector(
+        (error_message == NULL) ? "Unknown regexp error" :  
error_message)));
+    Handle<Object> regexp_err =
+        Factory::NewSyntaxError("malformed_regexp", array);
+    return Handle<Object>(Top::Throw(*regexp_err));
+  }

-  while (true) {
-    malloc_failure = Failure::Exception();
-    code = jsRegExpCompile(two_byte_pattern->GetTwoByteData(),
-                           pattern->length(), case_option,
-                           multiline_option, &number_of_captures,
-                           &error_message, &JSREMalloc, &JSREFree);
-    if (code == NULL) {
-      if (first_time && malloc_failure->IsRetryAfterGC()) {
-        first_time = false;
-        if (!Heap::CollectGarbage(malloc_failure->requested(),
-                                  malloc_failure->allocation_space())) {
-          // TODO(1181417): Fix this.
-          V8::FatalProcessOutOfMemory("RegExpImpl::JsreCompile");
-        }
-        continue;
-      }
-      if (malloc_failure->IsRetryAfterGC() ||
-          malloc_failure->IsOutOfMemoryFailure()) {
-        // TODO(1181417): Fix this.
-        V8::FatalProcessOutOfMemory("RegExpImpl::JsreCompile");
-      } else {
-        // Throw an exception.
-        Handle<JSArray> array = Factory::NewJSArray(2);
-        SetElement(array, 0, pattern);
-        SetElement(array, 1, Factory::NewStringFromUtf8(CStrVector(
-            (error_message == NULL) ? "Unknown regexp error" :  
error_message)));
-        Handle<Object> regexp_err =
-            Factory::NewSyntaxError("malformed_regexp", array);
-        return Handle<Object>(Top::Throw(*regexp_err));
-      }
-    }
-
-    ASSERT(code != NULL);
-    // Convert the return address to a ByteArray pointer.
-    Handle<ByteArray> internal(
-        ByteArray::FromDataStartAddress(reinterpret_cast<Address>(code)));
-
-    Handle<FixedArray> value = Factory::NewFixedArray(2);
-    value->set(CAPTURE_INDEX, Smi::FromInt(number_of_captures));
-    value->set(INTERNAL_INDEX, *internal);
-    Factory::SetRegExpData(re, JSRegExp::JSCRE, pattern, flags, value);
+  // Convert the return address to a ByteArray pointer.
+  Handle<ByteArray> internal(
+      ByteArray::FromDataStartAddress(reinterpret_cast<Address>(code)));
+
+  Handle<FixedArray> value = Factory::NewFixedArray(2);
+  value->set(CAPTURE_INDEX, Smi::FromInt(number_of_captures));
+  value->set(INTERNAL_INDEX, *internal);
+  Factory::SetRegExpData(re, JSRegExp::JSCRE, pattern, flags, value);

-    return re;
-  }
+  return re;
  }



--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to