Optimize Date construction and string concatenation with
authorkasperl@chromium.org <kasperl@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 3 Jul 2009 10:09:59 +0000 (10:09 +0000)
committerkasperl@chromium.org <kasperl@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 3 Jul 2009 10:09:59 +0000 (10:09 +0000)
string objects (not values).
Review URL: http://codereview.chromium.org/149177

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

src/date-delay.js
src/math.js
src/runtime.js

index 5a109c6b6cdc9df921f456b49edb4df9b0f6d8e0..3414cb985509e6278d5a2433ea8040d111b11c40 100644 (file)
@@ -47,7 +47,7 @@ function ThrowDateTypeError() {
 
 // ECMA 262 - 15.9.1.2
 function Day(time) {
-  return FLOOR(time/msPerDay);
+  return FLOOR(time / msPerDay);
 }
 
 
@@ -428,29 +428,33 @@ function TimeClip(time) {
 
 
 %SetCode($Date, function(year, month, date, hours, minutes, seconds, ms) {
-  if (%_IsConstructCall()) {
-    // ECMA 262 - 15.9.3
-    var argc = %_ArgumentsLength();
-    if (argc == 0) {
-      %_SetValueOf(this, %DateCurrentTime());
-      return;
-    }
-    if (argc == 1) {
+  if (!%_IsConstructCall()) {
+    // ECMA 262 - 15.9.2
+    return (new $Date()).toString();
+  }
+
+  // ECMA 262 - 15.9.3
+  var argc = %_ArgumentsLength();
+  var value;
+  if (argc == 0) {
+    value = %DateCurrentTime();
+
+  } else if (argc == 1) {
+    if (IS_NUMBER(year)) {
+      value = TimeClip(year);
+    } else {
       // According to ECMA 262, no hint should be given for this
-      // conversion.  However, ToPrimitive defaults to String Hint
-      // for Date objects which will lose precision when the Date
+      // conversion. However, ToPrimitive defaults to STRING_HINT for
+      // Date objects which will lose precision when the Date
       // constructor is called with another Date object as its
-      // argument.  We therefore use Number Hint for the conversion
-      // (which is the default for everything else than Date
-      // objects).  This makes us behave like KJS and SpiderMonkey.
+      // argument. We therefore use NUMBER_HINT for the conversion,
+      // which is the default for everything else than Date objects.
+      // This makes us behave like KJS and SpiderMonkey.
       var time = ToPrimitive(year, NUMBER_HINT);
-      if (IS_STRING(time)) {
-        %_SetValueOf(this, DateParse(time));
-      } else {
-        %_SetValueOf(this, TimeClip(ToNumber(time)));
-      }
-      return;
+      value = IS_STRING(time) ? DateParse(time) : TimeClip(ToNumber(time));
     }
+
+  } else {
     year = ToNumber(year);
     month = ToNumber(month);
     date = argc > 2 ? ToNumber(date) : 1;
@@ -462,11 +466,9 @@ function TimeClip(time) {
         ? 1900 + TO_INTEGER(year) : year;
     var day = MakeDay(year, month, date);
     var time = MakeTime(hours, minutes, seconds, ms);
-    %_SetValueOf(this, TimeClip(UTC(MakeDate(day, time))));
-  } else {
-    // ECMA 262 - 15.9.2
-    return (new $Date()).toString();
+    value = TimeClip(UTC(MakeDate(day, time)));
   }
+  %_SetValueOf(this, value);
 });
 
 
index 1f5ce87af93f8672fa9c6af0cb5cc274a67a8679..d12927e74a06b89970b71a9582671a4fd986d2a6 100644 (file)
@@ -95,7 +95,9 @@ function MathExp(x) {
 // ECMA 262 - 15.8.2.9
 function MathFloor(x) {
   if (!IS_NUMBER(x)) x = ToNumber(x);
-  if (0 < x && x <= 0x7FFFFFFF) {
+  // It's more common to call this with a positive number that's out
+  // of range than negative numbers; check the upper bound first.
+  if (x <= 0x7FFFFFFF && x > 0) {
     // Numbers in the range [0, 2^31) can be floored by converting
     // them to an unsigned 32-bit value using the shift operator.
     // We avoid doing so for -0, because the result of Math.floor(-0)
index 25cc5baa8e771232342509d7aa8cf07b6703eb7e..789bfdb77fcd8b8fee2d37eaf4c8fa7b1a3b2bb3 100644 (file)
@@ -161,14 +161,31 @@ function ADD(x) {
 
 // Left operand (this) is already a string.
 function STRING_ADD_LEFT(y) {
-  if (!IS_STRING(y)) y = %ToString(%ToPrimitive(y, NO_HINT));
+  if (!IS_STRING(y)) {
+    if (IS_STRING_WRAPPER(y)) {
+      y = %_ValueOf(y);
+    } else {
+      y = IS_NUMBER(y)
+          ? %NumberToString(y)
+          : %ToString(%ToPrimitive(y, NO_HINT));
+    }
+  }
   return %StringAdd(this, y);
 }
 
 
 // Right operand (y) is already a string.
 function STRING_ADD_RIGHT(y) {
-  var x = IS_STRING(this) ? this : %ToString(%ToPrimitive(this, NO_HINT));
+  var x = this;
+  if (!IS_STRING(x)) {
+    if (IS_STRING_WRAPPER(x)) {
+      x = %_ValueOf(x);
+    } else {
+      x = IS_NUMBER(x)
+          ? %NumberToString(x)
+          : %ToString(%ToPrimitive(x, NO_HINT));
+    }
+  }
   return %StringAdd(x, y);
 }