Remove Failure::OutOfMemory propagation and V8::IgnoreOutOfMemoryException.

R=dcarney@chromium.org
BUG=v8:3060
LOG=Y

Review URL: https://codereview.chromium.org/208263002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20179 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
yangguo@chromium.org 2014-03-24 08:47:45 +00:00
parent 3ab0622b96
commit 62f65d8697
22 changed files with 69 additions and 447 deletions

View File

@ -4615,20 +4615,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.
@ -5233,9 +5219,6 @@ class V8_EXPORT Context {
*/
void Exit();
/** Returns true if the context has experienced an out of memory situation. */
bool HasOutOfMemoryException();
/** Returns an isolate associated with a current context. */
v8::Isolate* GetIsolate();

View File

@ -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<Value> v8::Context::GetSecurityToken() {
}
bool Context::HasOutOfMemoryException() {
i::Handle<i::Context> env = Utils::OpenHandle(this);
return env->has_out_of_memory();
}
v8::Isolate* Context::GetIsolate() {
i::Handle<i::Context> env = Utils::OpenHandle(this);
return reinterpret_cast<Isolate*>(env->GetIsolate());
@ -6225,11 +6214,6 @@ Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
}
void V8::IgnoreOutOfMemoryException() {
EnterIsolateIfNeeded()->set_ignore_out_of_memory(true);
}
bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");

View File

@ -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<int32_t>(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);

View File

@ -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<uint64_t>(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");

View File

@ -1310,9 +1310,6 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> 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<FixedArray> embedder_data = factory->NewFixedArray(3);
native_context()->set_embedder_data(*embedder_data);

View File

@ -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);

View File

@ -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);

View File

@ -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),

View File

@ -135,11 +135,6 @@ static Handle<Object> 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<Object> Execution::TryCall(Handle<JSFunction> 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();

View File

@ -138,7 +138,7 @@ MaybeObject* Heap::AllocateInternalizedStringImpl(
MaybeObject* Heap::AllocateOneByteInternalizedString(Vector<const uint8_t> 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<const uint8_t> str,
MaybeObject* Heap::AllocateTwoByteInternalizedString(Vector<const uc16> 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__)

View File

@ -3871,8 +3871,7 @@ MaybeObject* Heap::AllocateExternalStringFromAscii(
const ExternalAsciiString::Resource* resource) {
size_t length = resource->length();
if (length > static_cast<size_t>(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<size_t>(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<false>(
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

View File

@ -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<int32_t>(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);

View File

@ -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<Context> Isolate::native_context() {
return Handle<Context>(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;

View File

@ -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)

View File

@ -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<int32_t>(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);

View File

@ -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<AllocationSpace>((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<intptr_t>(
reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);

View File

@ -13921,7 +13921,7 @@ MaybeObject* HashTable<Shape, Key>::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;

View File

@ -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);

View File

@ -3913,7 +3913,9 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalAtomRegExpWithString(
static_cast<int64_t>(pattern_len)) *
static_cast<int64_t>(matches) +
static_cast<int64_t>(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<int>(result_len_64);
int subject_pos = 0;

View File

@ -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<int64_t>(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);

View File

@ -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);
}

View File

@ -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<v8::Value> 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());