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 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@650 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
52b2a12684
commit
8a8a24870b
@ -642,13 +642,12 @@ void Builtins::Setup(bool create_heap_objects) {
|
||||
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()));
|
||||
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");
|
||||
}
|
||||
|
@ -452,6 +452,7 @@ Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
|
||||
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 @@ Handle<Code> Factory::CopyCode(Handle<Code> code) {
|
||||
}
|
||||
|
||||
|
||||
#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);
|
||||
CALL_HEAP_FUNCTION(DoCopyInsert(*array, *key, *value, attributes),
|
||||
DescriptorArray);
|
||||
}
|
||||
if (obj->IsFailure()) {
|
||||
// TODO(1181417): Fix this.
|
||||
V8::FatalProcessOutOfMemory("CopyAppendProxyDescriptor");
|
||||
}
|
||||
}
|
||||
return Handle<DescriptorArray>(DescriptorArray::cast(obj));
|
||||
}
|
||||
|
||||
#undef CALL_GC
|
||||
|
||||
|
||||
Handle<String> Factory::SymbolFromString(Handle<String> value) {
|
||||
|
@ -307,15 +307,55 @@ Handle<Object> RegExpImpl::AtomExecGlobal(Handle<JSRegExp> re,
|
||||
}
|
||||
|
||||
|
||||
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,29 +365,13 @@ Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re,
|
||||
JscreRegExp* code = NULL;
|
||||
FlattenString(pattern);
|
||||
|
||||
bool first_time = true;
|
||||
CompileWithRetryAfterGC(two_byte_pattern,
|
||||
flags,
|
||||
&number_of_captures,
|
||||
&error_message,
|
||||
&code);
|
||||
|
||||
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);
|
||||
@ -357,9 +381,7 @@ Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re,
|
||||
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)));
|
||||
@ -371,7 +393,6 @@ Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re,
|
||||
|
||||
return re;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Handle<Object> RegExpImpl::JsreExecOnce(Handle<JSRegExp> regexp,
|
||||
|
Loading…
Reference in New Issue
Block a user