Do not allow inlining functions with direct arguments access.
authorkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 26 May 2011 10:56:07 +0000 (10:56 +0000)
committerkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 26 May 2011 10:56:07 +0000 (10:56 +0000)
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

src/ast.cc
src/hydrogen.cc

index 5004556..b4abf54 100644 (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;
index 6e520bd..bd370e4 100644 (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();