v8  3.14.5(node0.10.28)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
execution.cc
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include <stdlib.h>
29 
30 #include "v8.h"
31 
32 #include "api.h"
33 #include "bootstrapper.h"
34 #include "codegen.h"
35 #include "debug.h"
36 #include "isolate-inl.h"
37 #include "runtime-profiler.h"
38 #include "simulator.h"
39 #include "v8threads.h"
40 #include "vm-state-inl.h"
41 
42 namespace v8 {
43 namespace internal {
44 
45 
46 StackGuard::StackGuard()
47  : isolate_(NULL) {
48 }
49 
50 
51 void StackGuard::set_interrupt_limits(const ExecutionAccess& lock) {
52  ASSERT(isolate_ != NULL);
53  // Ignore attempts to interrupt when interrupts are postponed.
54  if (should_postpone_interrupts(lock)) return;
55  thread_local_.jslimit_ = kInterruptLimit;
56  thread_local_.climit_ = kInterruptLimit;
57  isolate_->heap()->SetStackLimits();
58 }
59 
60 
61 void StackGuard::reset_limits(const ExecutionAccess& lock) {
62  ASSERT(isolate_ != NULL);
63  thread_local_.jslimit_ = thread_local_.real_jslimit_;
64  thread_local_.climit_ = thread_local_.real_climit_;
65  isolate_->heap()->SetStackLimits();
66 }
67 
68 
69 static Handle<Object> Invoke(bool is_construct,
70  Handle<JSFunction> function,
71  Handle<Object> receiver,
72  int argc,
73  Handle<Object> args[],
74  bool* has_pending_exception) {
75  Isolate* isolate = function->GetIsolate();
76 
77  // Entering JavaScript.
78  VMState state(isolate, JS);
79 
80  // Placeholder for return value.
81  MaybeObject* value = reinterpret_cast<Object*>(kZapValue);
82 
83  typedef Object* (*JSEntryFunction)(byte* entry,
84  Object* function,
85  Object* receiver,
86  int argc,
87  Object*** args);
88 
89  Handle<Code> code = is_construct
90  ? isolate->factory()->js_construct_entry_code()
91  : isolate->factory()->js_entry_code();
92 
93  // Convert calls on global objects to be calls on the global
94  // receiver instead to avoid having a 'this' pointer which refers
95  // directly to a global object.
96  if (receiver->IsGlobalObject()) {
97  Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
98  receiver = Handle<JSObject>(global->global_receiver());
99  }
100 
101  // Make sure that the global object of the context we're about to
102  // make the current one is indeed a global object.
103  ASSERT(function->context()->global_object()->IsGlobalObject());
104 
105  {
106  // Save and restore context around invocation and block the
107  // allocation of handles without explicit handle scopes.
108  SaveContext save(isolate);
109  NoHandleAllocation na;
110  JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
111 
112  // Call the function through the right JS entry stub.
113  byte* function_entry = function->code()->entry();
114  JSFunction* func = *function;
115  Object* recv = *receiver;
116  Object*** argv = reinterpret_cast<Object***>(args);
117  value =
118  CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
119  }
120 
121 #ifdef VERIFY_HEAP
122  value->Verify();
123 #endif
124 
125  // Update the pending exception flag and return the value.
126  *has_pending_exception = value->IsException();
127  ASSERT(*has_pending_exception == Isolate::Current()->has_pending_exception());
128  if (*has_pending_exception) {
129  isolate->ReportPendingMessages();
130  if (isolate->pending_exception() == Failure::OutOfMemoryException()) {
131  if (!isolate->ignore_out_of_memory()) {
132  V8::FatalProcessOutOfMemory("JS", true);
133  }
134  }
135 #ifdef ENABLE_DEBUGGER_SUPPORT
136  // Reset stepping state when script exits with uncaught exception.
137  if (isolate->debugger()->IsDebuggerActive()) {
138  isolate->debug()->ClearStepping();
139  }
140 #endif // ENABLE_DEBUGGER_SUPPORT
141  return Handle<Object>();
142  } else {
143  isolate->clear_pending_message();
144  }
145 
146  return Handle<Object>(value->ToObjectUnchecked(), isolate);
147 }
148 
149 
151  Handle<Object> receiver,
152  int argc,
153  Handle<Object> argv[],
154  bool* pending_exception,
155  bool convert_receiver) {
156  *pending_exception = false;
157 
158  if (!callable->IsJSFunction()) {
159  callable = TryGetFunctionDelegate(callable, pending_exception);
160  if (*pending_exception) return callable;
161  }
163 
164  // In non-strict mode, convert receiver.
165  if (convert_receiver && !receiver->IsJSReceiver() &&
166  !func->shared()->native() && func->shared()->is_classic_mode()) {
167  if (receiver->IsUndefined() || receiver->IsNull()) {
168  Object* global = func->context()->global_object()->global_receiver();
169  // Under some circumstances, 'global' can be the JSBuiltinsObject
170  // In that case, don't rewrite. (FWIW, the same holds for
171  // GetIsolate()->global_object()->global_receiver().)
172  if (!global->IsJSBuiltinsObject()) receiver = Handle<Object>(global);
173  } else {
174  receiver = ToObject(receiver, pending_exception);
175  }
176  if (*pending_exception) return callable;
177  }
178 
179  return Invoke(false, func, receiver, argc, argv, pending_exception);
180 }
181 
182 
184  int argc,
185  Handle<Object> argv[],
186  bool* pending_exception) {
187  return Invoke(true, func, Isolate::Current()->global_object(), argc, argv,
188  pending_exception);
189 }
190 
191 
193  Handle<Object> receiver,
194  int argc,
195  Handle<Object> args[],
196  bool* caught_exception) {
197  // Enter a try-block while executing the JavaScript code. To avoid
198  // duplicate error printing it must be non-verbose. Also, to avoid
199  // creating message objects during stack overflow we shouldn't
200  // capture messages.
201  v8::TryCatch catcher;
202  catcher.SetVerbose(false);
203  catcher.SetCaptureMessage(false);
204  *caught_exception = false;
205 
206  Handle<Object> result = Invoke(false, func, receiver, argc, args,
207  caught_exception);
208 
209  if (*caught_exception) {
210  ASSERT(catcher.HasCaught());
211  Isolate* isolate = Isolate::Current();
212  ASSERT(isolate->has_pending_exception());
213  ASSERT(isolate->external_caught_exception());
214  if (isolate->pending_exception() ==
215  isolate->heap()->termination_exception()) {
216  result = isolate->factory()->termination_exception();
217  } else {
218  result = v8::Utils::OpenHandle(*catcher.Exception());
219  }
220  isolate->OptionalRescheduleException(true);
221  }
222 
223  ASSERT(!Isolate::Current()->has_pending_exception());
224  ASSERT(!Isolate::Current()->external_caught_exception());
225  return result;
226 }
227 
228 
230  ASSERT(!object->IsJSFunction());
231  Isolate* isolate = Isolate::Current();
232  Factory* factory = isolate->factory();
233 
234  // If you return a function from here, it will be called when an
235  // attempt is made to call the given object as a function.
236 
237  // If object is a function proxy, get its handler. Iterate if necessary.
238  Object* fun = *object;
239  while (fun->IsJSFunctionProxy()) {
240  fun = JSFunctionProxy::cast(fun)->call_trap();
241  }
242  if (fun->IsJSFunction()) return Handle<Object>(fun);
243 
244  // Objects created through the API can have an instance-call handler
245  // that should be used when calling the object as a function.
246  if (fun->IsHeapObject() &&
248  return Handle<JSFunction>(
249  isolate->native_context()->call_as_function_delegate());
250  }
251 
252  return factory->undefined_value();
253 }
254 
255 
257  bool* has_pending_exception) {
258  ASSERT(!object->IsJSFunction());
259  Isolate* isolate = Isolate::Current();
260 
261  // If object is a function proxy, get its handler. Iterate if necessary.
262  Object* fun = *object;
263  while (fun->IsJSFunctionProxy()) {
264  fun = JSFunctionProxy::cast(fun)->call_trap();
265  }
266  if (fun->IsJSFunction()) return Handle<Object>(fun);
267 
268  // Objects created through the API can have an instance-call handler
269  // that should be used when calling the object as a function.
270  if (fun->IsHeapObject() &&
272  return Handle<JSFunction>(
273  isolate->native_context()->call_as_function_delegate());
274  }
275 
276  // If the Object doesn't have an instance-call handler we should
277  // throw a non-callable exception.
278  i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
279  "called_non_callable", i::HandleVector<i::Object>(&object, 1));
280  isolate->Throw(*error_obj);
281  *has_pending_exception = true;
282 
283  return isolate->factory()->undefined_value();
284 }
285 
286 
288  ASSERT(!object->IsJSFunction());
289  Isolate* isolate = Isolate::Current();
290 
291  // If you return a function from here, it will be called when an
292  // attempt is made to call the given object as a constructor.
293 
294  // If object is a function proxies, get its handler. Iterate if necessary.
295  Object* fun = *object;
296  while (fun->IsJSFunctionProxy()) {
297  fun = JSFunctionProxy::cast(fun)->call_trap();
298  }
299  if (fun->IsJSFunction()) return Handle<Object>(fun);
300 
301  // Objects created through the API can have an instance-call handler
302  // that should be used when calling the object as a function.
303  if (fun->IsHeapObject() &&
305  return Handle<JSFunction>(
306  isolate->native_context()->call_as_constructor_delegate());
307  }
308 
309  return isolate->factory()->undefined_value();
310 }
311 
312 
314  Handle<Object> object,
315  bool* has_pending_exception) {
316  ASSERT(!object->IsJSFunction());
317  Isolate* isolate = Isolate::Current();
318 
319  // If you return a function from here, it will be called when an
320  // attempt is made to call the given object as a constructor.
321 
322  // If object is a function proxies, get its handler. Iterate if necessary.
323  Object* fun = *object;
324  while (fun->IsJSFunctionProxy()) {
325  fun = JSFunctionProxy::cast(fun)->call_trap();
326  }
327  if (fun->IsJSFunction()) return Handle<Object>(fun);
328 
329  // Objects created through the API can have an instance-call handler
330  // that should be used when calling the object as a function.
331  if (fun->IsHeapObject() &&
333  return Handle<JSFunction>(
334  isolate->native_context()->call_as_constructor_delegate());
335  }
336 
337  // If the Object doesn't have an instance-call handler we should
338  // throw a non-callable exception.
339  i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
340  "called_non_callable", i::HandleVector<i::Object>(&object, 1));
341  isolate->Throw(*error_obj);
342  *has_pending_exception = true;
343 
344  return isolate->factory()->undefined_value();
345 }
346 
347 
349  ExecutionAccess access(isolate_);
350  return (thread_local_.jslimit_ != kInterruptLimit &&
351  thread_local_.climit_ != kInterruptLimit);
352 }
353 
354 
355 void StackGuard::EnableInterrupts() {
356  ExecutionAccess access(isolate_);
357  if (has_pending_interrupts(access)) {
358  set_interrupt_limits(access);
359  }
360 }
361 
362 
363 void StackGuard::SetStackLimit(uintptr_t limit) {
364  ExecutionAccess access(isolate_);
365  // If the current limits are special (e.g. due to a pending interrupt) then
366  // leave them alone.
367  uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit);
368  if (thread_local_.jslimit_ == thread_local_.real_jslimit_) {
369  thread_local_.jslimit_ = jslimit;
370  }
371  if (thread_local_.climit_ == thread_local_.real_climit_) {
372  thread_local_.climit_ = limit;
373  }
374  thread_local_.real_climit_ = limit;
375  thread_local_.real_jslimit_ = jslimit;
376 }
377 
378 
379 void StackGuard::DisableInterrupts() {
380  ExecutionAccess access(isolate_);
381  reset_limits(access);
382 }
383 
384 
386  ExecutionAccess access(isolate_);
387  return should_postpone_interrupts(access);
388 }
389 
390 
392  ExecutionAccess access(isolate_);
393  return (thread_local_.interrupt_flags_ & INTERRUPT) != 0;
394 }
395 
396 
398  ExecutionAccess access(isolate_);
399  thread_local_.interrupt_flags_ |= INTERRUPT;
400  set_interrupt_limits(access);
401 }
402 
403 
405  ExecutionAccess access(isolate_);
406  return thread_local_.interrupt_flags_ & PREEMPT;
407 }
408 
409 
411  ExecutionAccess access(isolate_);
412  thread_local_.interrupt_flags_ |= PREEMPT;
413  set_interrupt_limits(access);
414 }
415 
416 
418  ExecutionAccess access(isolate_);
419  return (thread_local_.interrupt_flags_ & TERMINATE) != 0;
420 }
421 
422 
424  ExecutionAccess access(isolate_);
425  thread_local_.interrupt_flags_ |= TERMINATE;
426  set_interrupt_limits(access);
427 }
428 
429 
431  ExecutionAccess access(isolate_);
432  return (thread_local_.interrupt_flags_ & RUNTIME_PROFILER_TICK) != 0;
433 }
434 
435 
437  // Ignore calls if we're not optimizing or if we can't get the lock.
438  if (FLAG_opt && ExecutionAccess::TryLock(isolate_)) {
439  thread_local_.interrupt_flags_ |= RUNTIME_PROFILER_TICK;
440  if (thread_local_.postpone_interrupts_nesting_ == 0) {
441  thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
442  isolate_->heap()->SetStackLimits();
443  }
444  ExecutionAccess::Unlock(isolate_);
445  }
446 }
447 
448 
450  ASSERT(FLAG_parallel_recompilation);
451  if (ExecutionAccess::TryLock(isolate_)) {
452  thread_local_.interrupt_flags_ |= CODE_READY;
453  if (thread_local_.postpone_interrupts_nesting_ == 0) {
454  thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
455  isolate_->heap()->SetStackLimits();
456  }
457  ExecutionAccess::Unlock(isolate_);
458  }
459 }
460 
461 
463  ExecutionAccess access(isolate_);
464  return (thread_local_.interrupt_flags_ & CODE_READY) != 0;
465 }
466 
467 
469  ExecutionAccess access(isolate_);
470  return (thread_local_.interrupt_flags_ & GC_REQUEST) != 0;
471 }
472 
473 
475  ExecutionAccess access(isolate_);
476  thread_local_.interrupt_flags_ |= GC_REQUEST;
477  if (thread_local_.postpone_interrupts_nesting_ == 0) {
478  thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
479  isolate_->heap()->SetStackLimits();
480  }
481 }
482 
483 
484 #ifdef ENABLE_DEBUGGER_SUPPORT
485 bool StackGuard::IsDebugBreak() {
486  ExecutionAccess access(isolate_);
487  return thread_local_.interrupt_flags_ & DEBUGBREAK;
488 }
489 
490 
491 void StackGuard::DebugBreak() {
492  ExecutionAccess access(isolate_);
493  thread_local_.interrupt_flags_ |= DEBUGBREAK;
494  set_interrupt_limits(access);
495 }
496 
497 
498 bool StackGuard::IsDebugCommand() {
499  ExecutionAccess access(isolate_);
500  return thread_local_.interrupt_flags_ & DEBUGCOMMAND;
501 }
502 
503 
504 void StackGuard::DebugCommand() {
505  if (FLAG_debugger_auto_break) {
506  ExecutionAccess access(isolate_);
507  thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
508  set_interrupt_limits(access);
509  }
510 }
511 #endif
512 
514  ExecutionAccess access(isolate_);
515  thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what);
516  if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
517  reset_limits(access);
518  }
519 }
520 
521 
523  ExecutionAccess access(isolate_);
524  memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
525  ThreadLocal blank;
526 
527  // Set the stack limits using the old thread_local_.
528  // TODO(isolates): This was the old semantics of constructing a ThreadLocal
529  // (as the ctor called SetStackLimits, which looked at the
530  // current thread_local_ from StackGuard)-- but is this
531  // really what was intended?
532  isolate_->heap()->SetStackLimits();
533  thread_local_ = blank;
534 
535  return to + sizeof(ThreadLocal);
536 }
537 
538 
539 char* StackGuard::RestoreStackGuard(char* from) {
540  ExecutionAccess access(isolate_);
541  memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
542  isolate_->heap()->SetStackLimits();
543  return from + sizeof(ThreadLocal);
544 }
545 
546 
548  Isolate::PerIsolateThreadData* per_thread =
549  isolate_->FindOrAllocatePerThreadDataForThisThread();
550  per_thread->set_stack_limit(thread_local_.real_climit_);
551 }
552 
553 
554 void StackGuard::ThreadLocal::Clear() {
555  real_jslimit_ = kIllegalLimit;
556  jslimit_ = kIllegalLimit;
557  real_climit_ = kIllegalLimit;
558  climit_ = kIllegalLimit;
559  nesting_ = 0;
560  postpone_interrupts_nesting_ = 0;
561  interrupt_flags_ = 0;
562 }
563 
564 
565 bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
566  bool should_set_stack_limits = false;
567  if (real_climit_ == kIllegalLimit) {
568  // Takes the address of the limit variable in order to find out where
569  // the top of stack is right now.
570  const uintptr_t kLimitSize = FLAG_stack_size * KB;
571  uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize;
572  ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize);
573  real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
574  jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
575  real_climit_ = limit;
576  climit_ = limit;
577  should_set_stack_limits = true;
578  }
579  nesting_ = 0;
580  postpone_interrupts_nesting_ = 0;
581  interrupt_flags_ = 0;
582  return should_set_stack_limits;
583 }
584 
585 
586 void StackGuard::ClearThread(const ExecutionAccess& lock) {
587  thread_local_.Clear();
588  isolate_->heap()->SetStackLimits();
589 }
590 
591 
592 void StackGuard::InitThread(const ExecutionAccess& lock) {
593  if (thread_local_.Initialize(isolate_)) isolate_->heap()->SetStackLimits();
594  Isolate::PerIsolateThreadData* per_thread =
595  isolate_->FindOrAllocatePerThreadDataForThisThread();
596  uintptr_t stored_limit = per_thread->stack_limit();
597  // You should hold the ExecutionAccess lock when you call this.
598  if (stored_limit != 0) {
599  SetStackLimit(stored_limit);
600  }
601 }
602 
603 
604 // --- C a l l s t o n a t i v e s ---
605 
606 #define RETURN_NATIVE_CALL(name, args, has_pending_exception) \
607  do { \
608  Isolate* isolate = Isolate::Current(); \
609  Handle<Object> argv[] = args; \
610  ASSERT(has_pending_exception != NULL); \
611  return Call(isolate->name##_fun(), \
612  isolate->js_builtins_object(), \
613  ARRAY_SIZE(argv), argv, \
614  has_pending_exception); \
615  } while (false)
616 
617 
619  // See the similar code in runtime.js:ToBoolean.
620  if (obj->IsBoolean()) return obj;
621  bool result = true;
622  if (obj->IsString()) {
623  result = Handle<String>::cast(obj)->length() != 0;
624  } else if (obj->IsNull() || obj->IsUndefined()) {
625  result = false;
626  } else if (obj->IsNumber()) {
627  double value = obj->Number();
628  result = !((value == 0) || isnan(value));
629  }
630  return Handle<Object>(HEAP->ToBoolean(result));
631 }
632 
633 
635  RETURN_NATIVE_CALL(to_number, { obj }, exc);
636 }
637 
638 
640  RETURN_NATIVE_CALL(to_string, { obj }, exc);
641 }
642 
643 
645  RETURN_NATIVE_CALL(to_detail_string, { obj }, exc);
646 }
647 
648 
650  if (obj->IsSpecObject()) return obj;
651  RETURN_NATIVE_CALL(to_object, { obj }, exc);
652 }
653 
654 
656  RETURN_NATIVE_CALL(to_integer, { obj }, exc);
657 }
658 
659 
661  RETURN_NATIVE_CALL(to_uint32, { obj }, exc);
662 }
663 
664 
666  RETURN_NATIVE_CALL(to_int32, { obj }, exc);
667 }
668 
669 
670 Handle<Object> Execution::NewDate(double time, bool* exc) {
671  Handle<Object> time_obj = FACTORY->NewNumber(time);
672  RETURN_NATIVE_CALL(create_date, { time_obj }, exc);
673 }
674 
675 
676 #undef RETURN_NATIVE_CALL
677 
678 
681  bool* exc) {
683  pattern->GetIsolate()->native_context()->regexp_function());
685  function, pattern, flags, exc);
686  if (*exc) return Handle<JSRegExp>();
687  return Handle<JSRegExp>::cast(re_obj);
688 }
689 
690 
692  Isolate* isolate = string->GetIsolate();
693  Factory* factory = isolate->factory();
694 
695  int int_index = static_cast<int>(index);
696  if (int_index < 0 || int_index >= string->length()) {
697  return factory->undefined_value();
698  }
699 
700  Handle<Object> char_at =
701  GetProperty(isolate->js_builtins_object(),
702  factory->char_at_symbol());
703  if (!char_at->IsJSFunction()) {
704  return factory->undefined_value();
705  }
706 
707  bool caught_exception;
708  Handle<Object> index_object = factory->NewNumberFromInt(int_index);
709  Handle<Object> index_arg[] = { index_object };
711  string,
712  ARRAY_SIZE(index_arg),
713  index_arg,
714  &caught_exception);
715  if (caught_exception) {
716  return factory->undefined_value();
717  }
718  return result;
719 }
720 
721 
724  bool* exc) {
725  Isolate* isolate = data->GetIsolate();
726  // Fast case: see if the function has already been instantiated
727  int serial_number = Smi::cast(data->serial_number())->value();
728  Object* elm =
729  isolate->native_context()->function_cache()->
730  GetElementNoExceptionThrown(serial_number);
731  if (elm->IsJSFunction()) return Handle<JSFunction>(JSFunction::cast(elm));
732  // The function has not yet been instantiated in this context; do it.
733  Handle<Object> args[] = { data };
734  Handle<Object> result = Call(isolate->instantiate_fun(),
735  isolate->js_builtins_object(),
736  ARRAY_SIZE(args),
737  args,
738  exc);
739  if (*exc) return Handle<JSFunction>::null();
740  return Handle<JSFunction>::cast(result);
741 }
742 
743 
745  bool* exc) {
746  Isolate* isolate = data->GetIsolate();
747  if (data->property_list()->IsUndefined() &&
748  !data->constructor()->IsUndefined()) {
749  // Initialization to make gcc happy.
750  Object* result = NULL;
751  {
752  HandleScope scope(isolate);
753  Handle<FunctionTemplateInfo> cons_template =
755  FunctionTemplateInfo::cast(data->constructor()));
756  Handle<JSFunction> cons = InstantiateFunction(cons_template, exc);
757  if (*exc) return Handle<JSObject>::null();
758  Handle<Object> value = New(cons, 0, NULL, exc);
759  if (*exc) return Handle<JSObject>::null();
760  result = *value;
761  }
762  ASSERT(!*exc);
763  return Handle<JSObject>(JSObject::cast(result));
764  } else {
765  Handle<Object> args[] = { data };
766  Handle<Object> result = Call(isolate->instantiate_fun(),
767  isolate->js_builtins_object(),
768  ARRAY_SIZE(args),
769  args,
770  exc);
771  if (*exc) return Handle<JSObject>::null();
772  return Handle<JSObject>::cast(result);
773  }
774 }
775 
776 
779  bool* exc) {
780  Isolate* isolate = Isolate::Current();
781  Handle<Object> args[] = { instance, instance_template };
782  Execution::Call(isolate->configure_instance_fun(),
783  isolate->js_builtins_object(),
784  ARRAY_SIZE(args),
785  args,
786  exc);
787 }
788 
789 
791  Handle<JSFunction> fun,
792  Handle<Object> pos,
793  Handle<Object> is_global) {
794  Isolate* isolate = fun->GetIsolate();
795  Handle<Object> args[] = { recv, fun, pos, is_global };
796  bool caught_exception;
797  Handle<Object> result = TryCall(isolate->get_stack_trace_line_fun(),
798  isolate->js_builtins_object(),
799  ARRAY_SIZE(args),
800  args,
801  &caught_exception);
802  if (caught_exception || !result->IsString()) {
803  return isolate->factory()->empty_symbol();
804  }
805 
806  return Handle<String>::cast(result);
807 }
808 
809 
810 static Object* RuntimePreempt() {
811  Isolate* isolate = Isolate::Current();
812 
813  // Clear the preempt request flag.
814  isolate->stack_guard()->Continue(PREEMPT);
815 
817 
818 #ifdef ENABLE_DEBUGGER_SUPPORT
819  if (isolate->debug()->InDebugger()) {
820  // If currently in the debugger don't do any actual preemption but record
821  // that preemption occoured while in the debugger.
822  isolate->debug()->PreemptionWhileInDebugger();
823  } else {
824  // Perform preemption.
825  v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
827  }
828 #else
829  { // NOLINT
830  // Perform preemption.
831  v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
833  }
834 #endif
835 
836  return isolate->heap()->undefined_value();
837 }
838 
839 
840 #ifdef ENABLE_DEBUGGER_SUPPORT
841 Object* Execution::DebugBreakHelper() {
842  Isolate* isolate = Isolate::Current();
843 
844  // Just continue if breaks are disabled.
845  if (isolate->debug()->disable_break()) {
846  return isolate->heap()->undefined_value();
847  }
848 
849  // Ignore debug break during bootstrapping.
850  if (isolate->bootstrapper()->IsActive()) {
851  return isolate->heap()->undefined_value();
852  }
853 
854  // Ignore debug break if debugger is not active.
855  if (!isolate->debugger()->IsDebuggerActive()) {
856  return isolate->heap()->undefined_value();
857  }
858 
859  StackLimitCheck check(isolate);
860  if (check.HasOverflowed()) {
861  return isolate->heap()->undefined_value();
862  }
863 
864  {
865  JavaScriptFrameIterator it(isolate);
866  ASSERT(!it.done());
867  Object* fun = it.frame()->function();
868  if (fun && fun->IsJSFunction()) {
869  // Don't stop in builtin functions.
870  if (JSFunction::cast(fun)->IsBuiltin()) {
871  return isolate->heap()->undefined_value();
872  }
873  GlobalObject* global = JSFunction::cast(fun)->context()->global_object();
874  // Don't stop in debugger functions.
875  if (isolate->debug()->IsDebugGlobal(global)) {
876  return isolate->heap()->undefined_value();
877  }
878  }
879  }
880 
881  // Collect the break state before clearing the flags.
882  bool debug_command_only =
883  isolate->stack_guard()->IsDebugCommand() &&
884  !isolate->stack_guard()->IsDebugBreak();
885 
886  // Clear the debug break request flag.
887  isolate->stack_guard()->Continue(DEBUGBREAK);
888 
889  ProcessDebugMessages(debug_command_only);
890 
891  // Return to continue execution.
892  return isolate->heap()->undefined_value();
893 }
894 
895 void Execution::ProcessDebugMessages(bool debug_command_only) {
896  Isolate* isolate = Isolate::Current();
897  // Clear the debug command request flag.
898  isolate->stack_guard()->Continue(DEBUGCOMMAND);
899 
900  StackLimitCheck check(isolate);
901  if (check.HasOverflowed()) {
902  return;
903  }
904 
905  HandleScope scope(isolate);
906  // Enter the debugger. Just continue if we fail to enter the debugger.
907  EnterDebugger debugger;
908  if (debugger.FailedToEnter()) {
909  return;
910  }
911 
912  // Notify the debug event listeners. Indicate auto continue if the break was
913  // a debug command break.
914  isolate->debugger()->OnDebugBreak(isolate->factory()->undefined_value(),
915  debug_command_only);
916 }
917 
918 
919 #endif
920 
922  StackGuard* stack_guard = isolate->stack_guard();
923  if (stack_guard->ShouldPostponeInterrupts()) {
924  return isolate->heap()->undefined_value();
925  }
926 
927  if (stack_guard->IsGCRequest()) {
929  "StackGuard GC request");
930  stack_guard->Continue(GC_REQUEST);
931  }
932 
933  if (stack_guard->IsCodeReadyEvent()) {
934  ASSERT(FLAG_parallel_recompilation);
935  if (FLAG_trace_parallel_recompilation) {
936  PrintF(" ** CODE_READY event received.\n");
937  }
938  stack_guard->Continue(CODE_READY);
939  }
940  if (!stack_guard->IsTerminateExecution()) {
942  }
943 
944  isolate->counters()->stack_interrupts()->Increment();
945  // If FLAG_count_based_interrupts, every interrupt is a profiler interrupt.
946  if (FLAG_count_based_interrupts ||
947  stack_guard->IsRuntimeProfilerTick()) {
948  isolate->counters()->runtime_profiler_ticks()->Increment();
949  stack_guard->Continue(RUNTIME_PROFILER_TICK);
950  isolate->runtime_profiler()->OptimizeNow();
951  }
952 #ifdef ENABLE_DEBUGGER_SUPPORT
953  if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) {
954  DebugBreakHelper();
955  }
956 #endif
957  if (stack_guard->IsPreempted()) RuntimePreempt();
958  if (stack_guard->IsTerminateExecution()) {
959  stack_guard->Continue(TERMINATE);
960  return isolate->TerminateExecution();
961  }
962  if (stack_guard->IsInterrupted()) {
963  stack_guard->Continue(INTERRUPT);
964  return isolate->StackOverflow();
965  }
966  return isolate->heap()->undefined_value();
967 }
968 
969 
970 } } // namespace v8::internal
static Handle< Object > New(Handle< JSFunction > func, int argc, Handle< Object > argv[], bool *pending_exception)
Definition: execution.cc:183
Failure * StackOverflow()
Definition: isolate.cc:924
void SetStackLimits()
Definition: heap.cc:6253
static Handle< Object > TryCall(Handle< JSFunction > func, Handle< Object > receiver, int argc, Handle< Object > argv[], bool *caught_exception)
Definition: execution.cc:192
static Handle< Object > ToUint32(Handle< Object > obj, bool *exc)
Definition: execution.cc:660
void PrintF(const char *format,...)
Definition: v8utils.cc:40
Local< Value > Exception() const
Definition: api.cc:1720
const int KB
Definition: globals.h:207
bool HasCaught() const
Definition: api.cc:1703
void SetCaptureMessage(bool value)
Definition: api.cc:1773
void CollectAllGarbage(int flags, const char *gc_reason=NULL)
Definition: heap.cc:538
static HeapObject * cast(Object *obj)
static Handle< T > cast(Handle< S > that)
Definition: handles.h:81
static Failure * OutOfMemoryException()
Definition: objects-inl.h:1029
static Handle< Object > CreateRegExpLiteral(Handle< JSFunction > constructor, Handle< String > pattern, Handle< String > flags, bool *has_pending_exception)
Definition: jsregexp.cc:66
static Handle< Object > ToInteger(Handle< Object > obj, bool *exc)
Definition: execution.cc:655
static Handle< Object > GetConstructorDelegate(Handle< Object > object)
Definition: execution.cc:287
static Handle< Object > ToObject(Handle< Object > obj, bool *exc)
Definition: execution.cc:649
static Handle< Object > ToInt32(Handle< Object > obj, bool *exc)
Definition: execution.cc:665
#define ASSERT(condition)
Definition: checks.h:270
static void ConfigureInstance(Handle< Object > instance, Handle< Object > data, bool *exc)
Definition: execution.cc:777
kPropertyAccessorsOffset kNamedPropertyHandlerOffset instance_template
Definition: objects-inl.h:3860
static Handle< Object > ToDetailString(Handle< Object > obj, bool *exc)
Definition: execution.cc:644
void SetVerbose(bool value)
Definition: api.cc:1768
int isnan(double x)
Handle< Object > GetProperty(Handle< JSReceiver > obj, const char *name)
Definition: handles.cc:282
Factory * factory()
Definition: isolate.h:992
static Smi * cast(Object *object)
StackGuard * stack_guard()
Definition: isolate.h:834
bool has_instance_call_handler()
Definition: objects.h:4766
uint8_t byte
Definition: globals.h:156
GlobalObject * global_object()
Definition: contexts.h:328
static JSFunctionProxy * cast(Object *obj)
static Handle< Object > CharAt(Handle< String > str, uint32_t index)
Definition: execution.cc:691
static Handle< Object > ToBoolean(Handle< Object > obj)
Definition: execution.cc:618
char * RestoreStackGuard(char *from)
Definition: execution.cc:539
void ClearThread(const ExecutionAccess &lock)
Definition: execution.cc:586
RuntimeProfiler * runtime_profiler()
Definition: isolate.h:826
static void PreemptionReceived()
Definition: v8threads.cc:481
char * ArchiveStackGuard(char *to)
Definition: execution.cc:522
static MUST_USE_RESULT MaybeObject * HandleStackGuardInterrupt(Isolate *isolate)
Definition: execution.cc:921
static const int kNoGCFlags
Definition: heap.h:1081
const Address kZapValue
Definition: v8globals.h:80
static uintptr_t JsLimitFromCLimit(v8::internal::Isolate *isolate, uintptr_t c_limit)
Definition: simulator-arm.h:71
static FunctionTemplateInfo * cast(Object *obj)
static Handle< JSRegExp > NewJSRegExp(Handle< String > pattern, Handle< String > flags, bool *exc)
Definition: execution.cc:679
#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4)
Definition: simulator-arm.h:48
static Handle< Object > NewDate(double time, bool *exc)
Definition: execution.cc:670
Handle< JSBuiltinsObject > js_builtins_object()
Definition: isolate.h:656
static Handle< Object > Call(Handle< Object > callable, Handle< Object > receiver, int argc, Handle< Object > argv[], bool *pending_exception, bool convert_receiver=false)
Definition: execution.cc:150
Handle< Object > NewNumberFromInt(int32_t value, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:605
static Handle< JSFunction > InstantiateFunction(Handle< FunctionTemplateInfo > data, bool *exc)
Definition: execution.cc:722
void Continue(InterruptFlag after_what)
Definition: execution.cc:513
JavaScriptFrameIteratorTemp< StackFrameIterator > JavaScriptFrameIterator
Definition: frames.h:775
static Handle< Object > GetFunctionDelegate(Handle< Object > object)
Definition: execution.cc:229
void set_stack_limit(uintptr_t value)
Definition: isolate.h:385
static Handle< T > null()
Definition: handles.h:86
#define RETURN_NATIVE_CALL(name, args, has_pending_exception)
Definition: execution.cc:606
#define HEAP
Definition: isolate.h:1433
static Handle< Object > ToNumber(Handle< Object > obj, bool *exc)
Definition: execution.cc:634
Counters * counters()
Definition: isolate.h:819
static Handle< JSObject > InstantiateObject(Handle< ObjectTemplateInfo > data, bool *exc)
Definition: execution.cc:744
Failure * TerminateExecution()
Definition: isolate.cc:939
OptimizingCompilerThread * optimizing_compiler_thread()
Definition: isolate.h:1065
#define FACTORY
Definition: isolate.h:1434
static Handle< String > GetStackTraceLine(Handle< Object > recv, Handle< JSFunction > fun, Handle< Object > pos, Handle< Object > is_global)
Definition: execution.cc:790
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 use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra 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 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Definition: flags.cc:301
static Handle< Object > ToString(Handle< Object > obj, bool *exc)
Definition: execution.cc:639
Handle< Context > native_context()
Definition: isolate.cc:1345
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 use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
static Handle< Object > TryGetConstructorDelegate(Handle< Object > object, bool *has_pending_exception)
Definition: execution.cc:313
void SetStackLimit(uintptr_t limit)
Definition: execution.cc:363
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 use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra 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 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage including flags
Definition: flags.cc:495
void check(i::Vector< const char > string)
static void FatalProcessOutOfMemory(const char *location, bool take_snapshot=false)
#define ARRAY_SIZE(a)
Definition: globals.h:281
static Handle< Object > TryGetFunctionDelegate(Handle< Object > object, bool *has_pending_exception)
Definition: execution.cc:256
static JSObject * cast(Object *obj)
void InitThread(const ExecutionAccess &lock)
Definition: execution.cc:592
static JSFunction * cast(Object *obj)