runtime-compiler.cc revision 958fae7ec3f466955f8e5b50fa5b8d38b9e91675
1958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright 2014 the V8 project authors. All rights reserved. 2958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Use of this source code is governed by a BSD-style license that can be 3958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// found in the LICENSE file. 4958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 5958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/v8.h" 6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/arguments.h" 8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler.h" 9958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/deoptimizer.h" 10958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/frames.h" 11958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/full-codegen.h" 12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/isolate-inl.h" 13958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/runtime/runtime-utils.h" 14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/v8threads.h" 15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/vm-state-inl.h" 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 { 18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal { 19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_CompileLazy) { 21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.length() == 1); 23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#ifdef DEBUG 25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_lazy && !function->shared()->is_compiled()) { 26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("[unoptimized: "); 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->PrintName(); 28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("]\n"); 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Compile the target function. 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(function->shared()->allows_lazy_compilation()); 34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Code> code; 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code, 37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Compiler::GetLazyCode(function)); 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(code->kind() == Code::FUNCTION || 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier code->kind() == Code::OPTIMIZED_FUNCTION); 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->ReplaceCode(*code); 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *code; 42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_CompileOptimized) { 46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.length() == 2); 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_BOOLEAN_ARG_CHECKED(concurrent, 1); 50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(isolate->use_crankshaft()); 51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Code> unoptimized(function->shared()->code()); 53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (function->shared()->optimization_disabled() || 54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->DebuggerHasBreakPoints()) { 55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If the function is not optimizable or debugger is active continue 56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // using the code from the full compiler. 57958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_opt) { 58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("[failed to optimize "); 59958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->PrintName(); 60958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(": is code optimizable: %s, is debugger enabled: %s]\n", 61958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->shared()->optimization_disabled() ? "F" : "T", 62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->DebuggerHasBreakPoints() ? "T" : "F"); 63958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->ReplaceCode(*unoptimized); 65958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return function->code(); 66958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 68958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Compiler::ConcurrencyMode mode = 69958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier concurrent ? Compiler::CONCURRENT : Compiler::NOT_CONCURRENT; 70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Code> code; 71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (Compiler::GetOptimizedCode(function, unoptimized, mode).ToHandle(&code)) { 72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->ReplaceCode(*code); 73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->ReplaceCode(function->shared()->code()); 75958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(function->code()->kind() == Code::FUNCTION || 78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->code()->kind() == Code::OPTIMIZED_FUNCTION || 79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->IsInOptimizationQueue()); 80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return function->code(); 81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_NotifyStubFailure) { 85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.length() == 0); 87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); 88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(AllowHeapAllocation::IsAllowed()); 89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier delete deoptimizer; 90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return isolate->heap()->undefined_value(); 91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass ActivationsFinder : public ThreadVisitor { 95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Code* code_; 97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool has_code_activations_; 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit ActivationsFinder(Code* code) 100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : code_(code), has_code_activations_(false) {} 101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void VisitThread(Isolate* isolate, ThreadLocalTop* top) { 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JavaScriptFrameIterator it(isolate, top); 104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitFrames(&it); 105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void VisitFrames(JavaScriptFrameIterator* it) { 108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (; !it->done(); it->Advance()) { 109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JavaScriptFrame* frame = it->frame(); 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (code_->contains(frame->pc())) has_code_activations_ = true; 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_NotifyDeoptimized) { 117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.length() == 1); 119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_SMI_ARG_CHECKED(type_arg, 0); 120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Deoptimizer::BailoutType type = 121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<Deoptimizer::BailoutType>(type_arg); 122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); 123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(AllowHeapAllocation::IsAllowed()); 124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSFunction> function = deoptimizer->function(); 126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Code> optimized_code = deoptimizer->compiled_code(); 127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(optimized_code->kind() == Code::OPTIMIZED_FUNCTION); 129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(type == deoptimizer->bailout_type()); 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Make sure to materialize objects before causing any allocation. 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JavaScriptFrameIterator it(isolate); 133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier deoptimizer->MaterializeHeapObjects(&it); 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier delete deoptimizer; 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JavaScriptFrame* frame = it.frame(); 137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RUNTIME_ASSERT(frame->function()->IsJSFunction()); 138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(frame->function() == *function); 139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Avoid doing too much work when running with --always-opt and keep 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the optimized code around. 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_always_opt || type == Deoptimizer::LAZY) { 143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return isolate->heap()->undefined_value(); 144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Search for other activations of the same function and code. 147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ActivationsFinder activations_finder(*optimized_code); 148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier activations_finder.VisitFrames(&it); 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->thread_manager()->IterateArchivedThreads(&activations_finder); 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!activations_finder.has_code_activations_) { 152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (function->code() == *optimized_code) { 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_deopt) { 154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("[removing optimized code for: "); 155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->PrintName(); 156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("]\n"); 157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->ReplaceCode(function->shared()->code()); 159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Evict optimized code for this function from the cache so that it 160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // doesn't get used for new closures. 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->shared()->EvictFromOptimizedCodeMap(*optimized_code, 162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "notify deoptimized"); 163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(titzer): we should probably do DeoptimizeCodeList(code) 166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // unconditionally if the code is not already marked for deoptimization. 167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If there is an index by shared function info, all the better. 168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Deoptimizer::DeoptimizeFunction(*function); 169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return isolate->heap()->undefined_value(); 172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic bool IsSuitableForOnStackReplacement(Isolate* isolate, 176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSFunction> function, 177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Code> current_code) { 178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Keep track of whether we've succeeded in optimizing. 179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!current_code->optimizable()) return false; 180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If we are trying to do OSR when there are already optimized 181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // activations of the function, it means (a) the function is directly or 182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // indirectly recursive and (b) an optimized invocation has been 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // deoptimized so that we are currently in an unoptimized activation. 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check for optimized activations of this function. 185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) { 186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JavaScriptFrame* frame = it.frame(); 187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (frame->is_optimized() && frame->function() == *function) return false; 188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return true; 191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { 195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.length() == 1); 197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Code> caller_code(function->shared()->code()); 199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // We're not prepared to handle a function with arguments object. 201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!function->shared()->uses_arguments()); 202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RUNTIME_ASSERT(FLAG_use_osr); 204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Passing the PC in the javascript frame from the caller directly is 206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // not GC safe, so we walk the stack to get it. 207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JavaScriptFrameIterator it(isolate); 208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JavaScriptFrame* frame = it.frame(); 209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!caller_code->contains(frame->pc())) { 210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Code on the stack may not be the code object referenced by the shared 211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // function info. It may have been replaced to include deoptimization data. 212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier caller_code = Handle<Code>(frame->LookupCode()); 213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t pc_offset = 216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<uint32_t>(frame->pc() - caller_code->instruction_start()); 217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#ifdef DEBUG 219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(frame->function(), *function); 220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(frame->LookupCode(), *caller_code); 221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(caller_code->contains(frame->pc())); 222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif // DEBUG 223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset); 226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!ast_id.IsNone()); 227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Compiler::ConcurrencyMode mode = 229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->concurrent_osr_enabled() && 230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (function->shared()->ast_node_count() > 512) 231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ? Compiler::CONCURRENT 232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : Compiler::NOT_CONCURRENT; 233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Code> result = Handle<Code>::null(); 234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OptimizedCompileJob* job = NULL; 236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mode == Compiler::CONCURRENT) { 237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Gate the OSR entry with a stack check. 238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BackEdgeTable::AddStackCheck(caller_code, pc_offset); 239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Poll already queued compilation jobs. 240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OptimizingCompilerThread* thread = isolate->optimizing_compiler_thread(); 241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (thread->IsQueuedForOSR(function, ast_id)) { 242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_osr) { 243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("[OSR - Still waiting for queued: "); 244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->PrintName(); 245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" at AST id %d]\n", ast_id.ToInt()); 246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return NULL; 248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier job = thread->FindReadyOSRCandidate(function, ast_id); 251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (job != NULL) { 254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_osr) { 255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("[OSR - Found ready: "); 256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->PrintName(); 257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" at AST id %d]\n", ast_id.ToInt()); 258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result = Compiler::GetConcurrentlyOptimizedCode(job); 260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (IsSuitableForOnStackReplacement(isolate, function, caller_code)) { 261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_osr) { 262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("[OSR - Compiling: "); 263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->PrintName(); 264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" at AST id %d]\n", ast_id.ToInt()); 265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MaybeHandle<Code> maybe_result = 267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Compiler::GetOptimizedCode(function, caller_code, mode, ast_id); 268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (maybe_result.ToHandle(&result) && 269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result.is_identical_to(isolate->builtins()->InOptimizationQueue())) { 270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Optimization is queued. Return to check later. 271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return NULL; 272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Revert the patched back edge table, regardless of whether OSR succeeds. 276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BackEdgeTable::Revert(isolate, *caller_code); 277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check whether we ended up with usable optimized code. 279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) { 280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DeoptimizationInputData* data = 281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DeoptimizationInputData::cast(result->deoptimization_data()); 282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (data->OsrPcOffset()->value() >= 0) { 284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(BailoutId(data->OsrAstId()->value()) == ast_id); 285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_osr) { 286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n", 287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ast_id.ToInt(), data->OsrPcOffset()->value()); 288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(titzer): this is a massive hack to make the deopt counts 290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // match. Fix heuristics for reenabling optimizations! 291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->shared()->increment_deopt_count(); 292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(titzer): Do not install code into the function. 294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->ReplaceCode(*result); 295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *result; 296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Failed. 300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_osr) { 301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("[OSR - Failed: "); 302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->PrintName(); 303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" at AST id %d]\n", ast_id.ToInt()); 304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!function->IsOptimized()) { 307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->ReplaceCode(function->shared()->code()); 308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return NULL; 310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_TryInstallOptimizedCode) { 314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.length() == 1); 316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // First check if this is a real stack overflow. 319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StackLimitCheck check(isolate); 320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (check.JsHasOverflowed()) { 321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SealHandleScope shs(isolate); 322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return isolate->StackOverflow(); 323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); 326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return (function->IsOptimized()) ? function->code() 327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : function->shared()->code(); 328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool CodeGenerationFromStringsAllowed(Isolate* isolate, 332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> context) { 333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(context->allow_code_gen_from_strings()->IsFalse()); 334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check with callback if set. 335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AllowCodeGenerationFromStringsCallback callback = 336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->allow_code_gen_callback(); 337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (callback == NULL) { 338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // No callback set and code generation disallowed. 339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return false; 340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Callback set. Let it decide if code generation is allowed. 342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VMState<EXTERNAL> state(isolate); 343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return callback(v8::Utils::ToLocal(context)); 344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_CompileString) { 349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.length() == 3); 351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_ARG_HANDLE_CHECKED(String, source, 0); 352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1); 353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_SMI_ARG_CHECKED(source_offset, 2); 354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Extract native context. 356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> context(isolate->native_context()); 357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check if native context allows code generation from 359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // strings. Throw an exception if it doesn't. 360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (context->allow_code_gen_from_strings()->IsFalse() && 361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier !CodeGenerationFromStringsAllowed(isolate, context)) { 362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> error_message = 363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier context->ErrorMessageForCodeGenerationFromStrings(); 364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier THROW_NEW_ERROR_RETURN_FAILURE( 365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate, NewEvalError("code_gen_from_strings", 366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleVector<Object>(&error_message, 1))); 367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Compile source string in the native context. 370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ParseRestriction restriction = function_literal_only 371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ? ONLY_SINGLE_FUNCTION_LITERAL 372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : NO_PARSE_RESTRICTION; 373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<SharedFunctionInfo> outer_info(context->closure()->shared(), isolate); 374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSFunction> fun; 375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate, fun, 377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Compiler::GetFunctionFromEval(source, outer_info, context, SLOPPY, 378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier restriction, RelocInfo::kNoPosition)); 379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (function_literal_only) { 380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The actual body is wrapped, which shifts line numbers. 381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Script> script(Script::cast(fun->shared()->script()), isolate); 382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (script->line_offset() == 0) { 383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int line_num = Script::GetLineNumber(script, source_offset); 384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier script->set_line_offset(Smi::FromInt(-line_num)); 385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *fun; 388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic ObjectPair CompileGlobalEval(Isolate* isolate, Handle<String> source, 392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<SharedFunctionInfo> outer_info, 393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> receiver, 394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StrictMode strict_mode, 395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int scope_position) { 396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> context = Handle<Context>(isolate->context()); 397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> native_context = Handle<Context>(context->native_context()); 398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check if native context allows code generation from 400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // strings. Throw an exception if it doesn't. 401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (native_context->allow_code_gen_from_strings()->IsFalse() && 402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier !CodeGenerationFromStringsAllowed(isolate, native_context)) { 403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> error_message = 404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier native_context->ErrorMessageForCodeGenerationFromStrings(); 405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> error; 406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MaybeHandle<Object> maybe_error = isolate->factory()->NewEvalError( 407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "code_gen_from_strings", HandleVector<Object>(&error_message, 1)); 408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (maybe_error.ToHandle(&error)) isolate->Throw(*error); 409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return MakePair(isolate->heap()->exception(), NULL); 410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Deal with a normal eval call with a string argument. Compile it 413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // and return the compiled function bound in the local context. 414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const ParseRestriction restriction = NO_PARSE_RESTRICTION; 415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSFunction> compiled; 416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSIGN_RETURN_ON_EXCEPTION_VALUE( 417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate, compiled, 418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Compiler::GetFunctionFromEval(source, outer_info, context, strict_mode, 419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier restriction, scope_position), 420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MakePair(isolate->heap()->exception(), NULL)); 421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return MakePair(*compiled, *receiver); 422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION_RETURN_PAIR(Runtime_ResolvePossiblyDirectEval) { 426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.length() == 6); 428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> callee = args.at<Object>(0); 430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If "eval" didn't refer to the original GlobalEval, it's not a 432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // direct call to eval. 433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // (And even if it is, but the first argument isn't a string, just let 434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // execution default to an indirect call to eval, which will also return 435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the first argument without doing anything). 436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (*callee != isolate->native_context()->global_eval_fun() || 437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier !args[1]->IsString()) { 438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return MakePair(*callee, isolate->heap()->undefined_value()); 439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args[4]->IsSmi()); 442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.smi_at(4) == SLOPPY || args.smi_at(4) == STRICT); 443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(4)); 444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args[5]->IsSmi()); 445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<SharedFunctionInfo> outer_info(args.at<JSFunction>(2)->shared(), 446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate); 447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return CompileGlobalEval(isolate, args.at<String>(1), outer_info, 448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier args.at<Object>(3), strict_mode, args.smi_at(5)); 449958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace v8::internal 452