From 8b8fb30e7f8915d0762402f0b6e5b16c820cab48 Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Mon, 24 Mar 2014 10:07:15 +0000 Subject: [PATCH] Reland "Remove Failure::OutOfMemory propagation and V8::IgnoreOutOfMemoryException." R=dcarney@chromium.org Review URL: https://codereview.chromium.org/209903003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20184 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 16 +------- src/api.cc | 16 -------- src/arm/code-stubs-arm.cc | 43 --------------------- src/arm64/code-stubs-arm64.cc | 45 ---------------------- src/bootstrapper.cc | 3 -- src/code-stubs.h | 1 - src/contexts.h | 7 ---- src/elements.cc | 2 +- src/execution.cc | 8 ---- src/heap-inl.h | 19 ++-------- src/heap.cc | 18 ++++----- src/ia32/code-stubs-ia32.cc | 41 -------------------- src/isolate.cc | 87 ++++++++++++++----------------------------- src/isolate.h | 23 +----------- src/mips/code-stubs-mips.cc | 42 --------------------- src/objects-inl.h | 16 -------- src/objects.cc | 2 +- src/objects.h | 5 --- src/runtime.cc | 4 +- src/x64/code-stubs-x64.cc | 42 --------------------- test/cctest/test-api.cc | 58 ++++++++++++----------------- test/cctest/test-strings.cc | 17 --------- 22 files changed, 70 insertions(+), 445 deletions(-) diff --git a/include/v8.h b/include/v8.h index 5e54267..ef98f77 100644 --- a/include/v8.h +++ b/include/v8.h @@ -4616,20 +4616,6 @@ class V8_EXPORT V8 { static void SetArrayBufferAllocator(ArrayBuffer::Allocator* allocator); /** - * Ignore out-of-memory exceptions. - * - * V8 running out of memory is treated as a fatal error by default. - * This means that the fatal error handler is called and that V8 is - * terminated. - * - * IgnoreOutOfMemoryException can be used to not treat an - * out-of-memory situation as a fatal error. This way, the contexts - * that did not cause the out of memory problem might be able to - * continue execution. - */ - static void IgnoreOutOfMemoryException(); - - /** * Check if V8 is dead and therefore unusable. This is the case after * fatal errors such as out-of-memory situations. */ @@ -5234,7 +5220,7 @@ class V8_EXPORT Context { void Exit(); /** Returns true if the context has experienced an out of memory situation. */ - bool HasOutOfMemoryException(); + bool HasOutOfMemoryException() { return false; } /** Returns an isolate associated with a current context. */ v8::Isolate* GetIsolate(); diff --git a/src/api.cc b/src/api.cc index 1c349b5..b1d133a 100644 --- a/src/api.cc +++ b/src/api.cc @@ -95,11 +95,6 @@ namespace v8 { (isolate)->handle_scope_implementer(); \ handle_scope_implementer->DecrementCallDepth(); \ if (has_pending_exception) { \ - if (handle_scope_implementer->CallDepthIsZero() && \ - (isolate)->is_out_of_memory()) { \ - if (!(isolate)->ignore_out_of_memory()) \ - i::V8::FatalProcessOutOfMemory(NULL); \ - } \ bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); \ (isolate)->OptionalRescheduleException(call_depth_is_zero); \ do_callback \ @@ -5261,12 +5256,6 @@ Handle v8::Context::GetSecurityToken() { } -bool Context::HasOutOfMemoryException() { - i::Handle env = Utils::OpenHandle(this); - return env->has_out_of_memory(); -} - - v8::Isolate* Context::GetIsolate() { i::Handle env = Utils::OpenHandle(this); return reinterpret_cast(env->GetIsolate()); @@ -6225,11 +6214,6 @@ Local v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) { } -void V8::IgnoreOutOfMemoryException() { - EnterIsolateIfNeeded()->set_ignore_out_of_memory(true); -} - - bool V8::AddMessageListener(MessageCallback that, Handle data) { i::Isolate* isolate = i::Isolate::Current(); EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()"); diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index 5609cd0..b3df94e 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -1501,22 +1501,9 @@ void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { } -static void JumpIfOOM(MacroAssembler* masm, - Register value, - Register scratch, - Label* oom_label) { - STATIC_ASSERT(Failure::OUT_OF_MEMORY_EXCEPTION == 3); - STATIC_ASSERT(kFailureTag == 3); - __ and_(scratch, value, Operand(0xf)); - __ cmp(scratch, Operand(0xf)); - __ b(eq, oom_label); -} - - void CEntryStub::GenerateCore(MacroAssembler* masm, Label* throw_normal_exception, Label* throw_termination_exception, - Label* throw_out_of_memory_exception, bool do_gc, bool always_allocate) { // r0: result parameter for PerformGC, if any @@ -1614,17 +1601,11 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, __ tst(r0, Operand(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); __ b(eq, &retry); - // Special handling of out of memory exceptions. - JumpIfOOM(masm, r0, ip, throw_out_of_memory_exception); - // Retrieve the pending exception. __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress, isolate))); __ ldr(r0, MemOperand(ip)); - // See if we just retrieved an OOM exception. - JumpIfOOM(masm, r0, ip, throw_out_of_memory_exception); - // Clear the pending exception. __ LoadRoot(r3, Heap::kTheHoleValueRootIndex); __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress, @@ -1679,13 +1660,11 @@ void CEntryStub::Generate(MacroAssembler* masm) { Label throw_normal_exception; Label throw_termination_exception; - Label throw_out_of_memory_exception; // Call into the runtime system. GenerateCore(masm, &throw_normal_exception, &throw_termination_exception, - &throw_out_of_memory_exception, false, false); @@ -1693,7 +1672,6 @@ void CEntryStub::Generate(MacroAssembler* masm) { GenerateCore(masm, &throw_normal_exception, &throw_termination_exception, - &throw_out_of_memory_exception, true, false); @@ -1703,30 +1681,9 @@ void CEntryStub::Generate(MacroAssembler* masm) { GenerateCore(masm, &throw_normal_exception, &throw_termination_exception, - &throw_out_of_memory_exception, true, true); - __ bind(&throw_out_of_memory_exception); - // Set external caught exception to false. - Isolate* isolate = masm->isolate(); - ExternalReference external_caught(Isolate::kExternalCaughtExceptionAddress, - isolate); - __ mov(r0, Operand(false, RelocInfo::NONE32)); - __ mov(r2, Operand(external_caught)); - __ str(r0, MemOperand(r2)); - - // Set pending exception and r0 to out of memory exception. - Label already_have_failure; - JumpIfOOM(masm, r0, ip, &already_have_failure); - Failure* out_of_memory = Failure::OutOfMemoryException(0x1); - __ mov(r0, Operand(reinterpret_cast(out_of_memory))); - __ bind(&already_have_failure); - __ mov(r2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, - isolate))); - __ str(r0, MemOperand(r2)); - // Fall through to the next label. - __ bind(&throw_termination_exception); __ ThrowUncatchable(r0); diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc index f06f6bc..61b395f 100644 --- a/src/arm64/code-stubs-arm64.cc +++ b/src/arm64/code-stubs-arm64.cc @@ -1405,18 +1405,6 @@ void CodeStub::GenerateFPStubs(Isolate* isolate) { } -static void JumpIfOOM(MacroAssembler* masm, - Register value, - Register scratch, - Label* oom_label) { - STATIC_ASSERT(Failure::OUT_OF_MEMORY_EXCEPTION == 3); - STATIC_ASSERT(kFailureTag == 3); - __ And(scratch, value, 0xf); - __ Cmp(scratch, 0xf); - __ B(eq, oom_label); -} - - bool CEntryStub::NeedsImmovableCode() { // CEntryStub stores the return address on the stack before calling into // C++ code. In some cases, the VM accesses this address, but it is not used @@ -1441,7 +1429,6 @@ void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { void CEntryStub::GenerateCore(MacroAssembler* masm, Label* throw_normal, Label* throw_termination, - Label* throw_out_of_memory, bool do_gc, bool always_allocate) { // x0 : Result parameter for PerformGC, if do_gc is true. @@ -1589,10 +1576,6 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, __ Tst(result, kFailureTypeTagMask << kFailureTagSize); __ B(eq, &retry); // RETRY_AFTER_GC - // Special handling of out-of-memory exceptions: Pass the failure result, - // rather than the exception descriptor. - JumpIfOOM(masm, result, x10, throw_out_of_memory); - // Retrieve the pending exception. const Register& exception = result; const Register& exception_address = x11; @@ -1601,9 +1584,6 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, isolate))); __ Ldr(exception, MemOperand(exception_address)); - // See if we just retrieved an OOM exception. - JumpIfOOM(masm, exception, x10, throw_out_of_memory); - // Clear the pending exception. __ Mov(x10, Operand(isolate->factory()->the_hole_value())); __ Str(x10, MemOperand(exception_address)); @@ -1697,13 +1677,11 @@ void CEntryStub::Generate(MacroAssembler* masm) { Label throw_normal; Label throw_termination; - Label throw_out_of_memory; // Call the runtime function. GenerateCore(masm, &throw_normal, &throw_termination, - &throw_out_of_memory, false, false); @@ -1714,7 +1692,6 @@ void CEntryStub::Generate(MacroAssembler* masm) { GenerateCore(masm, &throw_normal, &throw_termination, - &throw_out_of_memory, true, false); @@ -1723,7 +1700,6 @@ void CEntryStub::Generate(MacroAssembler* masm) { GenerateCore(masm, &throw_normal, &throw_termination, - &throw_out_of_memory, true, true); @@ -1740,27 +1716,6 @@ void CEntryStub::Generate(MacroAssembler* masm) { // If we throw an exception, we can end up re-entering CEntryStub before we // pop the exit frame, so need to ensure that x21-x23 contain GC-safe values // here. - __ Bind(&throw_out_of_memory); - ASM_LOCATION("Throw out of memory"); - __ Mov(argv, 0); - __ Mov(argc, 0); - __ Mov(target, 0); - // Set external caught exception to false. - Isolate* isolate = masm->isolate(); - __ Mov(x2, Operand(ExternalReference(Isolate::kExternalCaughtExceptionAddress, - isolate))); - __ Str(xzr, MemOperand(x2)); - - // Set pending exception and x0 to out of memory exception. - Label already_have_failure; - JumpIfOOM(masm, x0, x10, &already_have_failure); - Failure* out_of_memory = Failure::OutOfMemoryException(0x1); - __ Mov(x0, Operand(reinterpret_cast(out_of_memory))); - __ Bind(&already_have_failure); - __ Mov(x2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, - isolate))); - __ Str(x0, MemOperand(x2)); - // Fall through to the next label. __ Bind(&throw_termination); ASM_LOCATION("Throw termination"); diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 7edc5d5..7942c7f 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -1310,9 +1310,6 @@ void Genesis::InitializeGlobal(Handle inner_global, delegate->shared()->DontAdaptArguments(); } - // Initialize the out of memory slot. - native_context()->set_out_of_memory(heap->false_value()); - // Initialize the embedder data slot. Handle embedder_data = factory->NewFixedArray(3); native_context()->set_embedder_data(*embedder_data); diff --git a/src/code-stubs.h b/src/code-stubs.h index 3367c6d..25328fe 100644 --- a/src/code-stubs.h +++ b/src/code-stubs.h @@ -1496,7 +1496,6 @@ class CEntryStub : public PlatformCodeStub { void GenerateCore(MacroAssembler* masm, Label* throw_normal_exception, Label* throw_termination_exception, - Label* throw_out_of_memory_exception, bool do_gc, bool always_allocate_scope); diff --git a/src/contexts.h b/src/contexts.h index 479a692..6ba9b3e 100644 --- a/src/contexts.h +++ b/src/contexts.h @@ -162,7 +162,6 @@ enum BindingFlags { V(SCRIPT_FUNCTION_INDEX, JSFunction, script_function) \ V(OPAQUE_REFERENCE_FUNCTION_INDEX, JSFunction, opaque_reference_function) \ V(CONTEXT_EXTENSION_FUNCTION_INDEX, JSFunction, context_extension_function) \ - V(OUT_OF_MEMORY_INDEX, Object, out_of_memory) \ V(MAP_CACHE_INDEX, Object, map_cache) \ V(EMBEDDER_DATA_INDEX, FixedArray, embedder_data) \ V(ALLOW_CODE_GEN_FROM_STRINGS_INDEX, Object, allow_code_gen_from_strings) \ @@ -440,12 +439,6 @@ class Context: public FixedArray { return map == map->GetHeap()->global_context_map(); } - // Tells whether the native context is marked with out of memory. - inline bool has_out_of_memory(); - - // Mark the native context with out of memory. - inline void mark_out_of_memory(); - // A native context holds a list of all functions with optimized code. void AddOptimizedFunction(JSFunction* function); void RemoveOptimizedFunction(JSFunction* function); diff --git a/src/elements.cc b/src/elements.cc index 1ddc69d..527df6e 100644 --- a/src/elements.cc +++ b/src/elements.cc @@ -318,7 +318,7 @@ MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( // that no GC is triggered, allocate HeapNumbers from old space if they // can't be taken from new space. if (!maybe_value->ToObject(&value)) { - ASSERT(maybe_value->IsRetryAfterGC() || maybe_value->IsOutOfMemory()); + ASSERT(maybe_value->IsRetryAfterGC()); Heap* heap = from->GetHeap(); MaybeObject* maybe_value_object = heap->AllocateHeapNumber(from->get_scalar(i + from_start), diff --git a/src/execution.cc b/src/execution.cc index 1e0a6a8..7442d17 100644 --- a/src/execution.cc +++ b/src/execution.cc @@ -135,11 +135,6 @@ static Handle Invoke(bool is_construct, ASSERT(*has_pending_exception == isolate->has_pending_exception()); if (*has_pending_exception) { isolate->ReportPendingMessages(); - if (isolate->pending_exception()->IsOutOfMemory()) { - if (!isolate->ignore_out_of_memory()) { - V8::FatalProcessOutOfMemory("JS", true); - } - } #ifdef ENABLE_DEBUGGER_SUPPORT // Reset stepping state when script exits with uncaught exception. if (isolate->debugger()->IsDebuggerActive()) { @@ -225,9 +220,6 @@ Handle Execution::TryCall(Handle func, ASSERT(catcher.HasCaught()); ASSERT(isolate->has_pending_exception()); ASSERT(isolate->external_caught_exception()); - if (isolate->is_out_of_memory() && !isolate->ignore_out_of_memory()) { - V8::FatalProcessOutOfMemory("OOM during Execution::TryCall"); - } if (isolate->pending_exception() == isolate->heap()->termination_exception()) { result = isolate->factory()->termination_exception(); diff --git a/src/heap-inl.h b/src/heap-inl.h index efad2fb..7e465d5 100644 --- a/src/heap-inl.h +++ b/src/heap-inl.h @@ -138,7 +138,7 @@ MaybeObject* Heap::AllocateInternalizedStringImpl( MaybeObject* Heap::AllocateOneByteInternalizedString(Vector str, uint32_t hash_field) { if (str.length() > String::kMaxLength) { - return Failure::OutOfMemoryException(0x2); + v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true); } // Compute map and object size. Map* map = ascii_internalized_string_map(); @@ -171,7 +171,7 @@ MaybeObject* Heap::AllocateOneByteInternalizedString(Vector str, MaybeObject* Heap::AllocateTwoByteInternalizedString(Vector str, uint32_t hash_field) { if (str.length() > String::kMaxLength) { - return Failure::OutOfMemoryException(0x3); + v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true); } // Compute map and object size. Map* map = internalized_string_map(); @@ -641,24 +641,18 @@ Isolate* Heap::isolate() { // Warning: Do not use the identifiers __object__, __maybe_object__ or // __scope__ in a call to this macro. -#define CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY, OOM)\ +#define CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY) \ do { \ GC_GREEDY_CHECK(ISOLATE); \ MaybeObject* __maybe_object__ = FUNCTION_CALL; \ Object* __object__ = NULL; \ if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \ - if (__maybe_object__->IsOutOfMemory()) { \ - OOM; \ - } \ if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY; \ (ISOLATE)->heap()->CollectGarbage(Failure::cast(__maybe_object__)-> \ allocation_space(), \ "allocation failure"); \ __maybe_object__ = FUNCTION_CALL; \ if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \ - if (__maybe_object__->IsOutOfMemory()) { \ - OOM; \ - } \ if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY; \ (ISOLATE)->counters()->gc_last_resort_from_handles()->Increment(); \ (ISOLATE)->heap()->CollectAllAvailableGarbage("last resort gc"); \ @@ -667,9 +661,6 @@ Isolate* Heap::isolate() { __maybe_object__ = FUNCTION_CALL; \ } \ if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \ - if (__maybe_object__->IsOutOfMemory()) { \ - OOM; \ - } \ if (__maybe_object__->IsRetryAfterGC()) { \ /* TODO(1181417): Fix this. */ \ v8::internal::Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true);\ @@ -683,8 +674,7 @@ Isolate* Heap::isolate() { ISOLATE, \ FUNCTION_CALL, \ RETURN_VALUE, \ - RETURN_EMPTY, \ - v8::internal::Heap::FatalProcessOutOfMemory("CALL_AND_RETRY", true)) + RETURN_EMPTY) #define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE) \ CALL_AND_RETRY_OR_DIE(ISOLATE, \ @@ -701,7 +691,6 @@ Isolate* Heap::isolate() { CALL_AND_RETRY(ISOLATE, \ FUNCTION_CALL, \ return __object__, \ - return __maybe_object__, \ return __maybe_object__) diff --git a/src/heap.cc b/src/heap.cc index 0691947..6b2f8f7 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -3871,8 +3871,7 @@ MaybeObject* Heap::AllocateExternalStringFromAscii( const ExternalAsciiString::Resource* resource) { size_t length = resource->length(); if (length > static_cast(String::kMaxLength)) { - isolate()->context()->mark_out_of_memory(); - return Failure::OutOfMemoryException(0x5); + v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true); } Map* map = external_ascii_string_map(); @@ -3894,8 +3893,7 @@ MaybeObject* Heap::AllocateExternalStringFromTwoByte( const ExternalTwoByteString::Resource* resource) { size_t length = resource->length(); if (length > static_cast(String::kMaxLength)) { - isolate()->context()->mark_out_of_memory(); - return Failure::OutOfMemoryException(0x6); + v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true); } // For small strings we check whether the resource contains only @@ -3946,7 +3944,7 @@ MaybeObject* Heap::LookupSingleCharacterStringFromCode(uint16_t code) { MaybeObject* Heap::AllocateByteArray(int length, PretenureFlag pretenure) { if (length < 0 || length > ByteArray::kMaxLength) { - return Failure::OutOfMemoryException(0x7); + v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true); } int size = ByteArray::SizeFor(length); AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); @@ -4981,7 +4979,7 @@ MaybeObject* Heap::AllocateInternalizedStringImpl( Map* map; if (chars > String::kMaxLength) { - return Failure::OutOfMemoryException(0x9); + v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true); } if (is_one_byte) { map = ascii_internalized_string_map(); @@ -5029,7 +5027,7 @@ MaybeObject* Heap::AllocateInternalizedStringImpl( MaybeObject* Heap::AllocateRawOneByteString(int length, PretenureFlag pretenure) { if (length < 0 || length > String::kMaxLength) { - return Failure::OutOfMemoryException(0xb); + v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true); } int size = SeqOneByteString::SizeFor(length); ASSERT(size <= SeqOneByteString::kMaxSize); @@ -5053,7 +5051,7 @@ MaybeObject* Heap::AllocateRawOneByteString(int length, MaybeObject* Heap::AllocateRawTwoByteString(int length, PretenureFlag pretenure) { if (length < 0 || length > String::kMaxLength) { - return Failure::OutOfMemoryException(0xc); + v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true); } int size = SeqTwoByteString::SizeFor(length); ASSERT(size <= SeqTwoByteString::kMaxSize); @@ -5201,7 +5199,7 @@ MaybeObject* Heap::CopyConstantPoolArrayWithMap(ConstantPoolArray* src, MaybeObject* Heap::AllocateRawFixedArray(int length, PretenureFlag pretenure) { if (length < 0 || length > FixedArray::kMaxLength) { - return Failure::OutOfMemoryException(0xe); + v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true); } int size = FixedArray::SizeFor(length); AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, pretenure); @@ -5313,7 +5311,7 @@ MaybeObject* Heap::AllocateFixedDoubleArrayWithHoles( MaybeObject* Heap::AllocateRawFixedDoubleArray(int length, PretenureFlag pretenure) { if (length < 0 || length > FixedDoubleArray::kMaxLength) { - return Failure::OutOfMemoryException(0xf); + v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true); } int size = FixedDoubleArray::SizeFor(length); #ifndef V8_HOST_ARCH_64_BIT diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index fa67502..ce9bd21 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -2583,23 +2583,9 @@ void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { } -static void JumpIfOOM(MacroAssembler* masm, - Register value, - Register scratch, - Label* oom_label) { - __ mov(scratch, value); - STATIC_ASSERT(Failure::OUT_OF_MEMORY_EXCEPTION == 3); - STATIC_ASSERT(kFailureTag == 3); - __ and_(scratch, 0xf); - __ cmp(scratch, 0xf); - __ j(equal, oom_label); -} - - void CEntryStub::GenerateCore(MacroAssembler* masm, Label* throw_normal_exception, Label* throw_termination_exception, - Label* throw_out_of_memory_exception, bool do_gc, bool always_allocate_scope) { // eax: result parameter for PerformGC, if any @@ -2694,15 +2680,9 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, __ test(eax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); __ j(zero, &retry, Label::kNear); - // Special handling of out of memory exceptions. - JumpIfOOM(masm, eax, ecx, throw_out_of_memory_exception); - // Retrieve the pending exception. __ mov(eax, Operand::StaticVariable(pending_exception_address)); - // See if we just retrieved an OOM exception. - JumpIfOOM(masm, eax, ecx, throw_out_of_memory_exception); - // Clear the pending exception. __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value())); __ mov(Operand::StaticVariable(pending_exception_address), edx); @@ -2746,13 +2726,11 @@ void CEntryStub::Generate(MacroAssembler* masm) { Label throw_normal_exception; Label throw_termination_exception; - Label throw_out_of_memory_exception; // Call into the runtime system. GenerateCore(masm, &throw_normal_exception, &throw_termination_exception, - &throw_out_of_memory_exception, false, false); @@ -2760,7 +2738,6 @@ void CEntryStub::Generate(MacroAssembler* masm) { GenerateCore(masm, &throw_normal_exception, &throw_termination_exception, - &throw_out_of_memory_exception, true, false); @@ -2770,27 +2747,9 @@ void CEntryStub::Generate(MacroAssembler* masm) { GenerateCore(masm, &throw_normal_exception, &throw_termination_exception, - &throw_out_of_memory_exception, true, true); - __ bind(&throw_out_of_memory_exception); - // Set external caught exception to false. - Isolate* isolate = masm->isolate(); - ExternalReference external_caught(Isolate::kExternalCaughtExceptionAddress, - isolate); - __ mov(Operand::StaticVariable(external_caught), Immediate(false)); - - // Set pending exception and eax to out of memory exception. - ExternalReference pending_exception(Isolate::kPendingExceptionAddress, - isolate); - Label already_have_failure; - JumpIfOOM(masm, eax, ecx, &already_have_failure); - __ mov(eax, reinterpret_cast(Failure::OutOfMemoryException(0x1))); - __ bind(&already_have_failure); - __ mov(Operand::StaticVariable(pending_exception), eax); - // Fall through to the next label. - __ bind(&throw_termination_exception); __ ThrowUncatchable(eax); diff --git a/src/isolate.cc b/src/isolate.cc index 5518f00..2e94828 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -80,10 +80,6 @@ int ThreadId::GetCurrentThreadId() { ThreadLocalTop::ThreadLocalTop() { InitializeInternal(); - // This flag may be set using v8::V8::IgnoreOutOfMemoryException() - // before an isolate is initialized. The initialize methods below do - // not touch it to preserve its value. - ignore_out_of_memory_ = false; } @@ -1273,14 +1269,8 @@ void Isolate::ReportPendingMessages() { ASSERT(has_pending_exception()); PropagatePendingExceptionToExternalTryCatch(); - // If the pending exception is OutOfMemoryException set out_of_memory in - // the native context. Note: We have to mark the native context here - // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to - // set it. HandleScope scope(this); - if (thread_local_top_.pending_exception_->IsOutOfMemory()) { - context()->mark_out_of_memory(); - } else if (thread_local_top_.pending_exception_ == + if (thread_local_top_.pending_exception_ == heap()->termination_exception()) { // Do nothing: if needed, the exception has been already propagated to // v8::TryCatch. @@ -1311,8 +1301,7 @@ void Isolate::ReportPendingMessages() { MessageLocation Isolate::GetMessageLocation() { ASSERT(has_pending_exception()); - if (!thread_local_top_.pending_exception_->IsOutOfMemory() && - thread_local_top_.pending_exception_ != heap()->termination_exception() && + if (thread_local_top_.pending_exception_ != heap()->termination_exception() && thread_local_top_.has_pending_message_ && !thread_local_top_.pending_message_obj_->IsTheHole() && !thread_local_top_.pending_message_obj_->IsTheHole()) { @@ -1331,39 +1320,36 @@ bool Isolate::OptionalRescheduleException(bool is_bottom_call) { ASSERT(has_pending_exception()); PropagatePendingExceptionToExternalTryCatch(); - // Always reschedule out of memory exceptions. - if (!is_out_of_memory()) { - bool is_termination_exception = - pending_exception() == heap_.termination_exception(); + bool is_termination_exception = + pending_exception() == heap_.termination_exception(); - // Do not reschedule the exception if this is the bottom call. - bool clear_exception = is_bottom_call; + // Do not reschedule the exception if this is the bottom call. + bool clear_exception = is_bottom_call; - if (is_termination_exception) { - if (is_bottom_call) { - thread_local_top()->external_caught_exception_ = false; - clear_pending_exception(); - return false; - } - } else if (thread_local_top()->external_caught_exception_) { - // If the exception is externally caught, clear it if there are no - // JavaScript frames on the way to the C++ frame that has the - // external handler. - ASSERT(thread_local_top()->try_catch_handler_address() != NULL); - Address external_handler_address = - thread_local_top()->try_catch_handler_address(); - JavaScriptFrameIterator it(this); - if (it.done() || (it.frame()->sp() > external_handler_address)) { - clear_exception = true; - } - } - - // Clear the exception if needed. - if (clear_exception) { + if (is_termination_exception) { + if (is_bottom_call) { thread_local_top()->external_caught_exception_ = false; clear_pending_exception(); return false; } + } else if (thread_local_top()->external_caught_exception_) { + // If the exception is externally caught, clear it if there are no + // JavaScript frames on the way to the C++ frame that has the + // external handler. + ASSERT(thread_local_top()->try_catch_handler_address() != NULL); + Address external_handler_address = + thread_local_top()->try_catch_handler_address(); + JavaScriptFrameIterator it(this); + if (it.done() || (it.frame()->sp() > external_handler_address)) { + clear_exception = true; + } + } + + // Clear the exception if needed. + if (clear_exception) { + thread_local_top()->external_caught_exception_ = false; + clear_pending_exception(); + return false; } // Reschedule the exception. @@ -1383,23 +1369,6 @@ void Isolate::SetCaptureStackTraceForUncaughtExceptions( } -bool Isolate::is_out_of_memory() { - if (has_pending_exception()) { - MaybeObject* e = pending_exception(); - if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) { - return true; - } - } - if (has_scheduled_exception()) { - MaybeObject* e = scheduled_exception(); - if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) { - return true; - } - } - return false; -} - - Handle Isolate::native_context() { return Handle(context()->global_object()->native_context()); } @@ -1851,9 +1820,7 @@ void Isolate::PropagatePendingExceptionToExternalTryCatch() { if (!external_caught) return; - if (thread_local_top_.pending_exception_->IsOutOfMemory()) { - // Do not propagate OOM exception: we should kill VM asap. - } else if (thread_local_top_.pending_exception_ == + if (thread_local_top_.pending_exception_ == heap()->termination_exception()) { try_catch_handler()->can_continue_ = false; try_catch_handler()->has_terminated_ = true; diff --git a/src/isolate.h b/src/isolate.h index 1f3361c..9111a1d 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -288,9 +288,6 @@ class ThreadLocalTop BASE_EMBEDDED { // Head of the list of live LookupResults. LookupResult* top_lookup_result_; - // Whether out of memory exceptions should be ignored. - bool ignore_out_of_memory_; - private: void InitializeInternal(); @@ -641,8 +638,7 @@ class Isolate { bool IsExternallyCaught(); bool is_catchable_by_javascript(MaybeObject* exception) { - return (!exception->IsOutOfMemory()) && - (exception != heap()->termination_exception()); + return exception != heap()->termination_exception(); } // Serializer. @@ -721,12 +717,6 @@ class Isolate { int frame_limit, StackTrace::StackTraceOptions options); - // Tells whether the current context has experienced an out of memory - // exception. - bool is_out_of_memory(); - - THREAD_LOCAL_TOP_ACCESSOR(bool, ignore_out_of_memory) - void PrintCurrentStackTrace(FILE* out); void PrintStack(StringStream* accumulator); void PrintStack(FILE* out); @@ -1475,17 +1465,6 @@ class PostponeInterruptsScope BASE_EMBEDDED { }; -// Tells whether the native context is marked with out of memory. -inline bool Context::has_out_of_memory() { - return native_context()->out_of_memory()->IsTrue(); -} - - -// Mark the native context with out of memory. -inline void Context::mark_out_of_memory() { - native_context()->set_out_of_memory(GetIsolate()->heap()->true_value()); -} - class CodeTracer V8_FINAL : public Malloced { public: explicit CodeTracer(int isolate_id) diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index 6d06bd9..3b8e223 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -1606,21 +1606,9 @@ void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { } -static void JumpIfOOM(MacroAssembler* masm, - Register value, - Register scratch, - Label* oom_label) { - STATIC_ASSERT(Failure::OUT_OF_MEMORY_EXCEPTION == 3); - STATIC_ASSERT(kFailureTag == 3); - __ andi(scratch, value, 0xf); - __ Branch(oom_label, eq, scratch, Operand(0xf)); -} - - void CEntryStub::GenerateCore(MacroAssembler* masm, Label* throw_normal_exception, Label* throw_termination_exception, - Label* throw_out_of_memory_exception, bool do_gc, bool always_allocate) { // v0: result parameter for PerformGC, if any @@ -1723,17 +1711,11 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, __ andi(t0, v0, ((1 << kFailureTypeTagSize) - 1) << kFailureTagSize); __ Branch(&retry, eq, t0, Operand(zero_reg)); - // Special handling of out of memory exceptions. - JumpIfOOM(masm, v0, t0, throw_out_of_memory_exception); - // Retrieve the pending exception. __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress, isolate))); __ lw(v0, MemOperand(t0)); - // See if we just retrieved an OOM exception. - JumpIfOOM(masm, v0, t0, throw_out_of_memory_exception); - // Clear the pending exception. __ li(a3, Operand(isolate->factory()->the_hole_value())); __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress, @@ -1787,13 +1769,11 @@ void CEntryStub::Generate(MacroAssembler* masm) { Label throw_normal_exception; Label throw_termination_exception; - Label throw_out_of_memory_exception; // Call into the runtime system. GenerateCore(masm, &throw_normal_exception, &throw_termination_exception, - &throw_out_of_memory_exception, false, false); @@ -1801,7 +1781,6 @@ void CEntryStub::Generate(MacroAssembler* masm) { GenerateCore(masm, &throw_normal_exception, &throw_termination_exception, - &throw_out_of_memory_exception, true, false); @@ -1811,30 +1790,9 @@ void CEntryStub::Generate(MacroAssembler* masm) { GenerateCore(masm, &throw_normal_exception, &throw_termination_exception, - &throw_out_of_memory_exception, true, true); - __ bind(&throw_out_of_memory_exception); - // Set external caught exception to false. - Isolate* isolate = masm->isolate(); - ExternalReference external_caught(Isolate::kExternalCaughtExceptionAddress, - isolate); - __ li(a0, Operand(false, RelocInfo::NONE32)); - __ li(a2, Operand(external_caught)); - __ sw(a0, MemOperand(a2)); - - // Set pending exception and v0 to out of memory exception. - Label already_have_failure; - JumpIfOOM(masm, v0, t0, &already_have_failure); - Failure* out_of_memory = Failure::OutOfMemoryException(0x1); - __ li(v0, Operand(reinterpret_cast(out_of_memory))); - __ bind(&already_have_failure); - __ li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, - isolate))); - __ sw(v0, MemOperand(a2)); - // Fall through to the next label. - __ bind(&throw_termination_exception); __ ThrowUncatchable(v0); diff --git a/src/objects-inl.h b/src/objects-inl.h index 2e60a44..b3f23e6 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -649,12 +649,6 @@ bool MaybeObject::IsRetryAfterGC() { } -bool MaybeObject::IsOutOfMemory() { - return HAS_FAILURE_TAG(this) - && Failure::cast(this)->IsOutOfMemoryException(); -} - - bool MaybeObject::IsException() { return this == Failure::Exception(); } @@ -1245,11 +1239,6 @@ bool Failure::IsInternalError() const { } -bool Failure::IsOutOfMemoryException() const { - return type() == OUT_OF_MEMORY_EXCEPTION; -} - - AllocationSpace Failure::allocation_space() const { ASSERT_EQ(RETRY_AFTER_GC, type()); return static_cast((value() >> kFailureTypeTagSize) @@ -1267,11 +1256,6 @@ Failure* Failure::Exception() { } -Failure* Failure::OutOfMemoryException(intptr_t value) { - return Construct(OUT_OF_MEMORY_EXCEPTION, value); -} - - intptr_t Failure::value() const { return static_cast( reinterpret_cast(this) >> kFailureTagSize); diff --git a/src/objects.cc b/src/objects.cc index dae3223..c764b33 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -13921,7 +13921,7 @@ MaybeObject* HashTable::Allocate(Heap* heap, ? at_least_space_for : ComputeCapacity(at_least_space_for); if (capacity > HashTable::kMaxCapacity) { - return Failure::OutOfMemoryException(0x10); + v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); } Object* obj; diff --git a/src/objects.h b/src/objects.h index 34edd0a..c4d3f25 100644 --- a/src/objects.h +++ b/src/objects.h @@ -934,7 +934,6 @@ class MaybeObject BASE_EMBEDDED { public: inline bool IsFailure(); inline bool IsRetryAfterGC(); - inline bool IsOutOfMemory(); inline bool IsException(); INLINE(bool IsTheHole()); INLINE(bool IsUninitialized()); @@ -1728,15 +1727,11 @@ class Failure: public MaybeObject { inline AllocationSpace allocation_space() const; inline bool IsInternalError() const; - inline bool IsOutOfMemoryException() const; static inline Failure* RetryAfterGC(AllocationSpace space); static inline Failure* RetryAfterGC(); // NEW_SPACE static inline Failure* Exception(); static inline Failure* InternalError(); - // TODO(jkummerow): The value is temporary instrumentation. Remove it - // when it has served its purpose. - static inline Failure* OutOfMemoryException(intptr_t value); // Casting. static inline Failure* cast(MaybeObject* object); diff --git a/src/runtime.cc b/src/runtime.cc index b4c34ef..8b18e55 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -3913,7 +3913,9 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalAtomRegExpWithString( static_cast(pattern_len)) * static_cast(matches) + static_cast(subject_len); - if (result_len_64 > INT_MAX) return Failure::OutOfMemoryException(0x11); + if (result_len_64 > INT_MAX) { + v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true); + } int result_len = static_cast(result_len_64); int subject_pos = 0; diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index ce820b1..dc5496c 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -2407,23 +2407,9 @@ void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { } -static void JumpIfOOM(MacroAssembler* masm, - Register value, - Register scratch, - Label* oom_label) { - __ movp(scratch, value); - STATIC_ASSERT(Failure::OUT_OF_MEMORY_EXCEPTION == 3); - STATIC_ASSERT(kFailureTag == 3); - __ and_(scratch, Immediate(0xf)); - __ cmpq(scratch, Immediate(0xf)); - __ j(equal, oom_label); -} - - void CEntryStub::GenerateCore(MacroAssembler* masm, Label* throw_normal_exception, Label* throw_termination_exception, - Label* throw_out_of_memory_exception, bool do_gc, bool always_allocate_scope) { // rax: result parameter for PerformGC, if any. @@ -2530,9 +2516,6 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, __ testl(rax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); __ j(zero, &retry, Label::kNear); - // Special handling of out of memory exceptions. - JumpIfOOM(masm, rax, kScratchRegister, throw_out_of_memory_exception); - // Retrieve the pending exception. ExternalReference pending_exception_address( Isolate::kPendingExceptionAddress, masm->isolate()); @@ -2540,9 +2523,6 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, masm->ExternalOperand(pending_exception_address); __ movp(rax, pending_exception_operand); - // See if we just retrieved an OOM exception. - JumpIfOOM(masm, rax, kScratchRegister, throw_out_of_memory_exception); - // Clear the pending exception. pending_exception_operand = masm->ExternalOperand(pending_exception_address); @@ -2598,13 +2578,11 @@ void CEntryStub::Generate(MacroAssembler* masm) { Label throw_normal_exception; Label throw_termination_exception; - Label throw_out_of_memory_exception; // Call into the runtime system. GenerateCore(masm, &throw_normal_exception, &throw_termination_exception, - &throw_out_of_memory_exception, false, false); @@ -2612,7 +2590,6 @@ void CEntryStub::Generate(MacroAssembler* masm) { GenerateCore(masm, &throw_normal_exception, &throw_termination_exception, - &throw_out_of_memory_exception, true, false); @@ -2622,28 +2599,9 @@ void CEntryStub::Generate(MacroAssembler* masm) { GenerateCore(masm, &throw_normal_exception, &throw_termination_exception, - &throw_out_of_memory_exception, true, true); - __ bind(&throw_out_of_memory_exception); - // Set external caught exception to false. - Isolate* isolate = masm->isolate(); - ExternalReference external_caught(Isolate::kExternalCaughtExceptionAddress, - isolate); - __ Set(rax, static_cast(false)); - __ Store(external_caught, rax); - - // Set pending exception and rax to out of memory exception. - ExternalReference pending_exception(Isolate::kPendingExceptionAddress, - isolate); - Label already_have_failure; - JumpIfOOM(masm, rax, kScratchRegister, &already_have_failure); - __ Move(rax, Failure::OutOfMemoryException(0x1), Assembler::RelocInfoNone()); - __ bind(&already_have_failure); - __ Store(pending_exception, rax); - // Fall through to the next label. - __ bind(&throw_termination_exception); __ ThrowUncatchable(rax); diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index a159522..0818f33 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -19332,7 +19332,6 @@ TEST(IsolateDifferentContexts) { class InitDefaultIsolateThread : public v8::internal::Thread { public: enum TestCase { - IgnoreOOM, SetResourceConstraints, SetFatalHandler, SetCounterFunction, @@ -19349,34 +19348,30 @@ class InitDefaultIsolateThread : public v8::internal::Thread { v8::Isolate* isolate = v8::Isolate::New(); isolate->Enter(); switch (testCase_) { - case IgnoreOOM: - v8::V8::IgnoreOutOfMemoryException(); - break; - - case SetResourceConstraints: { - static const int K = 1024; - v8::ResourceConstraints constraints; - constraints.set_max_young_space_size(256 * K); - constraints.set_max_old_space_size(4 * K * K); - v8::SetResourceConstraints(CcTest::isolate(), &constraints); - break; - } + case SetResourceConstraints: { + static const int K = 1024; + v8::ResourceConstraints constraints; + constraints.set_max_young_space_size(256 * K); + constraints.set_max_old_space_size(4 * K * K); + v8::SetResourceConstraints(CcTest::isolate(), &constraints); + break; + } - case SetFatalHandler: - v8::V8::SetFatalErrorHandler(NULL); - break; + case SetFatalHandler: + v8::V8::SetFatalErrorHandler(NULL); + break; - case SetCounterFunction: - v8::V8::SetCounterFunction(NULL); - break; + case SetCounterFunction: + v8::V8::SetCounterFunction(NULL); + break; - case SetCreateHistogramFunction: - v8::V8::SetCreateHistogramFunction(NULL); - break; + case SetCreateHistogramFunction: + v8::V8::SetCreateHistogramFunction(NULL); + break; - case SetAddHistogramSampleFunction: - v8::V8::SetAddHistogramSampleFunction(NULL); - break; + case SetAddHistogramSampleFunction: + v8::V8::SetAddHistogramSampleFunction(NULL); + break; } isolate->Exit(); isolate->Dispose(); @@ -19400,31 +19395,26 @@ static void InitializeTestHelper(InitDefaultIsolateThread::TestCase testCase) { TEST(InitializeDefaultIsolateOnSecondaryThread1) { - InitializeTestHelper(InitDefaultIsolateThread::IgnoreOOM); -} - - -TEST(InitializeDefaultIsolateOnSecondaryThread2) { InitializeTestHelper(InitDefaultIsolateThread::SetResourceConstraints); } -TEST(InitializeDefaultIsolateOnSecondaryThread3) { +TEST(InitializeDefaultIsolateOnSecondaryThread2) { InitializeTestHelper(InitDefaultIsolateThread::SetFatalHandler); } -TEST(InitializeDefaultIsolateOnSecondaryThread4) { +TEST(InitializeDefaultIsolateOnSecondaryThread3) { InitializeTestHelper(InitDefaultIsolateThread::SetCounterFunction); } -TEST(InitializeDefaultIsolateOnSecondaryThread5) { +TEST(InitializeDefaultIsolateOnSecondaryThread4) { InitializeTestHelper(InitDefaultIsolateThread::SetCreateHistogramFunction); } -TEST(InitializeDefaultIsolateOnSecondaryThread6) { +TEST(InitializeDefaultIsolateOnSecondaryThread5) { InitializeTestHelper(InitDefaultIsolateThread::SetAddHistogramSampleFunction); } diff --git a/test/cctest/test-strings.cc b/test/cctest/test-strings.cc index 8e63cb0..0f37c3e 100644 --- a/test/cctest/test-strings.cc +++ b/test/cctest/test-strings.cc @@ -1275,23 +1275,6 @@ TEST(RobustSubStringStub) { } -TEST(RegExpOverflow) { - // Result string has the length 2^32, causing a 32-bit integer overflow. - CcTest::InitializeVM(); - v8::HandleScope scope(CcTest::isolate()); - LocalContext context; - v8::V8::IgnoreOutOfMemoryException(); - v8::Local result = CompileRun( - "var a = 'a'; " - "for (var i = 0; i < 16; i++) { " - " a += a; " - "} " - "a.replace(/a/g, a); "); - CHECK(result.IsEmpty()); - CHECK(context->HasOutOfMemoryException()); -} - - TEST(StringReplaceAtomTwoByteResult) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); -- 2.7.4