V8 Project
execution.cc
Go to the documentation of this file.
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/execution.h"
6 
7 #include "src/bootstrapper.h"
8 #include "src/codegen.h"
9 #include "src/deoptimizer.h"
10 #include "src/isolate-inl.h"
11 #include "src/vm-state-inl.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 StackGuard::StackGuard()
17  : isolate_(NULL) {
18 }
19 
20 
21 void StackGuard::set_interrupt_limits(const ExecutionAccess& lock) {
22  DCHECK(isolate_ != NULL);
23  thread_local_.jslimit_ = kInterruptLimit;
24  thread_local_.climit_ = kInterruptLimit;
25  isolate_->heap()->SetStackLimits();
26 }
27 
28 
29 void StackGuard::reset_limits(const ExecutionAccess& lock) {
30  DCHECK(isolate_ != NULL);
31  thread_local_.jslimit_ = thread_local_.real_jslimit_;
32  thread_local_.climit_ = thread_local_.real_climit_;
33  isolate_->heap()->SetStackLimits();
34 }
35 
36 
38  bool is_construct,
39  Handle<JSFunction> function,
40  Handle<Object> receiver,
41  int argc,
42  Handle<Object> args[]) {
43  Isolate* isolate = function->GetIsolate();
44 
45  // Entering JavaScript.
46  VMState<JS> state(isolate);
47  CHECK(AllowJavascriptExecution::IsAllowed(isolate));
48  if (!ThrowOnJavascriptExecution::IsAllowed(isolate)) {
49  isolate->ThrowIllegalOperation();
50  isolate->ReportPendingMessages();
51  return MaybeHandle<Object>();
52  }
53 
54  // Placeholder for return value.
55  Object* value = NULL;
56 
57  typedef Object* (*JSEntryFunction)(byte* entry,
58  Object* function,
59  Object* receiver,
60  int argc,
61  Object*** args);
62 
63  Handle<Code> code = is_construct
64  ? isolate->factory()->js_construct_entry_code()
65  : isolate->factory()->js_entry_code();
66 
67  // Convert calls on global objects to be calls on the global
68  // receiver instead to avoid having a 'this' pointer which refers
69  // directly to a global object.
70  if (receiver->IsGlobalObject()) {
71  receiver = handle(Handle<GlobalObject>::cast(receiver)->global_proxy());
72  }
73 
74  // Make sure that the global object of the context we're about to
75  // make the current one is indeed a global object.
76  DCHECK(function->context()->global_object()->IsGlobalObject());
77 
78  {
79  // Save and restore context around invocation and block the
80  // allocation of handles without explicit handle scopes.
81  SaveContext save(isolate);
82  SealHandleScope shs(isolate);
83  JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
84 
85  // Call the function through the right JS entry stub.
86  byte* function_entry = function->code()->entry();
87  JSFunction* func = *function;
88  Object* recv = *receiver;
89  Object*** argv = reinterpret_cast<Object***>(args);
90  value =
91  CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
92  }
93 
94 #ifdef VERIFY_HEAP
95  value->ObjectVerify();
96 #endif
97 
98  // Update the pending exception flag and return the value.
99  bool has_exception = value->IsException();
100  DCHECK(has_exception == isolate->has_pending_exception());
101  if (has_exception) {
102  isolate->ReportPendingMessages();
103  // Reset stepping state when script exits with uncaught exception.
104  if (isolate->debug()->is_active()) {
105  isolate->debug()->ClearStepping();
106  }
107  return MaybeHandle<Object>();
108  } else {
109  isolate->clear_pending_message();
110  }
111 
112  return Handle<Object>(value, isolate);
113 }
114 
115 
116 MaybeHandle<Object> Execution::Call(Isolate* isolate,
117  Handle<Object> callable,
118  Handle<Object> receiver,
119  int argc,
120  Handle<Object> argv[],
121  bool convert_receiver) {
122  if (!callable->IsJSFunction()) {
124  isolate, callable, TryGetFunctionDelegate(isolate, callable), Object);
125  }
126  Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
127 
128  // In sloppy mode, convert receiver.
129  if (convert_receiver && !receiver->IsJSReceiver() &&
130  !func->shared()->native() &&
131  func->shared()->strict_mode() == SLOPPY) {
132  if (receiver->IsUndefined() || receiver->IsNull()) {
133  receiver = handle(func->global_proxy());
134  DCHECK(!receiver->IsJSBuiltinsObject());
135  } else {
137  isolate, receiver, ToObject(isolate, receiver), Object);
138  }
139  }
140 
141  return Invoke(false, func, receiver, argc, argv);
142 }
143 
144 
145 MaybeHandle<Object> Execution::New(Handle<JSFunction> func,
146  int argc,
147  Handle<Object> argv[]) {
148  return Invoke(true, func, handle(func->global_proxy()), argc, argv);
149 }
150 
151 
152 MaybeHandle<Object> Execution::TryCall(Handle<JSFunction> func,
153  Handle<Object> receiver, int argc,
154  Handle<Object> args[],
155  MaybeHandle<Object>* exception_out) {
156  bool is_termination = false;
157  Isolate* isolate = func->GetIsolate();
158  MaybeHandle<Object> maybe_result;
159  if (exception_out != NULL) *exception_out = MaybeHandle<Object>();
160  // Enter a try-block while executing the JavaScript code. To avoid
161  // duplicate error printing it must be non-verbose. Also, to avoid
162  // creating message objects during stack overflow we shouldn't
163  // capture messages.
164  {
165  v8::TryCatch catcher;
166  catcher.SetVerbose(false);
167  catcher.SetCaptureMessage(false);
168 
169  maybe_result = Invoke(false, func, receiver, argc, args);
170 
171  if (maybe_result.is_null()) {
172  DCHECK(catcher.HasCaught());
173  DCHECK(isolate->has_pending_exception());
174  DCHECK(isolate->external_caught_exception());
175  if (exception_out != NULL) {
176  if (isolate->pending_exception() ==
177  isolate->heap()->termination_exception()) {
178  is_termination = true;
179  } else {
180  *exception_out = v8::Utils::OpenHandle(*catcher.Exception());
181  }
182  }
183  isolate->OptionalRescheduleException(true);
184  }
185 
186  DCHECK(!isolate->has_pending_exception());
187  DCHECK(!isolate->external_caught_exception());
188  }
189  if (is_termination) isolate->TerminateExecution();
190  return maybe_result;
191 }
192 
193 
194 Handle<Object> Execution::GetFunctionDelegate(Isolate* isolate,
195  Handle<Object> object) {
196  DCHECK(!object->IsJSFunction());
197  Factory* factory = isolate->factory();
198 
199  // If you return a function from here, it will be called when an
200  // attempt is made to call the given object as a function.
201 
202  // If object is a function proxy, get its handler. Iterate if necessary.
203  Object* fun = *object;
204  while (fun->IsJSFunctionProxy()) {
205  fun = JSFunctionProxy::cast(fun)->call_trap();
206  }
207  if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
208 
209  // Objects created through the API can have an instance-call handler
210  // that should be used when calling the object as a function.
211  if (fun->IsHeapObject() &&
212  HeapObject::cast(fun)->map()->has_instance_call_handler()) {
213  return Handle<JSFunction>(
214  isolate->native_context()->call_as_function_delegate());
215  }
216 
217  return factory->undefined_value();
218 }
219 
220 
221 MaybeHandle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate,
222  Handle<Object> object) {
223  DCHECK(!object->IsJSFunction());
224 
225  // If object is a function proxy, get its handler. Iterate if necessary.
226  Object* fun = *object;
227  while (fun->IsJSFunctionProxy()) {
228  fun = JSFunctionProxy::cast(fun)->call_trap();
229  }
230  if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
231 
232  // Objects created through the API can have an instance-call handler
233  // that should be used when calling the object as a function.
234  if (fun->IsHeapObject() &&
235  HeapObject::cast(fun)->map()->has_instance_call_handler()) {
236  return Handle<JSFunction>(
237  isolate->native_context()->call_as_function_delegate());
238  }
239 
240  // If the Object doesn't have an instance-call handler we should
241  // throw a non-callable exception.
242  THROW_NEW_ERROR(isolate, NewTypeError("called_non_callable",
243  i::HandleVector<i::Object>(&object, 1)),
244  Object);
245 }
246 
247 
248 Handle<Object> Execution::GetConstructorDelegate(Isolate* isolate,
249  Handle<Object> object) {
250  DCHECK(!object->IsJSFunction());
251 
252  // If you return a function from here, it will be called when an
253  // attempt is made to call the given object as a constructor.
254 
255  // If object is a function proxies, get its handler. Iterate if necessary.
256  Object* fun = *object;
257  while (fun->IsJSFunctionProxy()) {
258  fun = JSFunctionProxy::cast(fun)->call_trap();
259  }
260  if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
261 
262  // Objects created through the API can have an instance-call handler
263  // that should be used when calling the object as a function.
264  if (fun->IsHeapObject() &&
265  HeapObject::cast(fun)->map()->has_instance_call_handler()) {
266  return Handle<JSFunction>(
267  isolate->native_context()->call_as_constructor_delegate());
268  }
269 
270  return isolate->factory()->undefined_value();
271 }
272 
273 
274 MaybeHandle<Object> Execution::TryGetConstructorDelegate(
275  Isolate* isolate, Handle<Object> object) {
276  DCHECK(!object->IsJSFunction());
277 
278  // If you return a function from here, it will be called when an
279  // attempt is made to call the given object as a constructor.
280 
281  // If object is a function proxies, get its handler. Iterate if necessary.
282  Object* fun = *object;
283  while (fun->IsJSFunctionProxy()) {
284  fun = JSFunctionProxy::cast(fun)->call_trap();
285  }
286  if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
287 
288  // Objects created through the API can have an instance-call handler
289  // that should be used when calling the object as a function.
290  if (fun->IsHeapObject() &&
291  HeapObject::cast(fun)->map()->has_instance_call_handler()) {
292  return Handle<JSFunction>(
293  isolate->native_context()->call_as_constructor_delegate());
294  }
295 
296  // If the Object doesn't have an instance-call handler we should
297  // throw a non-callable exception.
298  THROW_NEW_ERROR(isolate, NewTypeError("called_non_callable",
299  i::HandleVector<i::Object>(&object, 1)),
300  Object);
301 }
302 
303 
304 void StackGuard::EnableInterrupts() {
305  ExecutionAccess access(isolate_);
306  if (has_pending_interrupts(access)) {
307  set_interrupt_limits(access);
308  }
309 }
310 
311 
312 void StackGuard::SetStackLimit(uintptr_t limit) {
313  ExecutionAccess access(isolate_);
314  // If the current limits are special (e.g. due to a pending interrupt) then
315  // leave them alone.
316  uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit);
317  if (thread_local_.jslimit_ == thread_local_.real_jslimit_) {
318  thread_local_.jslimit_ = jslimit;
319  }
320  if (thread_local_.climit_ == thread_local_.real_climit_) {
321  thread_local_.climit_ = limit;
322  }
323  thread_local_.real_climit_ = limit;
324  thread_local_.real_jslimit_ = jslimit;
325 }
326 
327 
328 void StackGuard::DisableInterrupts() {
329  ExecutionAccess access(isolate_);
330  reset_limits(access);
331 }
332 
333 
334 void StackGuard::PushPostponeInterruptsScope(PostponeInterruptsScope* scope) {
335  ExecutionAccess access(isolate_);
336  // Intercept already requested interrupts.
337  int intercepted = thread_local_.interrupt_flags_ & scope->intercept_mask_;
338  scope->intercepted_flags_ = intercepted;
339  thread_local_.interrupt_flags_ &= ~intercepted;
340  if (!has_pending_interrupts(access)) reset_limits(access);
341  // Add scope to the chain.
342  scope->prev_ = thread_local_.postpone_interrupts_;
343  thread_local_.postpone_interrupts_ = scope;
344 }
345 
346 
347 void StackGuard::PopPostponeInterruptsScope() {
348  ExecutionAccess access(isolate_);
349  PostponeInterruptsScope* top = thread_local_.postpone_interrupts_;
350  // Make intercepted interrupts active.
351  DCHECK((thread_local_.interrupt_flags_ & top->intercept_mask_) == 0);
352  thread_local_.interrupt_flags_ |= top->intercepted_flags_;
353  if (has_pending_interrupts(access)) set_interrupt_limits(access);
354  // Remove scope from chain.
355  thread_local_.postpone_interrupts_ = top->prev_;
356 }
357 
358 
359 bool StackGuard::CheckInterrupt(InterruptFlag flag) {
360  ExecutionAccess access(isolate_);
361  return thread_local_.interrupt_flags_ & flag;
362 }
363 
364 
365 void StackGuard::RequestInterrupt(InterruptFlag flag) {
366  ExecutionAccess access(isolate_);
367  // Check the chain of PostponeInterruptsScopes for interception.
368  if (thread_local_.postpone_interrupts_ &&
369  thread_local_.postpone_interrupts_->Intercept(flag)) {
370  return;
371  }
372 
373  // Not intercepted. Set as active interrupt flag.
374  thread_local_.interrupt_flags_ |= flag;
375  set_interrupt_limits(access);
376 }
377 
378 
379 void StackGuard::ClearInterrupt(InterruptFlag flag) {
380  ExecutionAccess access(isolate_);
381  // Clear the interrupt flag from the chain of PostponeInterruptsScopes.
382  for (PostponeInterruptsScope* current = thread_local_.postpone_interrupts_;
383  current != NULL;
384  current = current->prev_) {
385  current->intercepted_flags_ &= ~flag;
386  }
387 
388  // Clear the interrupt flag from the active interrupt flags.
389  thread_local_.interrupt_flags_ &= ~flag;
390  if (!has_pending_interrupts(access)) reset_limits(access);
391 }
392 
393 
394 bool StackGuard::CheckAndClearInterrupt(InterruptFlag flag) {
395  ExecutionAccess access(isolate_);
396  bool result = (thread_local_.interrupt_flags_ & flag);
397  thread_local_.interrupt_flags_ &= ~flag;
398  if (!has_pending_interrupts(access)) reset_limits(access);
399  return result;
400 }
401 
402 
403 char* StackGuard::ArchiveStackGuard(char* to) {
404  ExecutionAccess access(isolate_);
405  MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
406  ThreadLocal blank;
407 
408  // Set the stack limits using the old thread_local_.
409  // TODO(isolates): This was the old semantics of constructing a ThreadLocal
410  // (as the ctor called SetStackLimits, which looked at the
411  // current thread_local_ from StackGuard)-- but is this
412  // really what was intended?
413  isolate_->heap()->SetStackLimits();
414  thread_local_ = blank;
415 
416  return to + sizeof(ThreadLocal);
417 }
418 
419 
420 char* StackGuard::RestoreStackGuard(char* from) {
421  ExecutionAccess access(isolate_);
422  MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
423  isolate_->heap()->SetStackLimits();
424  return from + sizeof(ThreadLocal);
425 }
426 
427 
428 void StackGuard::FreeThreadResources() {
429  Isolate::PerIsolateThreadData* per_thread =
430  isolate_->FindOrAllocatePerThreadDataForThisThread();
431  per_thread->set_stack_limit(thread_local_.real_climit_);
432 }
433 
434 
435 void StackGuard::ThreadLocal::Clear() {
436  real_jslimit_ = kIllegalLimit;
437  jslimit_ = kIllegalLimit;
438  real_climit_ = kIllegalLimit;
439  climit_ = kIllegalLimit;
440  postpone_interrupts_ = NULL;
441  interrupt_flags_ = 0;
442 }
443 
444 
445 bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
446  bool should_set_stack_limits = false;
447  if (real_climit_ == kIllegalLimit) {
448  const uintptr_t kLimitSize = FLAG_stack_size * KB;
449  DCHECK(GetCurrentStackPosition() > kLimitSize);
450  uintptr_t limit = GetCurrentStackPosition() - kLimitSize;
451  real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
452  jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
453  real_climit_ = limit;
454  climit_ = limit;
455  should_set_stack_limits = true;
456  }
457  postpone_interrupts_ = NULL;
458  interrupt_flags_ = 0;
459  return should_set_stack_limits;
460 }
461 
462 
463 void StackGuard::ClearThread(const ExecutionAccess& lock) {
464  thread_local_.Clear();
465  isolate_->heap()->SetStackLimits();
466 }
467 
468 
469 void StackGuard::InitThread(const ExecutionAccess& lock) {
470  if (thread_local_.Initialize(isolate_)) isolate_->heap()->SetStackLimits();
471  Isolate::PerIsolateThreadData* per_thread =
472  isolate_->FindOrAllocatePerThreadDataForThisThread();
473  uintptr_t stored_limit = per_thread->stack_limit();
474  // You should hold the ExecutionAccess lock when you call this.
475  if (stored_limit != 0) {
476  SetStackLimit(stored_limit);
477  }
478 }
479 
480 
481 // --- C a l l s t o n a t i v e s ---
482 
483 #define RETURN_NATIVE_CALL(name, args) \
484  do { \
485  Handle<Object> argv[] = args; \
486  return Call(isolate, \
487  isolate->name##_fun(), \
488  isolate->js_builtins_object(), \
489  arraysize(argv), argv); \
490  } while (false)
491 
492 
493 MaybeHandle<Object> Execution::ToNumber(
494  Isolate* isolate, Handle<Object> obj) {
495  RETURN_NATIVE_CALL(to_number, { obj });
496 }
497 
498 
499 MaybeHandle<Object> Execution::ToString(
500  Isolate* isolate, Handle<Object> obj) {
501  RETURN_NATIVE_CALL(to_string, { obj });
502 }
503 
504 
505 MaybeHandle<Object> Execution::ToDetailString(
506  Isolate* isolate, Handle<Object> obj) {
507  RETURN_NATIVE_CALL(to_detail_string, { obj });
508 }
509 
510 
511 MaybeHandle<Object> Execution::ToObject(
512  Isolate* isolate, Handle<Object> obj) {
513  if (obj->IsSpecObject()) return obj;
514  RETURN_NATIVE_CALL(to_object, { obj });
515 }
516 
517 
518 MaybeHandle<Object> Execution::ToInteger(
519  Isolate* isolate, Handle<Object> obj) {
520  RETURN_NATIVE_CALL(to_integer, { obj });
521 }
522 
523 
524 MaybeHandle<Object> Execution::ToUint32(
525  Isolate* isolate, Handle<Object> obj) {
526  RETURN_NATIVE_CALL(to_uint32, { obj });
527 }
528 
529 
530 MaybeHandle<Object> Execution::ToInt32(
531  Isolate* isolate, Handle<Object> obj) {
532  RETURN_NATIVE_CALL(to_int32, { obj });
533 }
534 
535 
536 MaybeHandle<Object> Execution::NewDate(Isolate* isolate, double time) {
537  Handle<Object> time_obj = isolate->factory()->NewNumber(time);
538  RETURN_NATIVE_CALL(create_date, { time_obj });
539 }
540 
541 
542 #undef RETURN_NATIVE_CALL
543 
544 
545 MaybeHandle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern,
546  Handle<String> flags) {
547  Isolate* isolate = pattern->GetIsolate();
548  Handle<JSFunction> function = Handle<JSFunction>(
549  isolate->native_context()->regexp_function());
550  Handle<Object> re_obj;
552  isolate, re_obj,
553  RegExpImpl::CreateRegExpLiteral(function, pattern, flags),
554  JSRegExp);
555  return Handle<JSRegExp>::cast(re_obj);
556 }
557 
558 
559 Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) {
560  Isolate* isolate = string->GetIsolate();
561  Factory* factory = isolate->factory();
562 
563  int int_index = static_cast<int>(index);
564  if (int_index < 0 || int_index >= string->length()) {
565  return factory->undefined_value();
566  }
567 
568  Handle<Object> char_at = Object::GetProperty(
569  isolate->js_builtins_object(),
570  factory->char_at_string()).ToHandleChecked();
571  if (!char_at->IsJSFunction()) {
572  return factory->undefined_value();
573  }
574 
575  Handle<Object> index_object = factory->NewNumberFromInt(int_index);
576  Handle<Object> index_arg[] = { index_object };
577  Handle<Object> result;
578  if (!TryCall(Handle<JSFunction>::cast(char_at),
579  string,
580  arraysize(index_arg),
581  index_arg).ToHandle(&result)) {
582  return factory->undefined_value();
583  }
584  return result;
585 }
586 
587 
588 MaybeHandle<JSFunction> Execution::InstantiateFunction(
589  Handle<FunctionTemplateInfo> data) {
590  Isolate* isolate = data->GetIsolate();
591  if (!data->do_not_cache()) {
592  // Fast case: see if the function has already been instantiated
593  int serial_number = Smi::cast(data->serial_number())->value();
594  Handle<JSObject> cache(isolate->native_context()->function_cache());
595  Handle<Object> elm =
596  Object::GetElement(isolate, cache, serial_number).ToHandleChecked();
597  if (elm->IsJSFunction()) return Handle<JSFunction>::cast(elm);
598  }
599  // The function has not yet been instantiated in this context; do it.
600  Handle<Object> args[] = { data };
601  Handle<Object> result;
603  isolate, result,
604  Call(isolate,
605  isolate->instantiate_fun(),
606  isolate->js_builtins_object(),
607  arraysize(args),
608  args),
609  JSFunction);
610  return Handle<JSFunction>::cast(result);
611 }
612 
613 
614 MaybeHandle<JSObject> Execution::InstantiateObject(
615  Handle<ObjectTemplateInfo> data) {
616  Isolate* isolate = data->GetIsolate();
617  Handle<Object> result;
618  if (data->property_list()->IsUndefined() &&
619  !data->constructor()->IsUndefined()) {
620  Handle<FunctionTemplateInfo> cons_template =
621  Handle<FunctionTemplateInfo>(
622  FunctionTemplateInfo::cast(data->constructor()));
623  Handle<JSFunction> cons;
625  isolate, cons, InstantiateFunction(cons_template), JSObject);
626  ASSIGN_RETURN_ON_EXCEPTION(isolate, result, New(cons, 0, NULL), JSObject);
627  } else {
628  Handle<Object> args[] = { data };
630  isolate, result,
631  Call(isolate,
632  isolate->instantiate_fun(),
633  isolate->js_builtins_object(),
634  arraysize(args),
635  args),
636  JSObject);
637  }
638  return Handle<JSObject>::cast(result);
639 }
640 
641 
642 MaybeHandle<Object> Execution::ConfigureInstance(
643  Isolate* isolate,
644  Handle<Object> instance,
645  Handle<Object> instance_template) {
646  Handle<Object> args[] = { instance, instance_template };
647  return Execution::Call(isolate,
648  isolate->configure_instance_fun(),
649  isolate->js_builtins_object(),
650  arraysize(args),
651  args);
652 }
653 
654 
655 Handle<String> Execution::GetStackTraceLine(Handle<Object> recv,
656  Handle<JSFunction> fun,
657  Handle<Object> pos,
658  Handle<Object> is_global) {
659  Isolate* isolate = fun->GetIsolate();
660  Handle<Object> args[] = { recv, fun, pos, is_global };
661  MaybeHandle<Object> maybe_result =
662  TryCall(isolate->get_stack_trace_line_fun(),
663  isolate->js_builtins_object(),
664  arraysize(args),
665  args);
666  Handle<Object> result;
667  if (!maybe_result.ToHandle(&result) || !result->IsString()) {
668  return isolate->factory()->empty_string();
669  }
670 
671  return Handle<String>::cast(result);
672 }
673 
674 
675 Object* StackGuard::HandleInterrupts() {
676  if (CheckAndClearInterrupt(GC_REQUEST)) {
677  isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt");
678  }
679 
680  if (CheckDebugBreak() || CheckDebugCommand()) {
681  isolate_->debug()->HandleDebugBreak();
682  }
683 
684  if (CheckAndClearInterrupt(TERMINATE_EXECUTION)) {
685  return isolate_->TerminateExecution();
686  }
687 
688  if (CheckAndClearInterrupt(DEOPT_MARKED_ALLOCATION_SITES)) {
689  isolate_->heap()->DeoptMarkedAllocationSites();
690  }
691 
692  if (CheckAndClearInterrupt(INSTALL_CODE)) {
693  DCHECK(isolate_->concurrent_recompilation_enabled());
694  isolate_->optimizing_compiler_thread()->InstallOptimizedFunctions();
695  }
696 
697  if (CheckAndClearInterrupt(API_INTERRUPT)) {
698  // Callback must be invoked outside of ExecusionAccess lock.
699  isolate_->InvokeApiInterruptCallback();
700  }
701 
702  isolate_->counters()->stack_interrupts()->Increment();
703  isolate_->counters()->runtime_profiler_ticks()->Increment();
704  isolate_->runtime_profiler()->OptimizeNow();
705 
706  return isolate_->heap()->undefined_value();
707 }
708 
709 } } // namespace v8::internal
An object reference managed by the v8 garbage collector.
Definition: v8.h:198
Isolate represents an isolated instance of the V8 engine.
Definition: v8.h:4356
A JavaScript object (ECMA-262, 4.3.3)
Definition: v8.h:2283
An external exception handler.
Definition: v8.h:5271
void SetVerbose(bool value)
Set verbosity of the external exception handler.
Definition: api.cc:2046
void SetCaptureMessage(bool value)
Set whether or not this TryCatch should capture a Message object which holds source information about...
Definition: api.cc:2051
Local< Value > Exception() const
Returns the exception caught by this try/catch block.
Definition: api.cc:1976
bool HasCaught() const
Returns true if an exception has been caught by this try/catch block.
Definition: api.cc:1954
static v8::internal::Handle< To > OpenHandle(v8::Local< From > handle)
Definition: api.h:288
bool is_active() const
Definition: debug.h:465
void ClearStepping()
Definition: debug.cc:1643
Object * ThrowIllegalOperation()
Definition: isolate.cc:852
void clear_pending_message()
Definition: isolate.h:588
void ReportPendingMessages()
Definition: isolate.cc:1194
Factory * factory()
Definition: isolate.h:982
bool has_pending_exception()
Definition: isolate.h:581
#define RETURN_NATIVE_CALL(name, args)
Definition: execution.cc:483
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in only print modified registers Trace simulator debug messages Implied by trace sim abort randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot A filename with extra code to be included in the A file to write the raw snapshot bytes to(mksnapshot only)") DEFINE_STRING(raw_context_file
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call, T)
Definition: isolate.h:135
#define THROW_NEW_ERROR(isolate, call, T)
Definition: isolate.h:138
#define CHECK(condition)
Definition: logging.h:36
#define DCHECK(condition)
Definition: logging.h:205
#define arraysize(array)
Definition: macros.h:86
#define MUST_USE_RESULT
Definition: macros.h:266
const int KB
Definition: globals.h:106
int ToNumber(Register reg)
kSerializedDataOffset Object
Definition: objects-inl.h:5322
Handle< T > handle(T *t, Isolate *isolate)
Definition: handles.h:146
DISABLE_ASAN uintptr_t GetCurrentStackPosition()
Definition: utils.h:1460
kFeedbackVectorOffset flag
Definition: objects-inl.h:5418
void MemCopy(void *dest, const void *src, size_t size)
Definition: utils.h:350
static MUST_USE_RESULT MaybeHandle< Object > Invoke(bool is_construct, Handle< JSFunction > function, Handle< Object > receiver, int argc, Handle< Object > args[])
Definition: execution.cc:37
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4)
Definition: simulator-arm.h:25