16 StackGuard::StackGuard()
21 void StackGuard::set_interrupt_limits(
const ExecutionAccess& lock) {
23 thread_local_.jslimit_ = kInterruptLimit;
24 thread_local_.climit_ = kInterruptLimit;
25 isolate_->heap()->SetStackLimits();
29 void StackGuard::reset_limits(
const ExecutionAccess& lock) {
31 thread_local_.jslimit_ = thread_local_.real_jslimit_;
32 thread_local_.climit_ = thread_local_.real_climit_;
33 isolate_->heap()->SetStackLimits();
43 Isolate* isolate =
function->GetIsolate();
47 CHECK(AllowJavascriptExecution::IsAllowed(isolate));
48 if (!ThrowOnJavascriptExecution::IsAllowed(isolate)) {
57 typedef Object* (*JSEntryFunction)(
byte* entry,
64 ? isolate->
factory()->js_construct_entry_code()
65 : isolate->
factory()->js_entry_code();
70 if (receiver->IsGlobalObject()) {
76 DCHECK(function->context()->global_object()->IsGlobalObject());
81 SaveContext save(isolate);
82 SealHandleScope shs(isolate);
83 JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
86 byte* function_entry =
function->code()->entry();
95 value->ObjectVerify();
99 bool has_exception = value->IsException();
116 MaybeHandle<Object> Execution::Call(
Isolate* isolate,
121 bool convert_receiver) {
122 if (!callable->IsJSFunction()) {
124 isolate, callable, TryGetFunctionDelegate(isolate, callable),
Object);
126 Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
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());
137 isolate, receiver, ToObject(isolate, receiver),
Object);
141 return Invoke(
false, func, receiver, argc, argv);
145 MaybeHandle<Object> Execution::New(Handle<JSFunction> func,
147 Handle<Object> argv[]) {
148 return Invoke(
true, func,
handle(func->global_proxy()), argc, argv);
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>();
169 maybe_result =
Invoke(
false, func, receiver, argc, args);
171 if (maybe_result.is_null()) {
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;
183 isolate->OptionalRescheduleException(
true);
186 DCHECK(!isolate->has_pending_exception());
187 DCHECK(!isolate->external_caught_exception());
189 if (is_termination) isolate->TerminateExecution();
194 Handle<Object> Execution::GetFunctionDelegate(Isolate* isolate,
195 Handle<Object>
object) {
196 DCHECK(!object->IsJSFunction());
197 Factory* factory = isolate->factory();
204 while (fun->IsJSFunctionProxy()) {
205 fun = JSFunctionProxy::cast(fun)->call_trap();
207 if (fun->IsJSFunction())
return Handle<Object>(fun, isolate);
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());
217 return factory->undefined_value();
221 MaybeHandle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate,
222 Handle<Object>
object) {
223 DCHECK(!object->IsJSFunction());
227 while (fun->IsJSFunctionProxy()) {
228 fun = JSFunctionProxy::cast(fun)->call_trap();
230 if (fun->IsJSFunction())
return Handle<Object>(fun, isolate);
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());
243 i::HandleVector<i::Object>(&
object, 1)),
248 Handle<Object> Execution::GetConstructorDelegate(Isolate* isolate,
249 Handle<Object>
object) {
250 DCHECK(!object->IsJSFunction());
257 while (fun->IsJSFunctionProxy()) {
258 fun = JSFunctionProxy::cast(fun)->call_trap();
260 if (fun->IsJSFunction())
return Handle<Object>(fun, isolate);
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());
270 return isolate->factory()->undefined_value();
274 MaybeHandle<Object> Execution::TryGetConstructorDelegate(
275 Isolate* isolate, Handle<Object>
object) {
276 DCHECK(!object->IsJSFunction());
283 while (fun->IsJSFunctionProxy()) {
284 fun = JSFunctionProxy::cast(fun)->call_trap();
286 if (fun->IsJSFunction())
return Handle<Object>(fun, isolate);
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());
299 i::HandleVector<i::Object>(&
object, 1)),
304 void StackGuard::EnableInterrupts() {
305 ExecutionAccess access(isolate_);
306 if (has_pending_interrupts(access)) {
307 set_interrupt_limits(access);
312 void StackGuard::SetStackLimit(
uintptr_t limit) {
313 ExecutionAccess access(isolate_);
316 uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit);
317 if (thread_local_.jslimit_ == thread_local_.real_jslimit_) {
318 thread_local_.jslimit_ = jslimit;
320 if (thread_local_.climit_ == thread_local_.real_climit_) {
321 thread_local_.climit_ = limit;
323 thread_local_.real_climit_ = limit;
324 thread_local_.real_jslimit_ = jslimit;
328 void StackGuard::DisableInterrupts() {
329 ExecutionAccess access(isolate_);
330 reset_limits(access);
334 void StackGuard::PushPostponeInterruptsScope(PostponeInterruptsScope* scope) {
335 ExecutionAccess access(isolate_);
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);
342 scope->prev_ = thread_local_.postpone_interrupts_;
343 thread_local_.postpone_interrupts_ = scope;
347 void StackGuard::PopPostponeInterruptsScope() {
348 ExecutionAccess access(isolate_);
349 PostponeInterruptsScope* top = thread_local_.postpone_interrupts_;
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);
355 thread_local_.postpone_interrupts_ = top->prev_;
359 bool StackGuard::CheckInterrupt(InterruptFlag
flag) {
360 ExecutionAccess access(isolate_);
361 return thread_local_.interrupt_flags_ &
flag;
365 void StackGuard::RequestInterrupt(InterruptFlag
flag) {
366 ExecutionAccess access(isolate_);
368 if (thread_local_.postpone_interrupts_ &&
369 thread_local_.postpone_interrupts_->Intercept(
flag)) {
374 thread_local_.interrupt_flags_ |=
flag;
375 set_interrupt_limits(access);
379 void StackGuard::ClearInterrupt(InterruptFlag
flag) {
380 ExecutionAccess access(isolate_);
382 for (PostponeInterruptsScope* current = thread_local_.postpone_interrupts_;
384 current = current->prev_) {
385 current->intercepted_flags_ &= ~
flag;
389 thread_local_.interrupt_flags_ &= ~
flag;
390 if (!has_pending_interrupts(access)) reset_limits(access);
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);
403 char* StackGuard::ArchiveStackGuard(
char*
to) {
404 ExecutionAccess access(isolate_);
405 MemCopy(
to,
reinterpret_cast<char*
>(&thread_local_),
sizeof(ThreadLocal));
413 isolate_->heap()->SetStackLimits();
414 thread_local_ = blank;
416 return to +
sizeof(ThreadLocal);
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);
428 void StackGuard::FreeThreadResources() {
429 Isolate::PerIsolateThreadData* per_thread =
430 isolate_->FindOrAllocatePerThreadDataForThisThread();
431 per_thread->set_stack_limit(thread_local_.real_climit_);
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;
445 bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
446 bool should_set_stack_limits =
false;
447 if (real_climit_ == kIllegalLimit) {
451 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
452 jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
453 real_climit_ = limit;
455 should_set_stack_limits =
true;
457 postpone_interrupts_ =
NULL;
458 interrupt_flags_ = 0;
459 return should_set_stack_limits;
463 void StackGuard::ClearThread(
const ExecutionAccess& lock) {
464 thread_local_.Clear();
465 isolate_->heap()->SetStackLimits();
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();
475 if (stored_limit != 0) {
476 SetStackLimit(stored_limit);
483 #define RETURN_NATIVE_CALL(name, args) \
485 Handle<Object> argv[] = args; \
486 return Call(isolate, \
487 isolate->name##_fun(), \
488 isolate->js_builtins_object(), \
489 arraysize(argv), argv); \
494 Isolate* isolate, Handle<Object> obj) {
499 MaybeHandle<Object> Execution::ToString(
500 Isolate* isolate, Handle<Object> obj) {
505 MaybeHandle<Object> Execution::ToDetailString(
506 Isolate* isolate, Handle<Object> obj) {
511 MaybeHandle<Object> Execution::ToObject(
512 Isolate* isolate, Handle<Object> obj) {
513 if (obj->IsSpecObject())
return obj;
518 MaybeHandle<Object> Execution::ToInteger(
519 Isolate* isolate, Handle<Object> obj) {
524 MaybeHandle<Object> Execution::ToUint32(
525 Isolate* isolate, Handle<Object> obj) {
530 MaybeHandle<Object> Execution::ToInt32(
531 Isolate* isolate, Handle<Object> obj) {
536 MaybeHandle<Object> Execution::NewDate(Isolate* isolate,
double time) {
537 Handle<Object> time_obj = isolate->factory()->NewNumber(time);
542 #undef RETURN_NATIVE_CALL
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;
553 RegExpImpl::CreateRegExpLiteral(
function, pattern,
flags),
555 return Handle<JSRegExp>::cast(re_obj);
559 Handle<Object> Execution::CharAt(Handle<String>
string,
uint32_t index) {
560 Isolate* isolate =
string->GetIsolate();
561 Factory* factory = isolate->factory();
563 int int_index =
static_cast<int>(index);
564 if (int_index < 0 || int_index >= string->length()) {
565 return factory->undefined_value();
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();
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),
581 index_arg).ToHandle(&result)) {
582 return factory->undefined_value();
588 MaybeHandle<JSFunction> Execution::InstantiateFunction(
589 Handle<FunctionTemplateInfo> data) {
590 Isolate* isolate = data->GetIsolate();
591 if (!data->do_not_cache()) {
593 int serial_number = Smi::cast(data->serial_number())->value();
594 Handle<JSObject> cache(isolate->native_context()->function_cache());
596 Object::GetElement(isolate, cache, serial_number).ToHandleChecked();
597 if (elm->IsJSFunction())
return Handle<JSFunction>::cast(elm);
600 Handle<Object> args[] = { data };
601 Handle<Object> result;
605 isolate->instantiate_fun(),
606 isolate->js_builtins_object(),
610 return Handle<JSFunction>::cast(result);
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);
628 Handle<Object> args[] = { data };
632 isolate->instantiate_fun(),
633 isolate->js_builtins_object(),
638 return Handle<JSObject>::cast(result);
642 MaybeHandle<Object> Execution::ConfigureInstance(
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(),
655 Handle<String> Execution::GetStackTraceLine(Handle<Object> recv,
656 Handle<JSFunction> fun,
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(),
666 Handle<Object> result;
667 if (!maybe_result.ToHandle(&result) || !result->IsString()) {
668 return isolate->factory()->empty_string();
671 return Handle<String>::cast(result);
675 Object* StackGuard::HandleInterrupts() {
676 if (CheckAndClearInterrupt(GC_REQUEST)) {
677 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags,
"GC interrupt");
680 if (CheckDebugBreak() || CheckDebugCommand()) {
681 isolate_->debug()->HandleDebugBreak();
684 if (CheckAndClearInterrupt(TERMINATE_EXECUTION)) {
685 return isolate_->TerminateExecution();
688 if (CheckAndClearInterrupt(DEOPT_MARKED_ALLOCATION_SITES)) {
689 isolate_->heap()->DeoptMarkedAllocationSites();
692 if (CheckAndClearInterrupt(INSTALL_CODE)) {
693 DCHECK(isolate_->concurrent_recompilation_enabled());
694 isolate_->optimizing_compiler_thread()->InstallOptimizedFunctions();
697 if (CheckAndClearInterrupt(API_INTERRUPT)) {
699 isolate_->InvokeApiInterruptCallback();
702 isolate_->counters()->stack_interrupts()->Increment();
703 isolate_->counters()->runtime_profiler_ticks()->Increment();
704 isolate_->runtime_profiler()->OptimizeNow();
706 return isolate_->heap()->undefined_value();
An object reference managed by the v8 garbage collector.
Isolate represents an isolated instance of the V8 engine.
A JavaScript object (ECMA-262, 4.3.3)
An external exception handler.
void SetVerbose(bool value)
Set verbosity of the external exception handler.
void SetCaptureMessage(bool value)
Set whether or not this TryCatch should capture a Message object which holds source information about...
Local< Value > Exception() const
Returns the exception caught by this try/catch block.
bool HasCaught() const
Returns true if an exception has been caught by this try/catch block.
static v8::internal::Handle< To > OpenHandle(v8::Local< From > handle)
Object * ThrowIllegalOperation()
void clear_pending_message()
void ReportPendingMessages()
bool has_pending_exception()
#define RETURN_NATIVE_CALL(name, args)
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)
#define THROW_NEW_ERROR(isolate, call, T)
#define DCHECK(condition)
int ToNumber(Register reg)
kSerializedDataOffset Object
Handle< T > handle(T *t, Isolate *isolate)
DISABLE_ASAN uintptr_t GetCurrentStackPosition()
kFeedbackVectorOffset flag
void MemCopy(void *dest, const void *src, size_t size)
static MUST_USE_RESULT MaybeHandle< Object > Invoke(bool is_construct, Handle< JSFunction > function, Handle< Object > receiver, int argc, Handle< Object > args[])
Debugger support for the V8 JavaScript engine.
#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4)