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
