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(
|
global_context()->set_string_function_prototype_map(
|
||||||
HeapObject::cast(string_function->initial_map()->prototype())->map());
|
HeapObject::cast(string_function->initial_map()->prototype())->map());
|
||||||
|
|
||||||
InstallBuiltinFunctionIds();
|
|
||||||
|
|
||||||
// Install Function.prototype.call and apply.
|
// Install Function.prototype.call and apply.
|
||||||
{ Handle<String> key = factory()->function_class_symbol();
|
{ Handle<String> key = factory()->function_class_symbol();
|
||||||
Handle<JSFunction> function =
|
Handle<JSFunction> function =
|
||||||
@ -1622,6 +1620,8 @@ bool Genesis::InstallNatives() {
|
|||||||
apply->shared()->set_length(2);
|
apply->shared()->set_length(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InstallBuiltinFunctionIds();
|
||||||
|
|
||||||
// Create a constructor for RegExp results (a variant of Array that
|
// Create a constructor for RegExp results (a variant of Array that
|
||||||
// predefines the two properties index and match).
|
// predefines the two properties index and match).
|
||||||
{
|
{
|
||||||
|
@ -4762,10 +4762,17 @@ bool HGraphBuilder::TryCallApply(Call* expr) {
|
|||||||
Property* prop = callee->AsProperty();
|
Property* prop = callee->AsProperty();
|
||||||
ASSERT(prop != NULL);
|
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 (info()->scope()->arguments() == NULL) return false;
|
||||||
if (!name->IsEqualTo(CStrVector("apply"))) return false;
|
|
||||||
|
|
||||||
ZoneList<Expression*>* args = expr->arguments();
|
ZoneList<Expression*>* args = expr->arguments();
|
||||||
if (args->length() != 2) return false;
|
if (args->length() != 2) return false;
|
||||||
@ -4775,9 +4782,6 @@ bool HGraphBuilder::TryCallApply(Call* expr) {
|
|||||||
HValue* arg_two_value = environment()->Lookup(arg_two->var());
|
HValue* arg_two_value = environment()->Lookup(arg_two->var());
|
||||||
if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false;
|
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
|
// Our implementation of arguments (based on this stack frame or an
|
||||||
// adapter below it) does not work for inlined functions.
|
// adapter below it) does not work for inlined functions.
|
||||||
if (function_state()->outer() != NULL) {
|
if (function_state()->outer() != NULL) {
|
||||||
@ -4794,10 +4798,7 @@ bool HGraphBuilder::TryCallApply(Call* expr) {
|
|||||||
HValue* receiver = Pop();
|
HValue* receiver = Pop();
|
||||||
HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
|
HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
|
||||||
HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
|
HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
|
||||||
AddCheckConstantFunction(expr,
|
AddCheckConstantFunction(expr, function, function_map, true);
|
||||||
function,
|
|
||||||
expr->GetReceiverTypes()->first(),
|
|
||||||
true);
|
|
||||||
HInstruction* result =
|
HInstruction* result =
|
||||||
new(zone()) HApplyArguments(function, receiver, length, elements);
|
new(zone()) HApplyArguments(function, receiver, length, elements);
|
||||||
result->set_position(expr->position());
|
result->set_position(expr->position());
|
||||||
|
@ -874,7 +874,10 @@ class HGraphBuilder: public AstVisitor {
|
|||||||
bool is_store);
|
bool is_store);
|
||||||
|
|
||||||
bool TryArgumentsAccess(Property* expr);
|
bool TryArgumentsAccess(Property* expr);
|
||||||
|
|
||||||
|
// Try to optimize fun.apply(receiver, arguments) pattern.
|
||||||
bool TryCallApply(Call* expr);
|
bool TryCallApply(Call* expr);
|
||||||
|
|
||||||
bool TryInline(Call* expr);
|
bool TryInline(Call* expr);
|
||||||
bool TryInlineBuiltinFunction(Call* expr,
|
bool TryInlineBuiltinFunction(Call* expr,
|
||||||
HValue* receiver,
|
HValue* receiver,
|
||||||
|
@ -4444,6 +4444,7 @@ class Script: public Struct {
|
|||||||
#define FUNCTIONS_WITH_ID_LIST(V) \
|
#define FUNCTIONS_WITH_ID_LIST(V) \
|
||||||
V(Array.prototype, push, ArrayPush) \
|
V(Array.prototype, push, ArrayPush) \
|
||||||
V(Array.prototype, pop, ArrayPop) \
|
V(Array.prototype, pop, ArrayPop) \
|
||||||
|
V(Function.prototype, apply, FunctionApply) \
|
||||||
V(String.prototype, charCodeAt, StringCharCodeAt) \
|
V(String.prototype, charCodeAt, StringCharCodeAt) \
|
||||||
V(String.prototype, charAt, StringCharAt) \
|
V(String.prototype, charAt, StringCharAt) \
|
||||||
V(String, fromCharCode, StringFromCharCode) \
|
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