Optimize %IsConstructCall() on IA-32.
authorkasperl@chromium.org <kasperl@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 29 Jun 2009 08:14:06 +0000 (08:14 +0000)
committerkasperl@chromium.org <kasperl@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 29 Jun 2009 08:14:06 +0000 (08:14 +0000)
Review URL: http://codereview.chromium.org/150018

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2290 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

12 files changed:
src/arm/codegen-arm.cc
src/arm/codegen-arm.h
src/codegen.cc
src/date-delay.js
src/ia32/codegen-ia32.cc
src/ia32/codegen-ia32.h
src/messages.js
src/regexp-delay.js
src/string.js
src/v8natives.js
src/x64/codegen-x64.cc
src/x64/codegen-x64.h

index 6626619..eeea560 100644 (file)
@@ -3290,6 +3290,14 @@ void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
 }
 
 
+void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) {
+  VirtualFrame::SpilledScope spilled_scope;
+  ASSERT(args->length() == 0);
+  frame_->CallRuntime(Runtime::kIsConstructCall, 0);
+  frame_->EmitPush(r0);
+}
+
+
 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
   VirtualFrame::SpilledScope spilled_scope;
   ASSERT(args->length() == 0);
index 4fab900..2048a17 100644 (file)
@@ -333,6 +333,9 @@ class CodeGenerator: public AstVisitor {
   void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
   void GenerateIsArray(ZoneList<Expression*>* args);
 
+  // Support for construct call checks.
+  void GenerateIsConstructCall(ZoneList<Expression*>* args);
+
   // Support for arguments.length and arguments[?].
   void GenerateArgumentsLength(ZoneList<Expression*>* args);
   void GenerateArgumentsAccess(ZoneList<Expression*>* args);
index ad5b1ea..6a41b9d 100644 (file)
@@ -416,6 +416,7 @@ CodeGenerator::InlineRuntimeLUT CodeGenerator::kInlineRuntimeLUT[] = {
   {&CodeGenerator::GenerateIsSmi, "_IsSmi"},
   {&CodeGenerator::GenerateIsNonNegativeSmi, "_IsNonNegativeSmi"},
   {&CodeGenerator::GenerateIsArray, "_IsArray"},
+  {&CodeGenerator::GenerateIsConstructCall, "_IsConstructCall"},
   {&CodeGenerator::GenerateArgumentsLength, "_ArgumentsLength"},
   {&CodeGenerator::GenerateArgumentsAccess, "_Arguments"},
   {&CodeGenerator::GenerateValueOf, "_ValueOf"},
index 0a89783..18d58d5 100644 (file)
@@ -424,7 +424,7 @@ function TimeClip(time) {
 
 
 %SetCode($Date, function(year, month, date, hours, minutes, seconds, ms) {
-  if (%IsConstructCall()) {
+  if (%_IsConstructCall()) {
     // ECMA 262 - 15.9.3
     var argc = %_ArgumentsLength();
     if (argc == 0) {
index 59c1d45..fa407c2 100644 (file)
@@ -4987,6 +4987,29 @@ void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
 }
 
 
+void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) {
+  ASSERT(args->length() == 0);
+
+  // Get the frame pointer for the calling frame.
+  Result fp = allocator()->Allocate();
+  __ mov(fp.reg(), Operand(ebp, StandardFrameConstants::kCallerFPOffset));
+
+  // Skip the arguments adaptor frame if it exists.
+  Label check_frame_marker;
+  __ cmp(Operand(fp.reg(), StandardFrameConstants::kContextOffset),
+         Immediate(ArgumentsAdaptorFrame::SENTINEL));
+  __ j(not_equal, &check_frame_marker);
+  __ mov(fp.reg(), Operand(fp.reg(), StandardFrameConstants::kCallerFPOffset));
+
+  // Check the marker in the calling frame.
+  __ bind(&check_frame_marker);
+  __ cmp(Operand(fp.reg(), StandardFrameConstants::kMarkerOffset),
+         Immediate(Smi::FromInt(StackFrame::CONSTRUCT)));
+  fp.Unuse();
+  destination()->Split(equal);
+}
+
+
 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
   ASSERT(args->length() == 0);
   // ArgumentsAccessStub takes the parameter count as an input argument
index d25d07c..a7e0b06 100644 (file)
@@ -522,6 +522,9 @@ class CodeGenerator: public AstVisitor {
   void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
   void GenerateIsArray(ZoneList<Expression*>* args);
 
+  // Support for construct call checks.
+  void GenerateIsConstructCall(ZoneList<Expression*>* args);
+
   // Support for arguments.length and arguments[?].
   void GenerateArgumentsLength(ZoneList<Expression*>* args);
   void GenerateArgumentsAccess(ZoneList<Expression*>* args);
index ec4b352..bef5540 100644 (file)
@@ -659,7 +659,7 @@ function DefineError(f) {
   %SetProperty(f.prototype, 'constructor', f, DONT_ENUM);
   f.prototype.name = name;
   %SetCode(f, function(m) {
-    if (%IsConstructCall()) {
+    if (%_IsConstructCall()) {
       if (m === kAddMessageAccessorsMarker) {
         DefineOneShotAccessor(this, 'message', function (obj) {
           return FormatMessage({type: obj.type, args: obj.arguments});
index 8491863..14c3644 100644 (file)
@@ -103,7 +103,7 @@ function DoConstructRegExp(object, pattern, flags, isConstructorCall) {
 
 
 function RegExpConstructor(pattern, flags) {
-  if (%IsConstructCall()) {
+  if (%_IsConstructCall()) {
     DoConstructRegExp(this, pattern, flags, true);
   } else {
     // RegExp : Called as function; see ECMA-262, section 15.10.3.1.
index 3d8a11b..604f925 100644 (file)
@@ -35,7 +35,7 @@
 // Set the String function and constructor.
 %SetCode($String, function(x) {
   var value = %_ArgumentsLength() == 0 ? '' : ToString(x);
-  if (%IsConstructCall()) {
+  if (%_IsConstructCall()) {
     %_SetValueOf(this, value);
   } else {
     return value;
index fe46351..97363e9 100644 (file)
@@ -154,7 +154,7 @@ function SetupGlobal() {
 
   // ECMA-262 - 15.1.1.3.
   %SetProperty(global, "undefined", void 0, DONT_ENUM | DONT_DELETE);
-  
+
   // Setup non-enumerable function on the global object.
   InstallFunctions(global, DONT_ENUM, $Array(
     "isNaN", GlobalIsNaN,
@@ -174,7 +174,7 @@ SetupGlobal();
 
 
 %SetCode($Boolean, function(x) {
-  if (%IsConstructCall()) {
+  if (%_IsConstructCall()) {
     %_SetValueOf(this, ToBoolean(x));
   } else {
     return ToBoolean(x);
@@ -273,7 +273,7 @@ function ObjectLookupSetter(name) {
 
 
 %SetCode($Object, function(x) {
-  if (%IsConstructCall()) {
+  if (%_IsConstructCall()) {
     if (x == null) return this;
     return ToObject(x);
   } else {
@@ -350,7 +350,7 @@ SetupBoolean();
 // Set the Number function and constructor.
 %SetCode($Number, function(x) {
   var value = %_ArgumentsLength() == 0 ? 0 : ToNumber(x);
-  if (%IsConstructCall()) {
+  if (%_IsConstructCall()) {
     %_SetValueOf(this, value);
   } else {
     return value;
@@ -570,4 +570,3 @@ function SetupFunction() {
 }
 
 SetupFunction();
-
index fc196ce..24e3ec3 100644 (file)
@@ -3330,6 +3330,14 @@ void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
 }
 
 
+void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) {
+  // TODO(X64): Optimize this like it's done on IA-32.
+  ASSERT(args->length() == 0);
+  Result answer = frame_->CallRuntime(Runtime::kIsConstructCall, 0);
+  frame_->Push(&answer);
+}
+
+
 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
   ASSERT(args->length() == 0);
   // ArgumentsAccessStub takes the parameter count as an input argument
index af82de8..a174c51 100644 (file)
@@ -522,6 +522,9 @@ class CodeGenerator: public AstVisitor {
   void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
   void GenerateIsArray(ZoneList<Expression*>* args);
 
+  // Support for construct call checks.
+  void GenerateIsConstructCall(ZoneList<Expression*>* args);
+
   // Support for arguments.length and arguments[?].
   void GenerateArgumentsLength(ZoneList<Expression*>* args);
   void GenerateArgumentsAccess(ZoneList<Expression*>* args);