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 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/runtime/runtime-utils.h" 6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/arguments.h" 8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler.h" 9958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/deoptimizer.h" 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/frames-inl.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/full-codegen/full-codegen.h" 12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/isolate-inl.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/messages.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 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StackLimitCheck check(isolate); 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow(); 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Compile the target function. 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(function->shared()->allows_lazy_compilation()); 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Code> code; 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code, 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Compiler::GetLazyCode(function)); 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(code->IsJavaScriptCode()); 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->ReplaceCode(*code); 43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *code; 44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace { 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochObject* CompileOptimized(Isolate* isolate, Handle<JSFunction> function, 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Compiler::ConcurrencyMode mode) { 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StackLimitCheck check(isolate); 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow(); 53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Code> code; 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> unoptimized(function->shared()->code()); 56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (Compiler::GetOptimizedCode(function, unoptimized, mode).ToHandle(&code)) { 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Optimization succeeded, return optimized code. 58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->ReplaceCode(*code); 59958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Optimization failed, get unoptimized code. 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (isolate->has_pending_exception()) { // Possible stack overflow. 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return isolate->heap()->exception(); 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch code = Handle<Code>(function->shared()->code(), isolate); 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (code->kind() != Code::FUNCTION && 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch code->kind() != Code::OPTIMIZED_FUNCTION) { 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate, code, Compiler::GetUnoptimizedCode(function)); 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch function->ReplaceCode(*code); 71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(function->code()->kind() == Code::FUNCTION || 74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->code()->kind() == Code::OPTIMIZED_FUNCTION || 75958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->IsInOptimizationQueue()); 76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return function->code(); 77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRUNTIME_FUNCTION(Runtime_CompileOptimized_Concurrent) { 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleScope scope(isolate); 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(args.length() == 1); 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return CompileOptimized(isolate, function, Compiler::CONCURRENT); 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRUNTIME_FUNCTION(Runtime_CompileOptimized_NotConcurrent) { 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleScope scope(isolate); 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(args.length() == 1); 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return CompileOptimized(isolate, function, Compiler::NOT_CONCURRENT); 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_NotifyStubFailure) { 99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.length() == 0); 101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); 102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(AllowHeapAllocation::IsAllowed()); 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier delete deoptimizer; 104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return isolate->heap()->undefined_value(); 105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass ActivationsFinder : public ThreadVisitor { 109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Code* code_; 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool has_code_activations_; 112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit ActivationsFinder(Code* code) 114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : code_(code), has_code_activations_(false) {} 115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void VisitThread(Isolate* isolate, ThreadLocalTop* top) { 117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JavaScriptFrameIterator it(isolate, top); 118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitFrames(&it); 119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void VisitFrames(JavaScriptFrameIterator* it) { 122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (; !it->done(); it->Advance()) { 123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JavaScriptFrame* frame = it->frame(); 124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (code_->contains(frame->pc())) has_code_activations_ = true; 125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_NotifyDeoptimized) { 131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.length() == 1); 133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_SMI_ARG_CHECKED(type_arg, 0); 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Deoptimizer::BailoutType type = 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<Deoptimizer::BailoutType>(type_arg); 136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); 137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(AllowHeapAllocation::IsAllowed()); 138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSFunction> function = deoptimizer->function(); 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Code> optimized_code = deoptimizer->compiled_code(); 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(optimized_code->kind() == Code::OPTIMIZED_FUNCTION); 143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(type == deoptimizer->bailout_type()); 144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Make sure to materialize objects before causing any allocation. 146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JavaScriptFrameIterator it(isolate); 147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier deoptimizer->MaterializeHeapObjects(&it); 148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier delete deoptimizer; 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JavaScriptFrame* frame = it.frame(); 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RUNTIME_ASSERT(frame->function()->IsJSFunction()); 152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(frame->function() == *function); 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Ensure the context register is updated for materialized objects. 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JavaScriptFrameIterator top_it(isolate); 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JavaScriptFrame* top_frame = top_it.frame(); 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate->set_context(Context::cast(top_frame->context())); 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (type == Deoptimizer::LAZY) { 160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return isolate->heap()->undefined_value(); 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Search for other activations of the same function and code. 164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ActivationsFinder activations_finder(*optimized_code); 165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier activations_finder.VisitFrames(&it); 166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->thread_manager()->IterateArchivedThreads(&activations_finder); 167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!activations_finder.has_code_activations_) { 169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (function->code() == *optimized_code) { 170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_deopt) { 171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("[removing optimized code for: "); 172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->PrintName(); 173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("]\n"); 174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->ReplaceCode(function->shared()->code()); 176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Evict optimized code for this function from the cache so that it 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // doesn't get used for new closures. 179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch function->shared()->EvictFromOptimizedCodeMap(*optimized_code, 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "notify deoptimized"); 181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(titzer): we should probably do DeoptimizeCodeList(code) 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // unconditionally if the code is not already marked for deoptimization. 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If there is an index by shared function info, all the better. 185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Deoptimizer::DeoptimizeFunction(*function); 186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return isolate->heap()->undefined_value(); 189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic bool IsSuitableForOnStackReplacement(Isolate* isolate, 193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction> function) { 194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Keep track of whether we've succeeded in optimizing. 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (function->shared()->optimization_disabled()) return false; 196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If we are trying to do OSR when there are already optimized 197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // activations of the function, it means (a) the function is directly or 198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // indirectly recursive and (b) an optimized invocation has been 199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // deoptimized so that we are currently in an unoptimized activation. 200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check for optimized activations of this function. 201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) { 202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JavaScriptFrame* frame = it.frame(); 203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (frame->is_optimized() && frame->function() == *function) return false; 204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return true; 207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { 211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.length() == 1); 213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Code> caller_code(function->shared()->code()); 215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // We're not prepared to handle a function with arguments object. 217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!function->shared()->uses_arguments()); 218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RUNTIME_ASSERT(FLAG_use_osr); 220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Passing the PC in the javascript frame from the caller directly is 222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // not GC safe, so we walk the stack to get it. 223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JavaScriptFrameIterator it(isolate); 224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JavaScriptFrame* frame = it.frame(); 225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!caller_code->contains(frame->pc())) { 226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Code on the stack may not be the code object referenced by the shared 227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // function info. It may have been replaced to include deoptimization data. 228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier caller_code = Handle<Code>(frame->LookupCode()); 229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t pc_offset = 232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<uint32_t>(frame->pc() - caller_code->instruction_start()); 233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#ifdef DEBUG 235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(frame->function(), *function); 236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(frame->LookupCode(), *caller_code); 237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(caller_code->contains(frame->pc())); 238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif // DEBUG 239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset); 242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!ast_id.IsNone()); 243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Disable concurrent OSR for asm.js, to enable frame specialization. 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Compiler::ConcurrencyMode mode = (isolate->concurrent_osr_enabled() && 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !function->shared()->asm_function() && 247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch function->shared()->ast_node_count() > 512) 248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? Compiler::CONCURRENT 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Compiler::NOT_CONCURRENT; 250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Code> result = Handle<Code>::null(); 251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OptimizedCompileJob* job = NULL; 253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mode == Compiler::CONCURRENT) { 254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Gate the OSR entry with a stack check. 255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BackEdgeTable::AddStackCheck(caller_code, pc_offset); 256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Poll already queued compilation jobs. 257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OptimizingCompileDispatcher* dispatcher = 258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate->optimizing_compile_dispatcher(); 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (dispatcher->IsQueuedForOSR(function, ast_id)) { 260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_osr) { 261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("[OSR - Still waiting for queued: "); 262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->PrintName(); 263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" at AST id %d]\n", ast_id.ToInt()); 264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return NULL; 266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch job = dispatcher->FindReadyOSRCandidate(function, ast_id); 269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (job != NULL) { 272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_osr) { 273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("[OSR - Found ready: "); 274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->PrintName(); 275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" at AST id %d]\n", ast_id.ToInt()); 276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result = Compiler::GetConcurrentlyOptimizedCode(job); 278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (IsSuitableForOnStackReplacement(isolate, function)) { 279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_osr) { 280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("[OSR - Compiling: "); 281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->PrintName(); 282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" at AST id %d]\n", ast_id.ToInt()); 283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MaybeHandle<Code> maybe_result = Compiler::GetOptimizedCode( 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch function, caller_code, mode, ast_id, 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (mode == Compiler::NOT_CONCURRENT) ? frame : nullptr); 287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (maybe_result.ToHandle(&result) && 288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result.is_identical_to(isolate->builtins()->InOptimizationQueue())) { 289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Optimization is queued. Return to check later. 290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return NULL; 291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Revert the patched back edge table, regardless of whether OSR succeeds. 295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BackEdgeTable::Revert(isolate, *caller_code); 296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check whether we ended up with usable optimized code. 298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) { 299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DeoptimizationInputData* data = 300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DeoptimizationInputData::cast(result->deoptimization_data()); 301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (data->OsrPcOffset()->value() >= 0) { 303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(BailoutId(data->OsrAstId()->value()) == ast_id); 304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_osr) { 305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n", 306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ast_id.ToInt(), data->OsrPcOffset()->value()); 307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(titzer): this is a massive hack to make the deopt counts 309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // match. Fix heuristics for reenabling optimizations! 310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->shared()->increment_deopt_count(); 311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (result->is_turbofanned()) { 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TurboFanned OSR code cannot be installed into the function. 314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // But the function is obviously hot, so optimize it next time. 315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch function->ReplaceCode( 316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate->builtins()->builtin(Builtins::kCompileOptimized)); 317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Crankshafted OSR code can be installed into the function. 319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch function->ReplaceCode(*result); 320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *result; 322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Failed. 326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_osr) { 327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("[OSR - Failed: "); 328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->PrintName(); 329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" at AST id %d]\n", ast_id.ToInt()); 330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!function->IsOptimized()) { 333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->ReplaceCode(function->shared()->code()); 334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return NULL; 336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_TryInstallOptimizedCode) { 340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.length() == 1); 342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // First check if this is a real stack overflow. 345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StackLimitCheck check(isolate); 346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (check.JsHasOverflowed()) { 347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SealHandleScope shs(isolate); 348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return isolate->StackOverflow(); 349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions(); 352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return (function->IsOptimized()) ? function->code() 353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : function->shared()->code(); 354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool CodeGenerationFromStringsAllowed(Isolate* isolate, 358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> context) { 359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(context->allow_code_gen_from_strings()->IsFalse()); 360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check with callback if set. 361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AllowCodeGenerationFromStringsCallback callback = 362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->allow_code_gen_callback(); 363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (callback == NULL) { 364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // No callback set and code generation disallowed. 365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return false; 366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Callback set. Let it decide if code generation is allowed. 368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VMState<EXTERNAL> state(isolate); 369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return callback(v8::Utils::ToLocal(context)); 370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic Object* CompileGlobalEval(Isolate* isolate, Handle<String> source, 375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SharedFunctionInfo> outer_info, 376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LanguageMode language_mode, 377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int scope_position) { 378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> context = Handle<Context>(isolate->context()); 379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> native_context = Handle<Context>(context->native_context()); 380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check if native context allows code generation from 382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // strings. Throw an exception if it doesn't. 383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (native_context->allow_code_gen_from_strings()->IsFalse() && 384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier !CodeGenerationFromStringsAllowed(isolate, native_context)) { 385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> error_message = 386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier native_context->ErrorMessageForCodeGenerationFromStrings(); 387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> error; 388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MaybeHandle<Object> maybe_error = isolate->factory()->NewEvalError( 389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MessageTemplate::kCodeGenFromStrings, error_message); 390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (maybe_error.ToHandle(&error)) isolate->Throw(*error); 391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return isolate->heap()->exception(); 392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Deal with a normal eval call with a string argument. Compile it 395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // and return the compiled function bound in the local context. 396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const ParseRestriction restriction = NO_PARSE_RESTRICTION; 397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSFunction> compiled; 398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSIGN_RETURN_ON_EXCEPTION_VALUE( 399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate, compiled, 400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Compiler::GetFunctionFromEval(source, outer_info, context, language_mode, 401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier restriction, scope_position), 402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate->heap()->exception()); 403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return *compiled; 404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRUNTIME_FUNCTION(Runtime_ResolvePossiblyDirectEval) { 408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(args.length() == 5); 410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> callee = args.at<Object>(0); 412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If "eval" didn't refer to the original GlobalEval, it's not a 414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // direct call to eval. 415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // (And even if it is, but the first argument isn't a string, just let 416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // execution default to an indirect call to eval, which will also return 417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the first argument without doing anything). 418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (*callee != isolate->native_context()->global_eval_fun() || 419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier !args[1]->IsString()) { 420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return *callee; 421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(args[3]->IsSmi()); 424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(is_valid_language_mode(args.smi_at(3))); 425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LanguageMode language_mode = static_cast<LanguageMode>(args.smi_at(3)); 426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args[4]->IsSmi()); 427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<SharedFunctionInfo> outer_info(args.at<JSFunction>(2)->shared(), 428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate); 429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return CompileGlobalEval(isolate, args.at<String>(1), outer_info, 430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch language_mode, args.smi_at(4)); 431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 434