Do not allow inlining functions with direct arguments access.

Our implementations of arguments without materializing the arguments
object (based on inspecting the stack frame) does not work for inlined
functions.  Guard all attempts by disallowing them if possible or else
bailing out of the optimizing compiler.

R=fschneider@chromium.org
BUG=
TEST=

Review URL: http://codereview.chromium.org/6976022

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8072 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
kmillikin@chromium.org 2011-05-26 10:56:07 +00:00
parent 64c610727d
commit 68e2d1bfed
2 changed files with 33 additions and 0 deletions

View File

@ -544,6 +544,17 @@ bool CallNew::IsInlineable() const {
bool CallRuntime::IsInlineable() const {
// Don't try to inline JS runtime calls because we don't (currently) even
// optimize them.
if (is_jsruntime()) return false;
// Don't inline the %_ArgumentsLength or %_Arguments because their
// implementation will not work. There is no stack frame to get them
// from.
if (function()->intrinsic_type == Runtime::INLINE &&
(name()->IsEqualTo(CStrVector("_ArgumentsLength")) ||
name()->IsEqualTo(CStrVector("_Arguments")))) {
return false;
}
const int count = arguments()->length();
for (int i = 0; i < count; ++i) {
if (!arguments()->at(i)->IsInlineable()) return false;

View File

@ -3848,6 +3848,13 @@ bool HGraphBuilder::TryArgumentsAccess(Property* expr) {
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) {
Bailout("arguments access in inlined function");
return true;
}
HInstruction* result = NULL;
if (expr->key()->IsPropertyName()) {
Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
@ -4396,6 +4403,13 @@ bool HGraphBuilder::TryCallApply(Call* expr) {
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) {
Bailout("Function.prototype.apply optimization in inlined function");
return true;
}
// Found pattern f.apply(receiver, arguments).
VisitForValue(prop->obj());
if (HasStackOverflow() || current_block() == NULL) return true;
@ -5422,6 +5436,10 @@ void HGraphBuilder::GenerateIsConstructCall(CallRuntime* call) {
// Support for arguments.length and arguments[?].
void HGraphBuilder::GenerateArgumentsLength(CallRuntime* call) {
// Our implementation of arguments (based on this stack frame or an
// adapter below it) does not work for inlined functions. This runtime
// function is blacklisted by AstNode::IsInlineable.
ASSERT(function_state()->outer() == NULL);
ASSERT(call->arguments()->length() == 0);
HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
HArgumentsLength* result = new(zone()) HArgumentsLength(elements);
@ -5430,6 +5448,10 @@ void HGraphBuilder::GenerateArgumentsLength(CallRuntime* call) {
void HGraphBuilder::GenerateArguments(CallRuntime* call) {
// Our implementation of arguments (based on this stack frame or an
// adapter below it) does not work for inlined functions. This runtime
// function is blacklisted by AstNode::IsInlineable.
ASSERT(function_state()->outer() == NULL);
ASSERT(call->arguments()->length() == 1);
CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
HValue* index = Pop();