From: verwaest Date: Tue, 24 Mar 2015 12:05:45 +0000 (-0700) Subject: If CallNew targets a constant global, set its state to monomorphic X-Git-Tag: upstream/4.7.83~3641 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c46a93722012d3eff2e35402f0abec76e33595f3;p=platform%2Fupstream%2Fv8.git If CallNew targets a constant global, set its state to monomorphic BUG= Review URL: https://codereview.chromium.org/1023103003 Cr-Commit-Position: refs/heads/master@{#27399} --- diff --git a/src/ast.cc b/src/ast.cc index 1ef5ab3aa..c907df19b 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -622,24 +622,6 @@ Call::CallType Call::GetCallType(Isolate* isolate) const { } -bool Call::ComputeGlobalTarget(Handle global, - LookupIterator* it) { - target_ = Handle::null(); - DCHECK(it->IsFound() && it->GetHolder().is_identical_to(global)); - Handle cell = it->GetPropertyCell(); - if (cell->value()->IsJSFunction()) { - Handle candidate(JSFunction::cast(cell->value())); - // If the function is in new space we assume it's more likely to - // change and thus prefer the general IC code. - if (!it->isolate()->heap()->InNewSpace(*candidate)) { - target_ = candidate; - return true; - } - } - return false; -} - - // ---------------------------------------------------------------------------- // Implementation of AstVisitor diff --git a/src/ast.h b/src/ast.h index 661b5f962..60ba21d98 100644 --- a/src/ast.h +++ b/src/ast.h @@ -1849,11 +1849,14 @@ class Call FINAL : public Expression { Handle allocation_site() { return allocation_site_; } + void SetKnownGlobalTarget(Handle target) { + target_ = target; + set_is_uninitialized(false); + } void set_target(Handle target) { target_ = target; } void set_allocation_site(Handle site) { allocation_site_ = site; } - bool ComputeGlobalTarget(Handle global, LookupIterator* it); static int num_ids() { return parent_num_ids() + 2; } BailoutId ReturnId() const { return BailoutId(local_id(0)); } @@ -1954,6 +1957,10 @@ class CallNew FINAL : public Expression { } void set_is_monomorphic(bool monomorphic) { is_monomorphic_ = monomorphic; } void set_target(Handle target) { target_ = target; } + void SetKnownGlobalTarget(Handle target) { + target_ = target; + is_monomorphic_ = true; + } protected: CallNew(Zone* zone, Expression* expression, ZoneList* arguments, diff --git a/src/hydrogen.cc b/src/hydrogen.cc index d9e22c15a..530221668 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -9106,10 +9106,10 @@ bool HOptimizedGraphBuilder::TryHandleArrayCallNew(CallNew* expr, return false; } - BuildArrayCall(expr, - expr->arguments()->length(), - function, - expr->allocation_site()); + Handle site = expr->allocation_site(); + if (site.is_null()) return false; + + BuildArrayCall(expr, expr->arguments()->length(), function, site); return true; } @@ -9231,58 +9231,21 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { // evaluation of the arguments. CHECK_ALIVE(VisitForValue(expr->expression())); HValue* function = Top(); - if (expr->global_call()) { - Variable* var = proxy->var(); - bool known_global_function = false; - // If there is a global property cell for the name at compile time and - // access check is not enabled we assume that the function will not change - // and generate optimized code for calling the function. - Handle global(current_info()->global_object()); - LookupIterator it(global, var->name(), - LookupIterator::OWN_SKIP_INTERCEPTOR); - GlobalPropertyAccess type = LookupGlobalProperty(var, &it, LOAD); - if (type == kUseCell) { - known_global_function = expr->ComputeGlobalTarget(global, &it); - } - if (known_global_function) { - Add(function, expr->target()); - - // Placeholder for the receiver. - Push(graph()->GetConstantUndefined()); - CHECK_ALIVE(VisitExpressions(expr->arguments())); - - // Patch the global object on the stack by the expected receiver. - HValue* receiver = ImplicitReceiverFor(function, expr->target()); - const int receiver_index = argument_count - 1; - environment()->SetExpressionStackAt(receiver_index, receiver); - - if (TryInlineBuiltinFunctionCall(expr)) { - if (FLAG_trace_inlining) { - PrintF("Inlining builtin "); - expr->target()->ShortPrint(); - PrintF("\n"); - } - return; - } - if (TryInlineApiFunctionCall(expr, receiver)) return; - if (TryHandleArrayCall(expr, function)) return; - if (TryInlineCall(expr)) return; + if (function->IsConstant() && + HConstant::cast(function)->handle(isolate())->IsJSFunction()) { + Handle constant = HConstant::cast(function)->handle(isolate()); + Handle target = Handle::cast(constant); + expr->SetKnownGlobalTarget(target); + } - PushArgumentsFromEnvironment(argument_count); - call = BuildCallConstantFunction(expr->target(), argument_count); - } else { - Push(graph()->GetConstantUndefined()); - CHECK_ALIVE(VisitExpressions(expr->arguments())); - PushArgumentsFromEnvironment(argument_count); - call = New(function, argument_count); - } + // Placeholder for the receiver. + Push(graph()->GetConstantUndefined()); + CHECK_ALIVE(VisitExpressions(expr->arguments())); - } else if (expr->IsMonomorphic()) { + if (expr->IsMonomorphic()) { Add(function, expr->target()); - Push(graph()->GetConstantUndefined()); - CHECK_ALIVE(VisitExpressions(expr->arguments())); - + // Patch the global object on the stack by the expected receiver. HValue* receiver = ImplicitReceiverFor(function, expr->target()); const int receiver_index = argument_count - 1; environment()->SetExpressionStackAt(receiver_index, receiver); @@ -9296,15 +9259,12 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { return; } if (TryInlineApiFunctionCall(expr, receiver)) return; - + if (TryHandleArrayCall(expr, function)) return; if (TryInlineCall(expr)) return; - call = PreProcessCall(New( - function, expr->target(), argument_count)); - + PushArgumentsFromEnvironment(argument_count); + call = BuildCallConstantFunction(expr->target(), argument_count); } else { - Push(graph()->GetConstantUndefined()); - CHECK_ALIVE(VisitExpressions(expr->arguments())); PushArgumentsFromEnvironment(argument_count); HCallFunction* call_function = New(function, argument_count); @@ -9443,6 +9403,12 @@ void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { HValue* function = Top(); CHECK_ALIVE(VisitExpressions(expr->arguments())); + if (function->IsConstant() && + HConstant::cast(function)->handle(isolate())->IsJSFunction()) { + Handle constant = HConstant::cast(function)->handle(isolate()); + expr->SetKnownGlobalTarget(Handle::cast(constant)); + } + if (FLAG_inline_construct && expr->IsMonomorphic() && IsAllocationInlineable(expr->target())) {