Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Upgrade v8 to 1.3.6
Browse files Browse the repository at this point in the history
  • Loading branch information
ry committed Aug 21, 2009
1 parent 90ac9ab commit 048a1b8
Show file tree
Hide file tree
Showing 33 changed files with 726 additions and 145 deletions.
16 changes: 16 additions & 0 deletions deps/v8/ChangeLog
@@ -1,3 +1,19 @@
2009-08-21: Version 1.3.6

Add support for forceful termination of JavaScript execution.

Add low memory notification to the API. The embedding host can signal
a low memory situation to V8.

Changed the handling of global handles (persistent handles in the API
sense) to avoid issues regarding allocation of new global handles
during weak handle callbacks.

Changed the growth policy of the young space.

Fixed a GC issue introduced in version 1.3.5.


2009-08-19: Version 1.3.5 2009-08-19: Version 1.3.5


Optimize initialization of some arrays in the builtins. Optimize initialization of some arrays in the builtins.
Expand Down
63 changes: 63 additions & 0 deletions deps/v8/include/v8.h
Expand Up @@ -2223,6 +2223,47 @@ class V8EXPORT V8 {
*/ */
static int GetLogLines(int from_pos, char* dest_buf, int max_size); static int GetLogLines(int from_pos, char* dest_buf, int max_size);


/**
* Retrieve the V8 thread id of the calling thread.
*
* The thread id for a thread should only be retrieved after the V8
* lock has been acquired with a Locker object with that thread.
*/
static int GetCurrentThreadId();

/**
* Forcefully terminate execution of a JavaScript thread. This can
* be used to terminate long-running scripts.
*
* TerminateExecution should only be called when then V8 lock has
* been acquired with a Locker object. Therefore, in order to be
* able to terminate long-running threads, preemption must be
* enabled to allow the user of TerminateExecution to acquire the
* lock.
*
* The termination is achieved by throwing an exception that is
* uncatchable by JavaScript exception handlers. Termination
* exceptions act as if they were caught by a C++ TryCatch exception
* handlers. If forceful termination is used, any C++ TryCatch
* exception handler that catches an exception should check if that
* exception is a termination exception and immediately return if
* that is the case. Returning immediately in that case will
* continue the propagation of the termination exception if needed.
*
* The thread id passed to TerminateExecution must have been
* obtained by calling GetCurrentThreadId on the thread in question.
*
* \param thread_id The thread id of the thread to terminate.
*/
static void TerminateExecution(int thread_id);

/**
* Forcefully terminate the current thread of JavaScript execution.
*
* This method can be used by any thread even if that thread has not
* acquired the V8 lock with a Locker object.
*/
static void TerminateExecution();


/** /**
* Releases any resources used by v8 and stops any utility threads * Releases any resources used by v8 and stops any utility threads
Expand All @@ -2243,6 +2284,12 @@ class V8EXPORT V8 {
*/ */
static void IdleNotification(bool is_high_priority); static void IdleNotification(bool is_high_priority);


/**
* Optional notification that the system is running low on memory.
* V8 uses these notifications to attempt to free memory.
*/
static void LowMemoryNotification();

private: private:
V8(); V8();


Expand Down Expand Up @@ -2281,6 +2328,21 @@ class V8EXPORT TryCatch {
*/ */
bool HasCaught() const; bool HasCaught() const;


/**
* For certain types of exceptions, it makes no sense to continue
* execution.
*
* Currently, the only type of exception that can be caught by a
* TryCatch handler and for which it does not make sense to continue
* is termination exception. Such exceptions are thrown when the
* TerminateExecution methods are called to terminate a long-running
* script.
*
* If CanContinue returns false, the correct action is to perform
* any C++ cleanup needed and then return.
*/
bool CanContinue() const;

/** /**
* Returns the exception caught by this try/catch block. If no exception has * Returns the exception caught by this try/catch block. If no exception has
* been caught an empty handle is returned. * been caught an empty handle is returned.
Expand Down Expand Up @@ -2337,6 +2399,7 @@ class V8EXPORT TryCatch {
void* exception_; void* exception_;
void* message_; void* message_;
bool is_verbose_; bool is_verbose_;
bool can_continue_;
bool capture_message_; bool capture_message_;
void* js_handler_; void* js_handler_;
}; };
Expand Down
45 changes: 43 additions & 2 deletions deps/v8/src/api.cc
Expand Up @@ -75,7 +75,7 @@ namespace v8 {
i::V8::FatalProcessOutOfMemory(NULL); \ i::V8::FatalProcessOutOfMemory(NULL); \
} \ } \
bool call_depth_is_zero = thread_local.CallDepthIsZero(); \ bool call_depth_is_zero = thread_local.CallDepthIsZero(); \
i::Top::optional_reschedule_exception(call_depth_is_zero); \ i::Top::OptionalRescheduleException(call_depth_is_zero, false); \
return value; \ return value; \
} \ } \
} while (false) } while (false)
Expand Down Expand Up @@ -1208,6 +1208,11 @@ bool v8::TryCatch::HasCaught() const {
} }




bool v8::TryCatch::CanContinue() const {
return can_continue_;
}


v8::Local<Value> v8::TryCatch::Exception() const { v8::Local<Value> v8::TryCatch::Exception() const {
if (HasCaught()) { if (HasCaught()) {
// Check for out of memory exception. // Check for out of memory exception.
Expand Down Expand Up @@ -2599,10 +2604,18 @@ bool v8::V8::Dispose() {
} }




void v8::V8::IdleNotification(bool is_high_priority) { void v8::V8::IdleNotification(bool is_high_priority) {
i::V8::IdleNotification(is_high_priority); i::V8::IdleNotification(is_high_priority);
} }



void v8::V8::LowMemoryNotification() {
#if defined(ANDROID)
i::Heap::CollectAllGarbage(true);
#endif
}


const char* v8::V8::GetVersion() { const char* v8::V8::GetVersion() {
static v8::internal::EmbeddedVector<char, 128> buffer; static v8::internal::EmbeddedVector<char, 128> buffer;
v8::internal::Version::GetString(buffer); v8::internal::Version::GetString(buffer);
Expand Down Expand Up @@ -3354,6 +3367,34 @@ int V8::GetLogLines(int from_pos, char* dest_buf, int max_size) {
return 0; return 0;
} }



int V8::GetCurrentThreadId() {
API_ENTRY_CHECK("V8::GetCurrentThreadId()");
EnsureInitialized("V8::GetCurrentThreadId()");
return i::Top::thread_id();
}


void V8::TerminateExecution(int thread_id) {
if (!i::V8::IsRunning()) return;
API_ENTRY_CHECK("V8::GetCurrentThreadId()");
// If the thread_id identifies the current thread just terminate
// execution right away. Otherwise, ask the thread manager to
// terminate the thread with the given id if any.
if (thread_id == i::Top::thread_id()) {
i::StackGuard::TerminateExecution();
} else {
i::ThreadManager::TerminateExecution(thread_id);
}
}


void V8::TerminateExecution() {
if (!i::V8::IsRunning()) return;
i::StackGuard::TerminateExecution();
}


String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj) { String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj) {
EnsureInitialized("v8::String::Utf8Value::Utf8Value()"); EnsureInitialized("v8::String::Utf8Value::Utf8Value()");
if (obj.IsEmpty()) { if (obj.IsEmpty()) {
Expand Down
64 changes: 37 additions & 27 deletions deps/v8/src/arm/codegen-arm.cc
Expand Up @@ -5701,7 +5701,8 @@ void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
} }




void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) { void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm,
UncatchableExceptionType type) {
// Adjust this code if not the case. // Adjust this code if not the case.
ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);


Expand All @@ -5725,20 +5726,22 @@ void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) {


// Set the top handler address to next handler past the current ENTRY handler. // Set the top handler address to next handler past the current ENTRY handler.
ASSERT(StackHandlerConstants::kNextOffset == 0); ASSERT(StackHandlerConstants::kNextOffset == 0);
__ pop(r0); __ pop(r2);
__ str(r0, MemOperand(r3)); __ str(r2, MemOperand(r3));

// Set external caught exception to false.
ExternalReference external_caught(Top::k_external_caught_exception_address);
__ mov(r0, Operand(false));
__ mov(r2, Operand(external_caught));
__ str(r0, MemOperand(r2));


// Set pending exception and r0 to out of memory exception. if (type == OUT_OF_MEMORY) {
Failure* out_of_memory = Failure::OutOfMemoryException(); // Set external caught exception to false.
__ mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory))); ExternalReference external_caught(Top::k_external_caught_exception_address);
__ mov(r2, Operand(ExternalReference(Top::k_pending_exception_address))); __ mov(r0, Operand(false));
__ str(r0, MemOperand(r2)); __ mov(r2, Operand(external_caught));
__ str(r0, MemOperand(r2));

// Set pending exception and r0 to out of memory exception.
Failure* out_of_memory = Failure::OutOfMemoryException();
__ mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
__ mov(r2, Operand(ExternalReference(Top::k_pending_exception_address)));
__ str(r0, MemOperand(r2));
}


// Stack layout at this point. See also StackHandlerConstants. // Stack layout at this point. See also StackHandlerConstants.
// sp -> state (ENTRY) // sp -> state (ENTRY)
Expand Down Expand Up @@ -5768,6 +5771,7 @@ void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) {


void CEntryStub::GenerateCore(MacroAssembler* masm, void CEntryStub::GenerateCore(MacroAssembler* masm,
Label* throw_normal_exception, Label* throw_normal_exception,
Label* throw_termination_exception,
Label* throw_out_of_memory_exception, Label* throw_out_of_memory_exception,
StackFrame::Type frame_type, StackFrame::Type frame_type,
bool do_gc, bool do_gc,
Expand Down Expand Up @@ -5838,10 +5842,10 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
__ tst(r0, Operand(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); __ tst(r0, Operand(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize));
__ b(eq, &retry); __ b(eq, &retry);


Label continue_exception; // Special handling of out of memory exceptions.
// If the returned failure is EXCEPTION then promote Top::pending_exception(). Failure* out_of_memory = Failure::OutOfMemoryException();
__ cmp(r0, Operand(reinterpret_cast<int32_t>(Failure::Exception()))); __ cmp(r0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
__ b(ne, &continue_exception); __ b(eq, throw_out_of_memory_exception);


// Retrieve the pending exception and clear the variable. // Retrieve the pending exception and clear the variable.
__ mov(ip, Operand(ExternalReference::the_hole_value_location())); __ mov(ip, Operand(ExternalReference::the_hole_value_location()));
Expand All @@ -5850,11 +5854,10 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
__ ldr(r0, MemOperand(ip)); __ ldr(r0, MemOperand(ip));
__ str(r3, MemOperand(ip)); __ str(r3, MemOperand(ip));


__ bind(&continue_exception); // Special handling of termination exceptions which are uncatchable
// Special handling of out of memory exception. // by javascript code.
Failure* out_of_memory = Failure::OutOfMemoryException(); __ cmp(r0, Operand(Factory::termination_exception()));
__ cmp(r0, Operand(reinterpret_cast<int32_t>(out_of_memory))); __ b(eq, throw_termination_exception);
__ b(eq, throw_out_of_memory_exception);


// Handle normal exception. // Handle normal exception.
__ jmp(throw_normal_exception); __ jmp(throw_normal_exception);
Expand Down Expand Up @@ -5887,11 +5890,14 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
// r5: pointer to builtin function (C callee-saved) // r5: pointer to builtin function (C callee-saved)
// r6: pointer to first argument (C callee-saved) // r6: pointer to first argument (C callee-saved)


Label throw_out_of_memory_exception;
Label throw_normal_exception; Label throw_normal_exception;
Label throw_termination_exception;
Label throw_out_of_memory_exception;


// Call into the runtime system. // Call into the runtime system.
GenerateCore(masm, &throw_normal_exception, GenerateCore(masm,
&throw_normal_exception,
&throw_termination_exception,
&throw_out_of_memory_exception, &throw_out_of_memory_exception,
frame_type, frame_type,
false, false,
Expand All @@ -5900,6 +5906,7 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
// Do space-specific GC and retry runtime call. // Do space-specific GC and retry runtime call.
GenerateCore(masm, GenerateCore(masm,
&throw_normal_exception, &throw_normal_exception,
&throw_termination_exception,
&throw_out_of_memory_exception, &throw_out_of_memory_exception,
frame_type, frame_type,
true, true,
Expand All @@ -5910,14 +5917,17 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
__ mov(r0, Operand(reinterpret_cast<int32_t>(failure))); __ mov(r0, Operand(reinterpret_cast<int32_t>(failure)));
GenerateCore(masm, GenerateCore(masm,
&throw_normal_exception, &throw_normal_exception,
&throw_termination_exception,
&throw_out_of_memory_exception, &throw_out_of_memory_exception,
frame_type, frame_type,
true, true,
true); true);


__ bind(&throw_out_of_memory_exception); __ bind(&throw_out_of_memory_exception);
GenerateThrowOutOfMemory(masm); GenerateThrowUncatchable(masm, OUT_OF_MEMORY);
// control flow for generated will not return.
__ bind(&throw_termination_exception);
GenerateThrowUncatchable(masm, TERMINATION);


__ bind(&throw_normal_exception); __ bind(&throw_normal_exception);
GenerateThrowTOS(masm); GenerateThrowTOS(masm);
Expand Down
7 changes: 6 additions & 1 deletion deps/v8/src/codegen.h
Expand Up @@ -70,6 +70,9 @@
// Mode to overwrite BinaryExpression values. // Mode to overwrite BinaryExpression values.
enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT }; enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };


// Types of uncatchable exceptions.
enum UncatchableExceptionType { OUT_OF_MEMORY, TERMINATION };



#if V8_TARGET_ARCH_IA32 #if V8_TARGET_ARCH_IA32
#include "ia32/codegen-ia32.h" #include "ia32/codegen-ia32.h"
Expand Down Expand Up @@ -291,12 +294,14 @@ class CEntryStub : public CodeStub {
void GenerateBody(MacroAssembler* masm, bool is_debug_break); void GenerateBody(MacroAssembler* masm, bool is_debug_break);
void GenerateCore(MacroAssembler* masm, void GenerateCore(MacroAssembler* masm,
Label* throw_normal_exception, Label* throw_normal_exception,
Label* throw_termination_exception,
Label* throw_out_of_memory_exception, Label* throw_out_of_memory_exception,
StackFrame::Type frame_type, StackFrame::Type frame_type,
bool do_gc, bool do_gc,
bool always_allocate_scope); bool always_allocate_scope);
void GenerateThrowTOS(MacroAssembler* masm); void GenerateThrowTOS(MacroAssembler* masm);
void GenerateThrowOutOfMemory(MacroAssembler* masm); void GenerateThrowUncatchable(MacroAssembler* masm,
UncatchableExceptionType type);


private: private:
Major MajorKey() { return CEntry; } Major MajorKey() { return CEntry; }
Expand Down
20 changes: 19 additions & 1 deletion deps/v8/src/execution.cc
Expand Up @@ -156,7 +156,8 @@ Handle<Object> Execution::TryCall(Handle<JSFunction> func,
ASSERT(catcher.HasCaught()); ASSERT(catcher.HasCaught());
ASSERT(Top::has_pending_exception()); ASSERT(Top::has_pending_exception());
ASSERT(Top::external_caught_exception()); ASSERT(Top::external_caught_exception());
Top::optional_reschedule_exception(true); bool is_bottom_call = HandleScopeImplementer::instance()->CallDepthIsZero();
Top::OptionalRescheduleException(is_bottom_call, true);
result = v8::Utils::OpenHandle(*catcher.Exception()); result = v8::Utils::OpenHandle(*catcher.Exception());
} }


Expand Down Expand Up @@ -328,6 +329,19 @@ void StackGuard::Preempt() {
} }




bool StackGuard::IsTerminateExecution() {
ExecutionAccess access;
return thread_local_.interrupt_flags_ & TERMINATE;
}


void StackGuard::TerminateExecution() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= TERMINATE;
set_limits(kInterruptLimit, access);
}


#ifdef ENABLE_DEBUGGER_SUPPORT #ifdef ENABLE_DEBUGGER_SUPPORT
bool StackGuard::IsDebugBreak() { bool StackGuard::IsDebugBreak() {
ExecutionAccess access; ExecutionAccess access;
Expand Down Expand Up @@ -638,6 +652,10 @@ Object* Execution::HandleStackGuardInterrupt() {
} }
#endif #endif
if (StackGuard::IsPreempted()) RuntimePreempt(); if (StackGuard::IsPreempted()) RuntimePreempt();
if (StackGuard::IsTerminateExecution()) {
StackGuard::Continue(TERMINATE);
return Top::TerminateExecution();
}
if (StackGuard::IsInterrupted()) { if (StackGuard::IsInterrupted()) {
// interrupt // interrupt
StackGuard::Continue(INTERRUPT); StackGuard::Continue(INTERRUPT);
Expand Down

0 comments on commit 048a1b8

Please sign in to comment.