5 #include "src/arguments-inl.h" 6 #include "src/asmjs/asm-js.h" 7 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" 8 #include "src/compiler.h" 9 #include "src/deoptimizer.h" 10 #include "src/frames-inl.h" 11 #include "src/isolate-inl.h" 12 #include "src/message-template.h" 13 #include "src/objects/js-array-buffer-inl.h" 14 #include "src/objects/js-array-inl.h" 15 #include "src/runtime/runtime-utils.h" 16 #include "src/v8threads.h" 17 #include "src/vm-state-inl.h" 22 RUNTIME_FUNCTION(Runtime_CompileLazy) {
23 HandleScope scope(isolate);
24 DCHECK_EQ(1, args.length());
25 CONVERT_ARG_HANDLE_CHECKED(JSFunction,
function, 0);
28 if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
29 PrintF(
"[unoptimized: ");
30 function->PrintName();
35 StackLimitCheck check(isolate);
36 if (check.JsHasOverflowed(kStackSpaceRequiredForCompilation * KB)) {
37 return isolate->StackOverflow();
39 if (!Compiler::Compile(
function, Compiler::KEEP_EXCEPTION)) {
40 return ReadOnlyRoots(isolate).exception();
42 DCHECK(function->is_compiled());
43 return function->code();
46 RUNTIME_FUNCTION(Runtime_CompileOptimized_Concurrent) {
47 HandleScope scope(isolate);
48 DCHECK_EQ(1, args.length());
49 CONVERT_ARG_HANDLE_CHECKED(JSFunction,
function, 0);
50 StackLimitCheck check(isolate);
51 if (check.JsHasOverflowed(kStackSpaceRequiredForCompilation * KB)) {
52 return isolate->StackOverflow();
54 if (!Compiler::CompileOptimized(
function, ConcurrencyMode::kConcurrent)) {
55 return ReadOnlyRoots(isolate).exception();
57 DCHECK(function->is_compiled());
58 return function->code();
61 RUNTIME_FUNCTION(Runtime_FunctionFirstExecution) {
62 HandleScope scope(isolate);
63 StackLimitCheck check(isolate);
64 DCHECK_EQ(1, args.length());
66 CONVERT_ARG_HANDLE_CHECKED(JSFunction,
function, 0);
67 DCHECK_EQ(function->feedback_vector()->optimization_marker(),
68 OptimizationMarker::kLogFirstExecution);
69 DCHECK(FLAG_log_function_events);
70 Handle<SharedFunctionInfo> sfi(function->shared(), isolate);
71 LOG(isolate, FunctionEvent(
72 "first-execution", Script::cast(sfi->script())->
id(), 0,
73 sfi->StartPosition(), sfi->EndPosition(), sfi->DebugName()));
74 function->feedback_vector()->ClearOptimizationMarker();
77 return function->code();
80 RUNTIME_FUNCTION(Runtime_CompileOptimized_NotConcurrent) {
81 HandleScope scope(isolate);
82 DCHECK_EQ(1, args.length());
83 CONVERT_ARG_HANDLE_CHECKED(JSFunction,
function, 0);
84 StackLimitCheck check(isolate);
85 if (check.JsHasOverflowed(kStackSpaceRequiredForCompilation * KB)) {
86 return isolate->StackOverflow();
88 if (!Compiler::CompileOptimized(
function, ConcurrencyMode::kNotConcurrent)) {
89 return ReadOnlyRoots(isolate).exception();
91 DCHECK(function->is_compiled());
92 return function->code();
95 RUNTIME_FUNCTION(Runtime_EvictOptimizedCodeSlot) {
96 SealHandleScope scope(isolate);
97 DCHECK_EQ(1, args.length());
98 CONVERT_ARG_HANDLE_CHECKED(JSFunction,
function, 0);
100 DCHECK(function->shared()->is_compiled());
102 function->feedback_vector()->EvictOptimizedCodeMarkedForDeoptimization(
103 function->shared(),
"Runtime_EvictOptimizedCodeSlot");
104 return function->code();
107 RUNTIME_FUNCTION(Runtime_InstantiateAsmJs) {
108 HandleScope scope(isolate);
109 DCHECK_EQ(args.length(), 4);
110 CONVERT_ARG_HANDLE_CHECKED(JSFunction,
function, 0);
112 Handle<JSReceiver> stdlib;
113 if (args[1]->IsJSReceiver()) {
114 stdlib = args.at<JSReceiver>(1);
116 Handle<JSReceiver> foreign;
117 if (args[2]->IsJSReceiver()) {
118 foreign = args.at<JSReceiver>(2);
120 Handle<JSArrayBuffer> memory;
121 if (args[3]->IsJSArrayBuffer()) {
122 memory = args.at<JSArrayBuffer>(3);
124 if (function->shared()->HasAsmWasmData()) {
125 Handle<SharedFunctionInfo> shared(function->shared(), isolate);
126 Handle<AsmWasmData> data(shared->asm_wasm_data(), isolate);
127 MaybeHandle<Object> result = AsmJs::InstantiateAsmWasm(
128 isolate, shared, data, stdlib, foreign, memory);
129 if (!result.is_null()) {
130 return *result.ToHandleChecked();
135 if (function->shared()->HasAsmWasmData()) {
136 SharedFunctionInfo::DiscardCompiled(isolate,
137 handle(function->shared(), isolate));
139 function->shared()->set_is_asm_wasm_broken(
true);
140 DCHECK(function->code() ==
141 isolate->builtins()->builtin(Builtins::kInstantiateAsmJs));
142 function->set_code(isolate->builtins()->builtin(Builtins::kCompileLazy));
146 RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {
147 HandleScope scope(isolate);
148 DCHECK_EQ(0, args.length());
149 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
150 DCHECK(deoptimizer->compiled_code()->kind() == Code::OPTIMIZED_FUNCTION);
151 DCHECK(deoptimizer->compiled_code()->is_turbofanned());
152 DCHECK(AllowHeapAllocation::IsAllowed());
153 DCHECK(isolate->context().is_null());
155 TimerEventScope<TimerEventDeoptimizeCode> timer(isolate);
156 TRACE_EVENT0(
"v8",
"V8.DeoptimizeCode");
157 Handle<JSFunction>
function = deoptimizer->function();
158 DeoptimizeKind type = deoptimizer->deopt_kind();
162 isolate->set_context(deoptimizer->function()->native_context());
165 deoptimizer->MaterializeHeapObjects();
169 JavaScriptFrameIterator top_it(isolate);
170 JavaScriptFrame* top_frame = top_it.frame();
171 isolate->set_context(Context::cast(top_frame->context()));
174 if (type != DeoptimizeKind::kLazy) {
175 Deoptimizer::DeoptimizeFunction(*
function);
178 return ReadOnlyRoots(isolate).undefined_value();
182 static bool IsSuitableForOnStackReplacement(Isolate* isolate,
183 Handle<JSFunction>
function) {
185 if (function->shared()->optimization_disabled())
return false;
191 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
192 JavaScriptFrame* frame = it.frame();
193 if (frame->is_optimized() && frame->function() == *
function)
return false;
201 BailoutId DetermineEntryAndDisarmOSRForInterpreter(JavaScriptFrame* frame) {
202 InterpretedFrame* iframe =
reinterpret_cast<InterpretedFrame*
>(frame);
208 Handle<BytecodeArray> bytecode(iframe->GetBytecodeArray(), iframe->isolate());
210 DCHECK(frame->LookupCode()->is_interpreter_trampoline_builtin());
211 DCHECK(frame->function()->shared()->HasBytecodeArray());
212 DCHECK(frame->is_interpreted());
215 bytecode->set_osr_loop_nesting_level(0);
218 return BailoutId(iframe->GetBytecodeOffset());
223 RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
224 HandleScope scope(isolate);
225 DCHECK_EQ(1, args.length());
226 CONVERT_ARG_HANDLE_CHECKED(JSFunction,
function, 0);
232 JavaScriptFrameIterator it(isolate);
233 JavaScriptFrame* frame = it.frame();
234 DCHECK_EQ(frame->function(), *
function);
235 DCHECK(frame->is_interpreted());
239 BailoutId ast_id = DetermineEntryAndDisarmOSRForInterpreter(frame);
240 DCHECK(!ast_id.IsNone());
242 MaybeHandle<Code> maybe_result;
243 if (IsSuitableForOnStackReplacement(isolate,
function)) {
244 if (FLAG_trace_osr) {
245 PrintF(
"[OSR - Compiling: ");
246 function->PrintName();
247 PrintF(
" at AST id %d]\n", ast_id.ToInt());
249 maybe_result = Compiler::GetOptimizedCodeForOSR(
function, ast_id, frame);
254 if (maybe_result.ToHandle(&result) &&
255 result->kind() == Code::OPTIMIZED_FUNCTION) {
256 DeoptimizationData data =
257 DeoptimizationData::cast(result->deoptimization_data());
259 if (data->OsrPcOffset()->value() >= 0) {
260 DCHECK(BailoutId(data->OsrBytecodeOffset()->value()) == ast_id);
261 if (FLAG_trace_osr) {
262 PrintF(
"[OSR - Entry at AST id %d, offset %d in optimized code]\n",
263 ast_id.ToInt(), data->OsrPcOffset()->value());
266 DCHECK(result->is_turbofanned());
267 if (!function->HasOptimizedCode()) {
271 if (FLAG_trace_osr) {
272 PrintF(
"[OSR - Re-marking ");
273 function->PrintName();
274 PrintF(
" for non-concurrent optimization]\n");
276 function->SetOptimizationMarker(OptimizationMarker::kCompileOptimized);
283 if (FLAG_trace_osr) {
284 PrintF(
"[OSR - Failed: ");
285 function->PrintName();
286 PrintF(
" at AST id %d]\n", ast_id.ToInt());
289 if (!function->IsOptimized()) {
290 function->set_code(function->shared()->GetCode());
295 static Object* CompileGlobalEval(Isolate* isolate, Handle<String> source,
296 Handle<SharedFunctionInfo> outer_info,
297 LanguageMode language_mode,
298 int eval_scope_position,
int eval_position) {
299 Handle<Context> context(isolate->context(), isolate);
300 Handle<Context> native_context(context->native_context(), isolate);
304 if (native_context->allow_code_gen_from_strings()->IsFalse(isolate) &&
305 !Compiler::CodeGenerationFromStringsAllowed(isolate, native_context,
307 Handle<Object> error_message =
308 native_context->ErrorMessageForCodeGenerationFromStrings();
309 Handle<Object> error;
310 MaybeHandle<Object> maybe_error = isolate->factory()->NewEvalError(
311 MessageTemplate::kCodeGenFromStrings, error_message);
312 if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
313 return ReadOnlyRoots(isolate).exception();
318 static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
319 Handle<JSFunction> compiled;
320 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
322 Compiler::GetFunctionFromEval(source, outer_info, context, language_mode,
323 restriction, kNoSourcePosition,
324 eval_scope_position, eval_position),
325 ReadOnlyRoots(isolate).exception());
330 RUNTIME_FUNCTION(Runtime_ResolvePossiblyDirectEval) {
331 HandleScope scope(isolate);
332 DCHECK_EQ(6, args.length());
334 Handle<Object> callee = args.at(0);
341 if (*callee != isolate->native_context()->global_eval_fun() ||
342 !args[1]->IsString()) {
346 DCHECK(args[3]->IsSmi());
347 DCHECK(is_valid_language_mode(args.smi_at(3)));
348 LanguageMode language_mode =
static_cast<LanguageMode
>(args.smi_at(3));
349 DCHECK(args[4]->IsSmi());
350 Handle<SharedFunctionInfo> outer_info(args.at<JSFunction>(2)->shared(),
352 return CompileGlobalEval(isolate, args.at<String>(1), outer_info,
353 language_mode, args.smi_at(4), args.smi_at(5));