true,
true);
+ { FrameScope scope(masm, StackFrame::MANUAL);
+ __ PrepareCallCFunction(0, r0);
+ __ CallCFunction(
+ ExternalReference::out_of_memory_function(masm->isolate()), 0, 0);
+ }
+
__ bind(&throw_termination_exception);
__ ThrowUncatchable(r0);
true,
true);
+ { FrameScope scope(masm, StackFrame::MANUAL);
+ __ CallCFunction(
+ ExternalReference::out_of_memory_function(masm->isolate()), 0);
+ }
+
// We didn't execute a return case, so the stack frame hasn't been updated
// (except for the return address slot). However, we don't need to initialize
// jssp because the throw method will immediately overwrite it when it
// unwinds the stack.
- if (__ emit_debug_code()) {
- __ Mov(jssp, kDebugZapValue);
- }
__ SetStackPointer(jssp);
// Throw exceptions.
}
+ExternalReference ExternalReference::out_of_memory_function(Isolate* isolate) {
+ return
+ ExternalReference(Redirect(isolate, FUNCTION_ADDR(Runtime::OutOfMemory)));
+}
+
+
ExternalReference ExternalReference::delete_handle_scope_extensions(
Isolate* isolate) {
return ExternalReference(Redirect(
Isolate* isolate);
static ExternalReference flush_icache_function(Isolate* isolate);
static ExternalReference perform_gc_function(Isolate* isolate);
+ static ExternalReference out_of_memory_function(Isolate* isolate);
static ExternalReference delete_handle_scope_extensions(Isolate* isolate);
static ExternalReference get_date_field_function(Isolate* isolate);
true,
true);
+ { FrameScope scope(masm, StackFrame::MANUAL);
+ __ PrepareCallCFunction(0, eax);
+ __ CallCFunction(
+ ExternalReference::out_of_memory_function(masm->isolate()), 0);
+ }
+
__ bind(&throw_termination_exception);
__ ThrowUncatchable(eax);
true,
true);
+ { FrameScope scope(masm, StackFrame::MANUAL);
+ __ PrepareCallCFunction(0, v0);
+ __ CallCFunction(
+ ExternalReference::out_of_memory_function(masm->isolate()), 0);
+ }
+
__ bind(&throw_termination_exception);
__ ThrowUncatchable(v0);
}
+void Runtime::OutOfMemory() {
+ Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true);
+ UNREACHABLE();
+}
+
} } // namespace v8::internal
// Helper functions used stubs.
static void PerformGC(Object* result, Isolate* isolate);
+ static void OutOfMemory();
// Used in runtime.cc and hydrogen's VisitArrayLiteral.
static Handle<Object> CreateArrayLiteralBoilerplate(
RUNTIME_ENTRY,
1,
"Runtime::PerformGC");
+ // Runtime entries
+ Add(ExternalReference::out_of_memory_function(isolate).address(),
+ RUNTIME_ENTRY,
+ 2,
+ "Runtime::OutOfMemory");
Add(ExternalReference::delete_handle_scope_extensions(isolate).address(),
RUNTIME_ENTRY,
4,
true,
true);
+ { FrameScope scope(masm, StackFrame::MANUAL);
+ __ PrepareCallCFunction(0);
+ __ CallCFunction(
+ ExternalReference::out_of_memory_function(masm->isolate()), 0);
+ }
+
__ bind(&throw_termination_exception);
__ ThrowUncatchable(rax);
g->Call(global, 1, args1);
heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
}
-#endif
+
+
+void OnFatalErrorExpectOOM(const char* location, const char* message) {
+ // Exit with 0 if the location matches our expectation.
+ exit(strcmp(location, "CALL_AND_RETRY_LAST"));
+}
+
+
+TEST(CEntryStubOOM) {
+ i::FLAG_allow_natives_syntax = true;
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ v8::V8::SetFatalErrorHandler(OnFatalErrorExpectOOM);
+
+ v8::Handle<v8::Value> result = CompileRun(
+ "%SetFlags('--gc-interval=1');"
+ "var a = [];"
+ "a.__proto__ = [];"
+ "a.unshift(1)");
+
+ CHECK(result->IsNumber());
+}
+
+#endif // DEBUG