Revision: 3371
Author: [email protected]
Date: Thu Nov 26 16:28:06 2009
Log: Added fast compiler support for calling JS runtime functions.

Also added a simple test that invokes a JS runtime function
in top-level code.

Review URL: http://codereview.chromium.org/437081
http://code.google.com/p/v8/source/detail?r=3371

Added:
  /branches/bleeding_edge/test/mjsunit/compiler/jsnatives.js
Modified:
  /branches/bleeding_edge/src/arm/fast-codegen-arm.cc
  /branches/bleeding_edge/src/ast.h
  /branches/bleeding_edge/src/compiler.cc
  /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc
  /branches/bleeding_edge/src/x64/fast-codegen-x64.cc

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/compiler/jsnatives.js  Thu Nov 26  
16:28:06 2009
@@ -0,0 +1,33 @@
+// Copyright 2009 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
+
+// Test call of JS runtime functions.
+
+var a = %GlobalParseInt("21", 16);
+assertEquals(33, a);
=======================================
--- /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Thu Nov 26 13:13:20  
2009
+++ /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Thu Nov 26 16:28:06  
2009
@@ -1255,9 +1255,14 @@
  void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
    Comment cmnt(masm_, "[ CallRuntime");
    ZoneList<Expression*>* args = expr->arguments();
-  Runtime::Function* function = expr->function();
-
-  ASSERT(function != NULL);
+
+  if (expr->is_jsruntime()) {
+    // Prepare for calling JS runtime function.
+    __ mov(r1, Operand(expr->name()));
+    __ ldr(r0, CodeGenerator::GlobalObject());
+    __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset));
+    __ stm(db_w, sp, r1.bit() | r0.bit());
+  }

    // Push the arguments ("left-to-right").
    int arg_count = args->length();
@@ -1266,8 +1271,20 @@
      ASSERT_EQ(Expression::kValue, args->at(i)->context());
    }

-  __ CallRuntime(function, arg_count);
-  Move(expr->context(), r0);
+  if (expr->is_jsruntime()) {
+    // Call the JS runtime function.
+    Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
+                                                           NOT_IN_LOOP);
+    __ Call(ic, RelocInfo::CODE_TARGET);
+    // Restore context register.
+    __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+    // Discard the function left on TOS.
+    DropAndMove(expr->context(), r0);
+  } else {
+    // Call the C runtime function.
+    __ CallRuntime(expr->function(), arg_count);
+    Move(expr->context(), r0);
+  }
  }


=======================================
--- /branches/bleeding_edge/src/ast.h   Mon Nov 16 13:59:31 2009
+++ /branches/bleeding_edge/src/ast.h   Thu Nov 26 16:28:06 2009
@@ -1080,6 +1080,7 @@
    Handle<String> name() const { return name_; }
    Runtime::Function* function() const { return function_; }
    ZoneList<Expression*>* arguments() const { return arguments_; }
+  bool is_jsruntime() const { return function_ == NULL; }

   private:
    Handle<String> name_;
=======================================
--- /branches/bleeding_edge/src/compiler.cc     Thu Nov 26 02:28:32 2009
+++ /branches/bleeding_edge/src/compiler.cc     Thu Nov 26 16:28:06 2009
@@ -993,8 +993,6 @@


  void CodeGenSelector::VisitCallRuntime(CallRuntime* expr) {
-  // In case of JS runtime function bail out.
-  if (expr->function() == NULL) BAILOUT("call JS runtime function");
    // Check for inline runtime call
    if (expr->name()->Get(0) == '_' &&
        CodeGenerator::FindInlineRuntimeLUT(expr->name()) != NULL) {
=======================================
--- /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc       Thu Nov 26  
13:13:20 2009
+++ /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc       Thu Nov 26  
16:28:06 2009
@@ -1248,9 +1248,13 @@
  void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
    Comment cmnt(masm_, "[ CallRuntime");
    ZoneList<Expression*>* args = expr->arguments();
-  Runtime::Function* function = expr->function();
-
-  ASSERT(function != NULL);
+
+  if (expr->is_jsruntime()) {
+    // Prepare for calling JS runtime function.
+    __ push(Immediate(expr->name()));
+    __ mov(eax, CodeGenerator::GlobalObject());
+    __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
+  }

    // Push the arguments ("left-to-right").
    int arg_count = args->length();
@@ -1259,8 +1263,20 @@
      ASSERT_EQ(Expression::kValue, args->at(i)->context());
    }

-  __ CallRuntime(function, arg_count);
-  Move(expr->context(), eax);
+  if (expr->is_jsruntime()) {
+    // Call the JS runtime function.
+    Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
+                                                           NOT_IN_LOOP);
+    __ call(ic, RelocInfo::CODE_TARGET);
+      // Restore context register.
+    __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
+    // Discard the function left on TOS.
+    DropAndMove(expr->context(), eax);
+  } else {
+    // Call the C runtime function.
+    __ CallRuntime(expr->function(), arg_count);
+    Move(expr->context(), eax);
+  }
  }


=======================================
--- /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Thu Nov 26 13:13:20  
2009
+++ /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Thu Nov 26 16:28:06  
2009
@@ -1252,9 +1252,13 @@
  void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
    Comment cmnt(masm_, "[ CallRuntime");
    ZoneList<Expression*>* args = expr->arguments();
-  Runtime::Function* function = expr->function();
-
-  ASSERT(function != NULL);
+
+  if (expr->is_jsruntime()) {
+    // Prepare for calling JS runtime function.
+    __ Push(expr->name());
+    __ movq(rax, CodeGenerator::GlobalObject());
+    __ push(FieldOperand(rax, GlobalObject::kBuiltinsOffset));
+  }

    // Push the arguments ("left-to-right").
    int arg_count = args->length();
@@ -1263,8 +1267,19 @@
      ASSERT_EQ(Expression::kValue, args->at(i)->context());
    }

-  __ CallRuntime(function, arg_count);
-  Move(expr->context(), rax);
+  if (expr->is_jsruntime()) {
+    // Call the JS runtime function.
+    Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
+                                                           NOT_IN_LOOP);
+    __ call(ic, RelocInfo::CODE_TARGET);
+    // Restore context register.
+    __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
+    // Discard the function left on TOS.
+    DropAndMove(expr->context(), rax);
+  } else {
+    __ CallRuntime(expr->function(), arg_count);
+    Move(expr->context(), rax);
+  }
  }

  void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {

-- 
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to