46 StackGuard::StackGuard()
 
   51 void StackGuard::set_interrupt_limits(
const ExecutionAccess& lock) {
 
   54   if (should_postpone_interrupts(lock)) 
return;
 
   55   thread_local_.jslimit_ = kInterruptLimit;
 
   56   thread_local_.climit_ = kInterruptLimit;
 
   61 void StackGuard::reset_limits(
const ExecutionAccess& lock) {
 
   63   thread_local_.jslimit_ = thread_local_.real_jslimit_;
 
   64   thread_local_.climit_ = thread_local_.real_climit_;
 
   69 static Handle<Object> Invoke(
bool is_construct,
 
   70                              Handle<JSFunction> 
function,
 
   71                              Handle<Object> receiver,
 
   73                              Handle<Object> args[],
 
   74                              bool* has_pending_exception) {
 
   75   Isolate* isolate = 
function->GetIsolate();
 
   78   VMState state(isolate, JS);
 
   83   typedef Object* (*JSEntryFunction)(
byte* entry,
 
   89   Handle<Code> code = is_construct
 
   90       ? isolate->factory()->js_construct_entry_code()
 
   91       : isolate->factory()->js_entry_code();
 
   96   if (receiver->IsGlobalObject()) {
 
   98     receiver = Handle<JSObject>(global->global_receiver());
 
  103   ASSERT(function->context()->global()->IsGlobalObject());
 
  108     SaveContext save(isolate);
 
  109     NoHandleAllocation na;
 
  110     JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
 
  113     byte* function_entry = 
function->code()->entry();
 
  114     JSFunction* func = *
function;
 
  115     Object* recv = *receiver;
 
  116     Object*** argv = 
reinterpret_cast<Object***
>(args);
 
  126   *has_pending_exception = value->IsException();
 
  127   ASSERT(*has_pending_exception == Isolate::Current()->has_pending_exception());
 
  128   if (*has_pending_exception) {
 
  129     isolate->ReportPendingMessages();
 
  131       if (!isolate->ignore_out_of_memory()) {
 
  135     return Handle<Object>();
 
  137     isolate->clear_pending_message();
 
  140   return Handle<Object>(value->ToObjectUnchecked(), isolate);
 
  148                                bool* pending_exception,
 
  149                                bool convert_receiver) {
 
  150   *pending_exception = 
false;
 
  152   if (!callable->IsJSFunction()) {
 
  154     if (*pending_exception) 
return callable;
 
  159   if (convert_receiver && !receiver->IsJSReceiver() &&
 
  160       !func->shared()->native() && func->shared()->is_classic_mode()) {
 
  161     if (receiver->IsUndefined() || receiver->IsNull()) {
 
  162       Object* global = func->context()->global()->global_receiver();
 
  166       if (!global->IsJSBuiltinsObject()) receiver = 
Handle<Object>(global);
 
  168       receiver = 
ToObject(receiver, pending_exception);
 
  170     if (*pending_exception) 
return callable;
 
  173   return Invoke(
false, func, receiver, argc, argv, pending_exception);
 
  180                               bool* pending_exception) {
 
  181   return Invoke(
true, func, Isolate::Current()->global(), argc, argv,
 
  190                                   bool* caught_exception) {
 
  198   *caught_exception = 
false;
 
  203   if (*caught_exception) {
 
  205     Isolate* isolate = Isolate::Current();
 
  206     ASSERT(isolate->has_pending_exception());
 
  207     ASSERT(isolate->external_caught_exception());
 
  208     if (isolate->pending_exception() ==
 
  209         isolate->heap()->termination_exception()) {
 
  210       result = isolate->factory()->termination_exception();
 
  214     isolate->OptionalRescheduleException(
true);
 
  217   ASSERT(!Isolate::Current()->has_pending_exception());
 
  218   ASSERT(!Isolate::Current()->external_caught_exception());
 
  224   ASSERT(!object->IsJSFunction());
 
  225   Isolate* isolate = Isolate::Current();
 
  226   Factory* factory = isolate->factory();
 
  232   Object* fun = *object;
 
  233   while (fun->IsJSFunctionProxy()) {
 
  240   if (fun->IsHeapObject() &&
 
  243         isolate->global_context()->call_as_function_delegate());
 
  246   return factory->undefined_value();
 
  251                                                  bool* has_pending_exception) {
 
  252   ASSERT(!object->IsJSFunction());
 
  253   Isolate* isolate = Isolate::Current();
 
  256   Object* fun = *object;
 
  257   while (fun->IsJSFunctionProxy()) {
 
  264   if (fun->IsHeapObject() &&
 
  267         isolate->global_context()->call_as_function_delegate());
 
  273       "called_non_callable", i::HandleVector<i::Object>(&
object, 1));
 
  274   isolate->Throw(*error_obj);
 
  275   *has_pending_exception = 
true;
 
  277   return isolate->factory()->undefined_value();
 
  282   ASSERT(!object->IsJSFunction());
 
  283   Isolate* isolate = Isolate::Current();
 
  289   Object* fun = *object;
 
  290   while (fun->IsJSFunctionProxy()) {
 
  297   if (fun->IsHeapObject() &&
 
  300         isolate->global_context()->call_as_constructor_delegate());
 
  303   return isolate->factory()->undefined_value();
 
  309     bool* has_pending_exception) {
 
  310   ASSERT(!object->IsJSFunction());
 
  311   Isolate* isolate = Isolate::Current();
 
  317   Object* fun = *object;
 
  318   while (fun->IsJSFunctionProxy()) {
 
  325   if (fun->IsHeapObject() &&
 
  328         isolate->global_context()->call_as_constructor_delegate());
 
  334       "called_non_callable", i::HandleVector<i::Object>(&
object, 1));
 
  335   isolate->Throw(*error_obj);
 
  336   *has_pending_exception = 
true;
 
  338   return isolate->factory()->undefined_value();
 
  343   ExecutionAccess access(isolate_);
 
  344   return (thread_local_.jslimit_ != kInterruptLimit &&
 
  345           thread_local_.climit_ != kInterruptLimit);
 
  349 void StackGuard::EnableInterrupts() {
 
  350   ExecutionAccess access(isolate_);
 
  351   if (has_pending_interrupts(access)) {
 
  352     set_interrupt_limits(access);
 
  358   ExecutionAccess access(isolate_);
 
  362   if (thread_local_.jslimit_ == thread_local_.real_jslimit_) {
 
  363     thread_local_.jslimit_ = 
jslimit;
 
  365   if (thread_local_.climit_ == thread_local_.real_climit_) {
 
  366     thread_local_.climit_ = limit;
 
  368   thread_local_.real_climit_ = limit;
 
  369   thread_local_.real_jslimit_ = 
jslimit;
 
  373 void StackGuard::DisableInterrupts() {
 
  374   ExecutionAccess access(isolate_);
 
  375   reset_limits(access);
 
  380   ExecutionAccess access(isolate_);
 
  381   return should_postpone_interrupts(access);
 
  386   ExecutionAccess access(isolate_);
 
  387   return (thread_local_.interrupt_flags_ & 
INTERRUPT) != 0;
 
  392   ExecutionAccess access(isolate_);
 
  393   thread_local_.interrupt_flags_ |= 
INTERRUPT;
 
  394   set_interrupt_limits(access);
 
  399   ExecutionAccess access(isolate_);
 
  400   return thread_local_.interrupt_flags_ & 
PREEMPT;
 
  405   ExecutionAccess access(isolate_);
 
  406   thread_local_.interrupt_flags_ |= 
PREEMPT;
 
  407   set_interrupt_limits(access);
 
  412   ExecutionAccess access(isolate_);
 
  413   return (thread_local_.interrupt_flags_ & 
TERMINATE) != 0;
 
  418   ExecutionAccess access(isolate_);
 
  419   thread_local_.interrupt_flags_ |= 
TERMINATE;
 
  420   set_interrupt_limits(access);
 
  425   ExecutionAccess access(isolate_);
 
  432   if (FLAG_opt && ExecutionAccess::TryLock(isolate_)) {
 
  434     if (thread_local_.postpone_interrupts_nesting_ == 0) {
 
  435       thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
 
  438     ExecutionAccess::Unlock(isolate_);
 
  444   ExecutionAccess access(isolate_);
 
  445   return (thread_local_.interrupt_flags_ & 
GC_REQUEST) != 0;
 
  450   ExecutionAccess access(isolate_);
 
  452   if (thread_local_.postpone_interrupts_nesting_ == 0) {
 
  453     thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
 
  459 #ifdef ENABLE_DEBUGGER_SUPPORT 
  460 bool StackGuard::IsDebugBreak() {
 
  461   ExecutionAccess access(isolate_);
 
  462   return thread_local_.interrupt_flags_ & 
DEBUGBREAK;
 
  466 void StackGuard::DebugBreak() {
 
  467   ExecutionAccess access(isolate_);
 
  469   set_interrupt_limits(access);
 
  473 bool StackGuard::IsDebugCommand() {
 
  474   ExecutionAccess access(isolate_);
 
  479 void StackGuard::DebugCommand() {
 
  480   if (FLAG_debugger_auto_break) {
 
  481     ExecutionAccess access(isolate_);
 
  483     set_interrupt_limits(access);
 
  489   ExecutionAccess access(isolate_);
 
  490   thread_local_.interrupt_flags_ &= ~static_cast<
int>(after_what);
 
  491   if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
 
  492     reset_limits(access);
 
  498   ExecutionAccess access(isolate_);
 
  499   memcpy(to, reinterpret_cast<char*>(&thread_local_), 
sizeof(ThreadLocal));
 
  508   thread_local_ = blank;
 
  510   return to + 
sizeof(ThreadLocal);
 
  515   ExecutionAccess access(isolate_);
 
  516   memcpy(reinterpret_cast<char*>(&thread_local_), from, 
sizeof(ThreadLocal));
 
  518   return from + 
sizeof(ThreadLocal);
 
  524       isolate_->FindOrAllocatePerThreadDataForThisThread();
 
  529 void StackGuard::ThreadLocal::Clear() {
 
  530   real_jslimit_ = kIllegalLimit;
 
  531   jslimit_ = kIllegalLimit;
 
  532   real_climit_ = kIllegalLimit;
 
  533   climit_ = kIllegalLimit;
 
  535   postpone_interrupts_nesting_ = 0;
 
  536   interrupt_flags_ = 0;
 
  540 bool StackGuard::ThreadLocal::Initialize(
Isolate* isolate) {
 
  541   bool should_set_stack_limits = 
false;
 
  542   if (real_climit_ == kIllegalLimit) {
 
  545     const uintptr_t kLimitSize = FLAG_stack_size * 
KB;
 
  546     uintptr_t limit = 
reinterpret_cast<uintptr_t
>(&limit) - kLimitSize;
 
  547     ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize);
 
  550     real_climit_ = limit;
 
  552     should_set_stack_limits = 
true;
 
  555   postpone_interrupts_nesting_ = 0;
 
  556   interrupt_flags_ = 0;
 
  557   return should_set_stack_limits;
 
  562   thread_local_.Clear();
 
  570       isolate_->FindOrAllocatePerThreadDataForThisThread();
 
  571   uintptr_t stored_limit = per_thread->
stack_limit();
 
  573   if (stored_limit != 0) {
 
  581 #define RETURN_NATIVE_CALL(name, args, has_pending_exception)           \ 
  583     Isolate* isolate = Isolate::Current();                              \ 
  584     Handle<Object> argv[] = args;                                       \ 
  585     ASSERT(has_pending_exception != NULL);                              \ 
  586     return Call(isolate->name##_fun(),                                  \ 
  587                 isolate->js_builtins_object(),                          \ 
  588                 ARRAY_SIZE(argv), argv,                                 \ 
  589                 has_pending_exception);                                 \ 
  595   if (obj->IsBoolean()) 
return obj;
 
  597   if (obj->IsString()) {
 
  599   } 
else if (obj->IsNull() || obj->IsUndefined()) {
 
  601   } 
else if (obj->IsNumber()) {
 
  602     double value = obj->Number();
 
  603     result = !((value == 0) || 
isnan(value));
 
  625   if (obj->IsSpecObject()) 
return obj;
 
  651 #undef RETURN_NATIVE_CALL 
  658       pattern->GetIsolate()->global_context()->regexp_function());
 
  660       function, pattern, flags, exc);
 
  667   Isolate* isolate = 
string->GetIsolate();
 
  670   int int_index = 
static_cast<int>(index);
 
  671   if (int_index < 0 || int_index >= string->length()) {
 
  672     return factory->undefined_value();
 
  677                   factory->char_at_symbol());
 
  678   if (!char_at->IsJSFunction()) {
 
  679     return factory->undefined_value();
 
  682   bool caught_exception;
 
  690   if (caught_exception) {
 
  691     return factory->undefined_value();
 
  700   Isolate* isolate = data->GetIsolate();
 
  702   int serial_number = 
Smi::cast(data->serial_number())->value();
 
  705           GetElementNoExceptionThrown(serial_number);
 
  721   Isolate* isolate = data->GetIsolate();
 
  722   if (data->property_list()->IsUndefined() &&
 
  723       !data->constructor()->IsUndefined()) {
 
  725     Object* result = 
NULL;
 
  755   Isolate* isolate = Isolate::Current();
 
  769   Isolate* isolate = fun->GetIsolate();
 
  771   bool caught_exception;
 
  777   if (caught_exception || !result->IsString()) {
 
  778       return isolate->
factory()->empty_symbol();
 
  785 static Object* RuntimePreempt() {
 
  786   Isolate* isolate = Isolate::Current();
 
  793 #ifdef ENABLE_DEBUGGER_SUPPORT 
  794   if (isolate->debug()->InDebugger()) {
 
  797     isolate->debug()->PreemptionWhileInDebugger();
 
  800     v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
 
  806     v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
 
  811   return isolate->
heap()->undefined_value();
 
  815 #ifdef ENABLE_DEBUGGER_SUPPORT 
  816 Object* Execution::DebugBreakHelper() {
 
  817   Isolate* isolate = Isolate::Current();
 
  820   if (isolate->debug()->disable_break()) {
 
  821     return isolate->heap()->undefined_value();
 
  825   if (isolate->bootstrapper()->IsActive()) {
 
  826     return isolate->heap()->undefined_value();
 
  829   StackLimitCheck 
check(isolate);
 
  830   if (
check.HasOverflowed()) {
 
  831     return isolate->heap()->undefined_value();
 
  837     Object* fun = it.frame()->function();
 
  838     if (fun && fun->IsJSFunction()) {
 
  841         return isolate->heap()->undefined_value();
 
  845       if (isolate->debug()->IsDebugGlobal(global)) {
 
  846         return isolate->heap()->undefined_value();
 
  852   bool debug_command_only =
 
  853       isolate->stack_guard()->IsDebugCommand() &&
 
  854       !isolate->stack_guard()->IsDebugBreak();
 
  859   ProcessDebugMessages(debug_command_only);
 
  862   return isolate->heap()->undefined_value();
 
  865 void Execution::ProcessDebugMessages(
bool debug_command_only) {
 
  866   Isolate* isolate = Isolate::Current();
 
  870   StackLimitCheck 
check(isolate);
 
  871   if (
check.HasOverflowed()) {
 
  875   HandleScope scope(isolate);
 
  877   EnterDebugger debugger;
 
  878   if (debugger.FailedToEnter()) {
 
  884   isolate->debugger()->OnDebugBreak(isolate->factory()->undefined_value(),
 
  894     return isolate->
heap()->undefined_value();
 
  899                                        "StackGuard GC request");
 
  903   isolate->
counters()->stack_interrupts()->Increment();
 
  905   if (FLAG_count_based_interrupts ||
 
  907     isolate->
counters()->runtime_profiler_ticks()->Increment();
 
  911 #ifdef ENABLE_DEBUGGER_SUPPORT 
  912   if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) {
 
  925   return isolate->
heap()->undefined_value();
 
static Handle< Object > New(Handle< JSFunction > func, int argc, Handle< Object > argv[], bool *pending_exception)
Failure * StackOverflow()
static Handle< Object > TryCall(Handle< JSFunction > func, Handle< Object > receiver, int argc, Handle< Object > argv[], bool *caught_exception)
static Handle< Object > ToUint32(Handle< Object > obj, bool *exc)
Local< Value > Exception() const 
bool IsRuntimeProfilerTick()
void SetCaptureMessage(bool value)
void CollectAllGarbage(int flags, const char *gc_reason=NULL)
static HeapObject * cast(Object *obj)
static Handle< T > cast(Handle< S > that)
static Failure * OutOfMemoryException()
static Handle< Object > CreateRegExpLiteral(Handle< JSFunction > constructor, Handle< String > pattern, Handle< String > flags, bool *has_pending_exception)
static Handle< Object > ToInteger(Handle< Object > obj, bool *exc)
static Handle< Object > GetConstructorDelegate(Handle< Object > object)
static Handle< Object > ToObject(Handle< Object > obj, bool *exc)
static Handle< Object > ToInt32(Handle< Object > obj, bool *exc)
#define ASSERT(condition)
static void ConfigureInstance(Handle< Object > instance, Handle< Object > data, bool *exc)
kPropertyAccessorsOffset kNamedPropertyHandlerOffset instance_template
static Handle< Object > ToDetailString(Handle< Object > obj, bool *exc)
void SetVerbose(bool value)
Handle< Object > GetProperty(Handle< JSReceiver > obj, const char *name)
static Smi * cast(Object *object)
StackGuard * stack_guard()
Handle< Context > global_context()
bool has_instance_call_handler()
static JSFunctionProxy * cast(Object *obj)
void RequestRuntimeProfilerTick()
static Handle< Object > CharAt(Handle< String > str, uint32_t index)
static Handle< Object > ToBoolean(Handle< Object > obj)
char * RestoreStackGuard(char *from)
void ClearThread(const ExecutionAccess &lock)
RuntimeProfiler * runtime_profiler()
static void PreemptionReceived()
char * ArchiveStackGuard(char *to)
static MUST_USE_RESULT MaybeObject * HandleStackGuardInterrupt(Isolate *isolate)
bool IsTerminateExecution()
static const int kNoGCFlags
void TerminateExecution()
static uintptr_t JsLimitFromCLimit(v8::internal::Isolate *isolate, uintptr_t c_limit)
static FunctionTemplateInfo * cast(Object *obj)
static Handle< JSRegExp > NewJSRegExp(Handle< String > pattern, Handle< String > flags, bool *exc)
#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4)
static Handle< Object > NewDate(double time, bool *exc)
Handle< JSBuiltinsObject > js_builtins_object()
static Handle< Object > Call(Handle< Object > callable, Handle< Object > receiver, int argc, Handle< Object > argv[], bool *pending_exception, bool convert_receiver=false)
Handle< Object > NewNumberFromInt(int32_t value, PretenureFlag pretenure=NOT_TENURED)
static Handle< JSFunction > InstantiateFunction(Handle< FunctionTemplateInfo > data, bool *exc)
bool ShouldPostponeInterrupts()
void Continue(InterruptFlag after_what)
JavaScriptFrameIteratorTemp< StackFrameIterator > JavaScriptFrameIterator
static Handle< Object > GetFunctionDelegate(Handle< Object > object)
void set_stack_limit(uintptr_t value)
static Handle< T > null()
#define RETURN_NATIVE_CALL(name, args, has_pending_exception)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
static Handle< Object > ToNumber(Handle< Object > obj, bool *exc)
static Handle< JSObject > InstantiateObject(Handle< ObjectTemplateInfo > data, bool *exc)
Failure * TerminateExecution()
static Handle< String > GetStackTraceLine(Handle< Object > recv, Handle< JSFunction > fun, Handle< Object > pos, Handle< Object > is_global)
static Handle< Object > ToString(Handle< Object > obj, bool *exc)
void FreeThreadResources()
static Handle< Object > TryGetConstructorDelegate(Handle< Object > object, bool *has_pending_exception)
void SetStackLimit(uintptr_t limit)
uintptr_t stack_limit() const 
void check(i::Vector< const char > string)
static void FatalProcessOutOfMemory(const char *location, bool take_snapshot=false)
static Handle< Object > TryGetFunctionDelegate(Handle< Object > object, bool *has_pending_exception)
static JSObject * cast(Object *obj)
void InitThread(const ExecutionAccess &lock)
static v8::internal::Handle< v8::internal::TemplateInfo > OpenHandle(const Template *that)
static JSFunction * cast(Object *obj)