blob: b5910e4d3b25740cf4c7fcba957451731ca5cb4f [file] [log] [blame]
Emily Bernier958fae72015-03-24 16:35:39 -04001// 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
Ben Murdoch014dc512016-03-22 12:00:34 +00005#include "src/runtime/runtime-utils.h"
Emily Bernier958fae72015-03-24 16:35:39 -04006
7#include "src/arguments.h"
Ben Murdochf91f0612016-11-29 16:50:11 +00008#include "src/asmjs/asm-js.h"
9#include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
Emily Bernier958fae72015-03-24 16:35:39 -040010#include "src/compiler.h"
11#include "src/deoptimizer.h"
Ben Murdoch014dc512016-03-22 12:00:34 +000012#include "src/frames-inl.h"
13#include "src/full-codegen/full-codegen.h"
Emily Bernier958fae72015-03-24 16:35:39 -040014#include "src/isolate-inl.h"
Ben Murdoch014dc512016-03-22 12:00:34 +000015#include "src/messages.h"
Emily Bernier958fae72015-03-24 16:35:39 -040016#include "src/v8threads.h"
17#include "src/vm-state-inl.h"
18
19namespace v8 {
20namespace internal {
21
22RUNTIME_FUNCTION(Runtime_CompileLazy) {
23 HandleScope scope(isolate);
Ben Murdochbcf72ee2016-08-08 18:44:38 +010024 DCHECK_EQ(1, args.length());
Emily Bernier958fae72015-03-24 16:35:39 -040025 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010026
Emily Bernier958fae72015-03-24 16:35:39 -040027#ifdef DEBUG
28 if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
29 PrintF("[unoptimized: ");
30 function->PrintName();
31 PrintF("]\n");
32 }
33#endif
Ben Murdoch3b9bc312016-06-02 14:46:10 +010034
Ben Murdoch014dc512016-03-22 12:00:34 +000035 StackLimitCheck check(isolate);
36 if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow();
Ben Murdoch3b9bc312016-06-02 14:46:10 +010037 if (!Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) {
38 return isolate->heap()->exception();
Emily Bernier958fae72015-03-24 16:35:39 -040039 }
Ben Murdoch3b9bc312016-06-02 14:46:10 +010040 DCHECK(function->is_compiled());
Emily Bernier958fae72015-03-24 16:35:39 -040041 return function->code();
42}
43
Ben Murdochbcf72ee2016-08-08 18:44:38 +010044RUNTIME_FUNCTION(Runtime_CompileBaseline) {
45 HandleScope scope(isolate);
46 DCHECK_EQ(1, args.length());
47 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
48 StackLimitCheck check(isolate);
49 if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow();
50 if (!Compiler::CompileBaseline(function)) {
51 return isolate->heap()->exception();
52 }
53 DCHECK(function->is_compiled());
54 return function->code();
55}
Ben Murdoch014dc512016-03-22 12:00:34 +000056
57RUNTIME_FUNCTION(Runtime_CompileOptimized_Concurrent) {
58 HandleScope scope(isolate);
Ben Murdochbcf72ee2016-08-08 18:44:38 +010059 DCHECK_EQ(1, args.length());
Ben Murdoch014dc512016-03-22 12:00:34 +000060 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010061 StackLimitCheck check(isolate);
62 if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow();
63 if (!Compiler::CompileOptimized(function, Compiler::CONCURRENT)) {
64 return isolate->heap()->exception();
65 }
66 DCHECK(function->is_compiled());
67 return function->code();
Ben Murdoch014dc512016-03-22 12:00:34 +000068}
69
70
71RUNTIME_FUNCTION(Runtime_CompileOptimized_NotConcurrent) {
72 HandleScope scope(isolate);
Ben Murdochbcf72ee2016-08-08 18:44:38 +010073 DCHECK_EQ(1, args.length());
Ben Murdoch014dc512016-03-22 12:00:34 +000074 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010075 StackLimitCheck check(isolate);
76 if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow();
77 if (!Compiler::CompileOptimized(function, Compiler::NOT_CONCURRENT)) {
78 return isolate->heap()->exception();
79 }
80 DCHECK(function->is_compiled());
81 return function->code();
Ben Murdoch014dc512016-03-22 12:00:34 +000082}
83
Ben Murdochf91f0612016-11-29 16:50:11 +000084RUNTIME_FUNCTION(Runtime_InstantiateAsmJs) {
85 HandleScope scope(isolate);
86 DCHECK_EQ(args.length(), 4);
87 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
88
89 Handle<JSReceiver> stdlib;
90 if (args[1]->IsJSReceiver()) {
91 stdlib = args.at<JSReceiver>(1);
92 }
93 Handle<JSObject> foreign;
94 if (args[2]->IsJSObject()) {
95 foreign = args.at<i::JSObject>(2);
96 }
97 Handle<JSArrayBuffer> memory;
98 if (args[3]->IsJSArrayBuffer()) {
99 memory = args.at<i::JSArrayBuffer>(3);
100 }
101 if (function->shared()->HasAsmWasmData() &&
102 AsmJs::IsStdlibValid(isolate, handle(function->shared()->asm_wasm_data()),
103 stdlib)) {
104 MaybeHandle<Object> result;
105 result = AsmJs::InstantiateAsmWasm(
106 isolate, handle(function->shared()->asm_wasm_data()), memory, foreign);
107 if (!result.is_null()) {
108 return *result.ToHandleChecked();
109 }
110 }
111 // Remove wasm data, mark as broken for asm->wasm,
112 // replace code with CompileLazy, and return a smi 0 to indicate failure.
113 if (function->shared()->HasAsmWasmData()) {
114 function->shared()->ClearAsmWasmData();
115 }
116 function->shared()->set_is_asm_wasm_broken(true);
117 DCHECK(function->code() ==
118 isolate->builtins()->builtin(Builtins::kInstantiateAsmJs));
119 function->ReplaceCode(isolate->builtins()->builtin(Builtins::kCompileLazy));
120 if (function->shared()->code() ==
121 isolate->builtins()->builtin(Builtins::kInstantiateAsmJs)) {
122 function->shared()->ReplaceCode(
123 isolate->builtins()->builtin(Builtins::kCompileLazy));
124 }
125 return Smi::FromInt(0);
126}
Emily Bernier958fae72015-03-24 16:35:39 -0400127
128RUNTIME_FUNCTION(Runtime_NotifyStubFailure) {
129 HandleScope scope(isolate);
130 DCHECK(args.length() == 0);
131 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
132 DCHECK(AllowHeapAllocation::IsAllowed());
133 delete deoptimizer;
134 return isolate->heap()->undefined_value();
135}
136
Emily Bernier958fae72015-03-24 16:35:39 -0400137class ActivationsFinder : public ThreadVisitor {
138 public:
139 Code* code_;
140 bool has_code_activations_;
141
142 explicit ActivationsFinder(Code* code)
143 : code_(code), has_code_activations_(false) {}
144
145 void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
146 JavaScriptFrameIterator it(isolate, top);
147 VisitFrames(&it);
148 }
149
150 void VisitFrames(JavaScriptFrameIterator* it) {
151 for (; !it->done(); it->Advance()) {
152 JavaScriptFrame* frame = it->frame();
153 if (code_->contains(frame->pc())) has_code_activations_ = true;
154 }
155 }
156};
157
158
159RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {
160 HandleScope scope(isolate);
161 DCHECK(args.length() == 1);
162 CONVERT_SMI_ARG_CHECKED(type_arg, 0);
163 Deoptimizer::BailoutType type =
164 static_cast<Deoptimizer::BailoutType>(type_arg);
165 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
166 DCHECK(AllowHeapAllocation::IsAllowed());
Ben Murdoch109988c2016-05-18 11:27:45 +0100167 TimerEventScope<TimerEventDeoptimizeCode> timer(isolate);
168 TRACE_EVENT0("v8", "V8.DeoptimizeCode");
Emily Bernier958fae72015-03-24 16:35:39 -0400169
170 Handle<JSFunction> function = deoptimizer->function();
171 Handle<Code> optimized_code = deoptimizer->compiled_code();
172
173 DCHECK(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
174 DCHECK(type == deoptimizer->bailout_type());
175
176 // Make sure to materialize objects before causing any allocation.
177 JavaScriptFrameIterator it(isolate);
178 deoptimizer->MaterializeHeapObjects(&it);
179 delete deoptimizer;
180
Ben Murdoch014dc512016-03-22 12:00:34 +0000181 // Ensure the context register is updated for materialized objects.
182 JavaScriptFrameIterator top_it(isolate);
183 JavaScriptFrame* top_frame = top_it.frame();
184 isolate->set_context(Context::cast(top_frame->context()));
185
186 if (type == Deoptimizer::LAZY) {
Emily Bernier958fae72015-03-24 16:35:39 -0400187 return isolate->heap()->undefined_value();
188 }
189
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100190 // Search for other activations of the same optimized code.
191 // At this point {it} is at the topmost frame of all the frames materialized
192 // by the deoptimizer. Note that this frame does not necessarily represent
193 // an activation of {function} because of potential inlined tail-calls.
Emily Bernier958fae72015-03-24 16:35:39 -0400194 ActivationsFinder activations_finder(*optimized_code);
195 activations_finder.VisitFrames(&it);
196 isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
197
198 if (!activations_finder.has_code_activations_) {
199 if (function->code() == *optimized_code) {
200 if (FLAG_trace_deopt) {
201 PrintF("[removing optimized code for: ");
202 function->PrintName();
203 PrintF("]\n");
204 }
205 function->ReplaceCode(function->shared()->code());
Emily Bernier958fae72015-03-24 16:35:39 -0400206 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000207 // Evict optimized code for this function from the cache so that it
208 // doesn't get used for new closures.
209 function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
210 "notify deoptimized");
Emily Bernier958fae72015-03-24 16:35:39 -0400211 } else {
212 // TODO(titzer): we should probably do DeoptimizeCodeList(code)
213 // unconditionally if the code is not already marked for deoptimization.
214 // If there is an index by shared function info, all the better.
215 Deoptimizer::DeoptimizeFunction(*function);
216 }
217
218 return isolate->heap()->undefined_value();
219}
220
221
222static bool IsSuitableForOnStackReplacement(Isolate* isolate,
Ben Murdoch014dc512016-03-22 12:00:34 +0000223 Handle<JSFunction> function) {
Emily Bernier958fae72015-03-24 16:35:39 -0400224 // Keep track of whether we've succeeded in optimizing.
Ben Murdoch014dc512016-03-22 12:00:34 +0000225 if (function->shared()->optimization_disabled()) return false;
Emily Bernier958fae72015-03-24 16:35:39 -0400226 // If we are trying to do OSR when there are already optimized
227 // activations of the function, it means (a) the function is directly or
228 // indirectly recursive and (b) an optimized invocation has been
229 // deoptimized so that we are currently in an unoptimized activation.
230 // Check for optimized activations of this function.
231 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
232 JavaScriptFrame* frame = it.frame();
233 if (frame->is_optimized() && frame->function() == *function) return false;
234 }
235
236 return true;
237}
238
Ben Murdochf91f0612016-11-29 16:50:11 +0000239namespace {
Emily Bernier958fae72015-03-24 16:35:39 -0400240
Ben Murdochf91f0612016-11-29 16:50:11 +0000241BailoutId DetermineEntryAndDisarmOSRForBaseline(JavaScriptFrame* frame) {
242 Handle<Code> caller_code(frame->function()->shared()->code());
Emily Bernier958fae72015-03-24 16:35:39 -0400243
Ben Murdochf91f0612016-11-29 16:50:11 +0000244 // Passing the PC in the JavaScript frame from the caller directly is
Emily Bernier958fae72015-03-24 16:35:39 -0400245 // not GC safe, so we walk the stack to get it.
Emily Bernier958fae72015-03-24 16:35:39 -0400246 if (!caller_code->contains(frame->pc())) {
247 // Code on the stack may not be the code object referenced by the shared
248 // function info. It may have been replaced to include deoptimization data.
249 caller_code = Handle<Code>(frame->LookupCode());
250 }
251
Ben Murdochf91f0612016-11-29 16:50:11 +0000252 DCHECK_EQ(frame->LookupCode(), *caller_code);
253 DCHECK_EQ(Code::FUNCTION, caller_code->kind());
254 DCHECK(caller_code->contains(frame->pc()));
255
256 // Revert the patched back edge table, regardless of whether OSR succeeds.
257 BackEdgeTable::Revert(frame->isolate(), *caller_code);
258
Emily Bernier958fae72015-03-24 16:35:39 -0400259 uint32_t pc_offset =
260 static_cast<uint32_t>(frame->pc() - caller_code->instruction_start());
261
Ben Murdochf91f0612016-11-29 16:50:11 +0000262 return caller_code->TranslatePcOffsetToAstId(pc_offset);
263}
Emily Bernier958fae72015-03-24 16:35:39 -0400264
Ben Murdochf91f0612016-11-29 16:50:11 +0000265BailoutId DetermineEntryAndDisarmOSRForInterpreter(JavaScriptFrame* frame) {
266 InterpretedFrame* iframe = reinterpret_cast<InterpretedFrame*>(frame);
267
268 // Note that the bytecode array active on the stack might be different from
269 // the one installed on the function (e.g. patched by debugger). This however
270 // is fine because we guarantee the layout to be in sync, hence any BailoutId
271 // representing the entry point will be valid for any copy of the bytecode.
272 Handle<BytecodeArray> bytecode(iframe->GetBytecodeArray());
273
274 DCHECK(frame->LookupCode()->is_interpreter_trampoline_builtin());
275 DCHECK(frame->function()->shared()->HasBytecodeArray());
276 DCHECK(frame->is_interpreted());
277 DCHECK(FLAG_ignition_osr);
278
279 // Reset the OSR loop nesting depth to disarm back edges.
280 bytecode->set_osr_loop_nesting_level(0);
281
282 return BailoutId(iframe->GetBytecodeOffset());
283}
284
285} // namespace
286
287RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
288 HandleScope scope(isolate);
289 DCHECK(args.length() == 1);
290 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
291
292 // We're not prepared to handle a function with arguments object.
293 DCHECK(!function->shared()->uses_arguments());
294
295 // Only reachable when OST is enabled.
296 CHECK(FLAG_use_osr);
297
298 // Determine frame triggering OSR request.
299 JavaScriptFrameIterator it(isolate);
300 JavaScriptFrame* frame = it.frame();
301 DCHECK_EQ(frame->function(), *function);
302
303 // Determine the entry point for which this OSR request has been fired and
304 // also disarm all back edges in the calling code to stop new requests.
305 BailoutId ast_id = frame->is_interpreted()
306 ? DetermineEntryAndDisarmOSRForInterpreter(frame)
307 : DetermineEntryAndDisarmOSRForBaseline(frame);
Emily Bernier958fae72015-03-24 16:35:39 -0400308 DCHECK(!ast_id.IsNone());
309
Ben Murdoch109988c2016-05-18 11:27:45 +0100310 MaybeHandle<Code> maybe_result;
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100311 if (IsSuitableForOnStackReplacement(isolate, function)) {
Emily Bernier958fae72015-03-24 16:35:39 -0400312 if (FLAG_trace_osr) {
313 PrintF("[OSR - Compiling: ");
314 function->PrintName();
315 PrintF(" at AST id %d]\n", ast_id.ToInt());
316 }
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100317 maybe_result = Compiler::GetOptimizedCodeForOSR(function, ast_id, frame);
Emily Bernier958fae72015-03-24 16:35:39 -0400318 }
319
Emily Bernier958fae72015-03-24 16:35:39 -0400320 // Check whether we ended up with usable optimized code.
Ben Murdoch109988c2016-05-18 11:27:45 +0100321 Handle<Code> result;
322 if (maybe_result.ToHandle(&result) &&
323 result->kind() == Code::OPTIMIZED_FUNCTION) {
Emily Bernier958fae72015-03-24 16:35:39 -0400324 DeoptimizationInputData* data =
325 DeoptimizationInputData::cast(result->deoptimization_data());
326
327 if (data->OsrPcOffset()->value() >= 0) {
328 DCHECK(BailoutId(data->OsrAstId()->value()) == ast_id);
329 if (FLAG_trace_osr) {
330 PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n",
331 ast_id.ToInt(), data->OsrPcOffset()->value());
332 }
333 // TODO(titzer): this is a massive hack to make the deopt counts
334 // match. Fix heuristics for reenabling optimizations!
335 function->shared()->increment_deopt_count();
336
Ben Murdoch014dc512016-03-22 12:00:34 +0000337 if (result->is_turbofanned()) {
338 // TurboFanned OSR code cannot be installed into the function.
339 // But the function is obviously hot, so optimize it next time.
340 function->ReplaceCode(
341 isolate->builtins()->builtin(Builtins::kCompileOptimized));
342 } else {
343 // Crankshafted OSR code can be installed into the function.
344 function->ReplaceCode(*result);
345 }
Emily Bernier958fae72015-03-24 16:35:39 -0400346 return *result;
347 }
348 }
349
350 // Failed.
351 if (FLAG_trace_osr) {
352 PrintF("[OSR - Failed: ");
353 function->PrintName();
354 PrintF(" at AST id %d]\n", ast_id.ToInt());
355 }
356
357 if (!function->IsOptimized()) {
358 function->ReplaceCode(function->shared()->code());
359 }
360 return NULL;
361}
362
363
364RUNTIME_FUNCTION(Runtime_TryInstallOptimizedCode) {
365 HandleScope scope(isolate);
366 DCHECK(args.length() == 1);
367 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
368
369 // First check if this is a real stack overflow.
370 StackLimitCheck check(isolate);
371 if (check.JsHasOverflowed()) {
372 SealHandleScope shs(isolate);
373 return isolate->StackOverflow();
374 }
375
Ben Murdoch014dc512016-03-22 12:00:34 +0000376 isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions();
Emily Bernier958fae72015-03-24 16:35:39 -0400377 return (function->IsOptimized()) ? function->code()
378 : function->shared()->code();
379}
380
381
382bool CodeGenerationFromStringsAllowed(Isolate* isolate,
383 Handle<Context> context) {
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100384 DCHECK(context->allow_code_gen_from_strings()->IsFalse(isolate));
Emily Bernier958fae72015-03-24 16:35:39 -0400385 // Check with callback if set.
386 AllowCodeGenerationFromStringsCallback callback =
387 isolate->allow_code_gen_callback();
388 if (callback == NULL) {
389 // No callback set and code generation disallowed.
390 return false;
391 } else {
392 // Callback set. Let it decide if code generation is allowed.
393 VMState<EXTERNAL> state(isolate);
394 return callback(v8::Utils::ToLocal(context));
395 }
396}
397
Ben Murdoch014dc512016-03-22 12:00:34 +0000398static Object* CompileGlobalEval(Isolate* isolate, Handle<String> source,
399 Handle<SharedFunctionInfo> outer_info,
400 LanguageMode language_mode,
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100401 int eval_scope_position, int eval_position) {
Emily Bernier958fae72015-03-24 16:35:39 -0400402 Handle<Context> context = Handle<Context>(isolate->context());
403 Handle<Context> native_context = Handle<Context>(context->native_context());
404
405 // Check if native context allows code generation from
406 // strings. Throw an exception if it doesn't.
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100407 if (native_context->allow_code_gen_from_strings()->IsFalse(isolate) &&
Emily Bernier958fae72015-03-24 16:35:39 -0400408 !CodeGenerationFromStringsAllowed(isolate, native_context)) {
409 Handle<Object> error_message =
410 native_context->ErrorMessageForCodeGenerationFromStrings();
411 Handle<Object> error;
412 MaybeHandle<Object> maybe_error = isolate->factory()->NewEvalError(
Ben Murdoch014dc512016-03-22 12:00:34 +0000413 MessageTemplate::kCodeGenFromStrings, error_message);
Emily Bernier958fae72015-03-24 16:35:39 -0400414 if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
Ben Murdoch014dc512016-03-22 12:00:34 +0000415 return isolate->heap()->exception();
Emily Bernier958fae72015-03-24 16:35:39 -0400416 }
417
418 // Deal with a normal eval call with a string argument. Compile it
419 // and return the compiled function bound in the local context.
420 static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
421 Handle<JSFunction> compiled;
422 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100423 isolate, compiled, Compiler::GetFunctionFromEval(
424 source, outer_info, context, language_mode,
425 restriction, eval_scope_position, eval_position),
Ben Murdoch014dc512016-03-22 12:00:34 +0000426 isolate->heap()->exception());
427 return *compiled;
Emily Bernier958fae72015-03-24 16:35:39 -0400428}
429
430
Ben Murdoch014dc512016-03-22 12:00:34 +0000431RUNTIME_FUNCTION(Runtime_ResolvePossiblyDirectEval) {
Emily Bernier958fae72015-03-24 16:35:39 -0400432 HandleScope scope(isolate);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100433 DCHECK(args.length() == 6);
Emily Bernier958fae72015-03-24 16:35:39 -0400434
435 Handle<Object> callee = args.at<Object>(0);
436
437 // If "eval" didn't refer to the original GlobalEval, it's not a
438 // direct call to eval.
439 // (And even if it is, but the first argument isn't a string, just let
440 // execution default to an indirect call to eval, which will also return
441 // the first argument without doing anything).
442 if (*callee != isolate->native_context()->global_eval_fun() ||
443 !args[1]->IsString()) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000444 return *callee;
Emily Bernier958fae72015-03-24 16:35:39 -0400445 }
446
Ben Murdoch014dc512016-03-22 12:00:34 +0000447 DCHECK(args[3]->IsSmi());
448 DCHECK(is_valid_language_mode(args.smi_at(3)));
449 LanguageMode language_mode = static_cast<LanguageMode>(args.smi_at(3));
Emily Bernier958fae72015-03-24 16:35:39 -0400450 DCHECK(args[4]->IsSmi());
Emily Bernier958fae72015-03-24 16:35:39 -0400451 Handle<SharedFunctionInfo> outer_info(args.at<JSFunction>(2)->shared(),
452 isolate);
453 return CompileGlobalEval(isolate, args.at<String>(1), outer_info,
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100454 language_mode, args.smi_at(4), args.smi_at(5));
Emily Bernier958fae72015-03-24 16:35:39 -0400455}
Ben Murdoch014dc512016-03-22 12:00:34 +0000456} // namespace internal
457} // namespace v8