Fix fun.apply(receiver, arguments) optimization.
R=kmillikin@chromium.org BUG=v8:1592 TEST=mjsunit/regress/regress-1592.js Review URL: http://codereview.chromium.org/7497067 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8884 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
3c1b45b5d7
commit
a107387dde
@ -1587,8 +1587,6 @@ bool Genesis::InstallNatives() {
|
||||
global_context()->set_string_function_prototype_map(
|
||||
HeapObject::cast(string_function->initial_map()->prototype())->map());
|
||||
|
||||
InstallBuiltinFunctionIds();
|
||||
|
||||
// Install Function.prototype.call and apply.
|
||||
{ Handle<String> key = factory()->function_class_symbol();
|
||||
Handle<JSFunction> function =
|
||||
@ -1622,6 +1620,8 @@ bool Genesis::InstallNatives() {
|
||||
apply->shared()->set_length(2);
|
||||
}
|
||||
|
||||
InstallBuiltinFunctionIds();
|
||||
|
||||
// Create a constructor for RegExp results (a variant of Array that
|
||||
// predefines the two properties index and match).
|
||||
{
|
||||
|
@ -4762,10 +4762,17 @@ bool HGraphBuilder::TryCallApply(Call* expr) {
|
||||
Property* prop = callee->AsProperty();
|
||||
ASSERT(prop != NULL);
|
||||
|
||||
if (info()->scope()->arguments() == NULL) return false;
|
||||
if (!expr->IsMonomorphic() || expr->check_type() != RECEIVER_MAP_CHECK) {
|
||||
return false;
|
||||
}
|
||||
Handle<Map> function_map = expr->GetReceiverTypes()->first();
|
||||
if (function_map->instance_type() != JS_FUNCTION_TYPE ||
|
||||
!expr->target()->shared()->HasBuiltinFunctionId() ||
|
||||
expr->target()->shared()->builtin_function_id() != kFunctionApply) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
|
||||
if (!name->IsEqualTo(CStrVector("apply"))) return false;
|
||||
if (info()->scope()->arguments() == NULL) return false;
|
||||
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
if (args->length() != 2) return false;
|
||||
@ -4775,9 +4782,6 @@ bool HGraphBuilder::TryCallApply(Call* expr) {
|
||||
HValue* arg_two_value = environment()->Lookup(arg_two->var());
|
||||
if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false;
|
||||
|
||||
if (!expr->IsMonomorphic() ||
|
||||
expr->check_type() != RECEIVER_MAP_CHECK) return false;
|
||||
|
||||
// Our implementation of arguments (based on this stack frame or an
|
||||
// adapter below it) does not work for inlined functions.
|
||||
if (function_state()->outer() != NULL) {
|
||||
@ -4794,10 +4798,7 @@ bool HGraphBuilder::TryCallApply(Call* expr) {
|
||||
HValue* receiver = Pop();
|
||||
HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
|
||||
HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
|
||||
AddCheckConstantFunction(expr,
|
||||
function,
|
||||
expr->GetReceiverTypes()->first(),
|
||||
true);
|
||||
AddCheckConstantFunction(expr, function, function_map, true);
|
||||
HInstruction* result =
|
||||
new(zone()) HApplyArguments(function, receiver, length, elements);
|
||||
result->set_position(expr->position());
|
||||
|
@ -874,7 +874,10 @@ class HGraphBuilder: public AstVisitor {
|
||||
bool is_store);
|
||||
|
||||
bool TryArgumentsAccess(Property* expr);
|
||||
|
||||
// Try to optimize fun.apply(receiver, arguments) pattern.
|
||||
bool TryCallApply(Call* expr);
|
||||
|
||||
bool TryInline(Call* expr);
|
||||
bool TryInlineBuiltinFunction(Call* expr,
|
||||
HValue* receiver,
|
||||
|
@ -4444,6 +4444,7 @@ class Script: public Struct {
|
||||
#define FUNCTIONS_WITH_ID_LIST(V) \
|
||||
V(Array.prototype, push, ArrayPush) \
|
||||
V(Array.prototype, pop, ArrayPop) \
|
||||
V(Function.prototype, apply, FunctionApply) \
|
||||
V(String.prototype, charCodeAt, StringCharCodeAt) \
|
||||
V(String.prototype, charAt, StringCharAt) \
|
||||
V(String, fromCharCode, StringFromCharCode) \
|
||||
|
45
test/mjsunit/regress/regress-1592.js
Normal file
45
test/mjsunit/regress/regress-1592.js
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
var f = {
|
||||
apply: function(a, b) {}
|
||||
};
|
||||
|
||||
function test(a) {
|
||||
f.apply(this, arguments);
|
||||
}
|
||||
|
||||
// Initialize ICs.
|
||||
test(1);
|
||||
test(1);
|
||||
|
||||
%OptimizeFunctionOnNextCall(test);
|
||||
|
||||
// Kaboom!
|
||||
test(1);
|
Loading…
Reference in New Issue
Block a user