Author: [EMAIL PROTECTED]
Date: Tue Oct  7 03:54:50 2008
New Revision: 458

Modified:
    branches/bleeding_edge/src/date-delay.js
    branches/bleeding_edge/src/heap.h
    branches/bleeding_edge/src/macros.py
    branches/bleeding_edge/src/runtime.cc
    branches/bleeding_edge/src/runtime.h
    branches/bleeding_edge/src/runtime.js
    branches/bleeding_edge/src/string.js

Log:
- Added %IsArrayClass, %IsDateClass, and %IsStringClass.
- Added the FLOOR macro that only works on Number objects.
- Added LocalTimeNoCheck in the date code to eliminate some isNaN checks.
- Change computation of four_year_cycle_table to load time.
- Added fast case check to EQUALS and STRICT_EQUALS.

Review URL: http://codereview.chromium.org/6531

Modified: branches/bleeding_edge/src/date-delay.js
==============================================================================
--- branches/bleeding_edge/src/date-delay.js    (original)
+++ branches/bleeding_edge/src/date-delay.js    Tue Oct  7 03:54:50 2008
@@ -43,7 +43,7 @@

  // ECMA 262 - 15.9.1.2
  function Day(time) {
-  return $floor(time/msPerDay);
+  return FLOOR(time/msPerDay);
  }


@@ -69,9 +69,9 @@

  function DayFromYear(year) {
    return 365 * (year-1970)
-      + $floor((year-1969)/4)
-      - $floor((year-1901)/100)
-      + $floor((year-1601)/400);
+      + FLOOR((year-1969)/4)
+      - FLOOR((year-1901)/100)
+      + FLOOR((year-1601)/400);
  }


@@ -170,6 +170,10 @@
    return time + local_time_offset + DaylightSavingsOffset(time);
  }

+function LocalTimeNoCheck(time) {
+  return time + local_time_offset + DaylightSavingsOffset(time);
+}
+

  function UTC(time) {
    if ($isNaN(time)) return time;
@@ -180,17 +184,17 @@

  // ECMA 262 - 15.9.1.10
  function HourFromTime(time) {
-  return Modulo($floor(time / msPerHour), HoursPerDay);
+  return Modulo(FLOOR(time / msPerHour), HoursPerDay);
  }


  function MinFromTime(time) {
-  return Modulo($floor(time / msPerMinute), MinutesPerHour);
+  return Modulo(FLOOR(time / msPerMinute), MinutesPerHour);
  }


  function SecFromTime(time) {
-  return Modulo($floor(time / msPerSecond), SecondsPerMinute);
+  return Modulo(FLOOR(time / msPerSecond), SecondsPerMinute);
  }


@@ -223,12 +227,11 @@
  function ToJulianDay(year, month, date) {
    var jy = (month > 1) ? year : year - 1;
    var jm = (month > 1) ? month + 2 : month + 14;
-  var ja = $floor(0.01*jy);
-  return $floor($floor(365.25*jy) + $floor(30.6001*jm) + date + 1720995) +  
2 - ja + $floor(0.25*ja);
+  var ja = FLOOR(0.01*jy);
+  return FLOOR(FLOOR(365.25*jy) + FLOOR(30.6001*jm) + date + 1720995) + 2  
- ja + FLOOR(0.25*ja);
  }

-
-var four_year_cycle_table;
+var four_year_cycle_table = CalculateDateTable();


  function CalculateDateTable() {
@@ -261,7 +264,6 @@
  }


-
  // Constructor for creating objects holding year, month, and date.
  // Introduced to ensure the two return points in FromJulianDay match same  
map.
  function DayTriplet(year, month, date) {
@@ -279,8 +281,6 @@
    // when doing the multiply-to-divide trick.
    if (julian > kDayZeroInJulianDay &&
        (julian - kDayZeroInJulianDay) < 40177) { // 1970 - 2080
-    if (!four_year_cycle_table)
-      four_year_cycle_table = CalculateDateTable();
      var jsimple = (julian - kDayZeroInJulianDay) + 731; // Day 0 is 1st  
January 1968
      var y = 1968;
      // Divide by 1461 by multiplying with 22967 and shifting down by 25!
@@ -292,19 +292,20 @@
                             (four_year_cycle & kMonthMask) >> kMonthShift,
                             four_year_cycle & kDayMask);
    }
-  var jalpha = $floor((julian - 1867216.25) / 36524.25);
-  var jb = julian + 1 + jalpha - $floor(0.25 * jalpha) + 1524;
-  var jc = $floor(6680.0 + ((jb-2439870) - 122.1)/365.25);
-  var jd = $floor(365 * jc + (0.25 * jc));
-  var je = $floor((jb - jd)/30.6001);
+  var jalpha = FLOOR((julian - 1867216.25) / 36524.25);
+  var jb = julian + 1 + jalpha - FLOOR(0.25 * jalpha) + 1524;
+  var jc = FLOOR(6680.0 + ((jb-2439870) - 122.1)/365.25);
+  var jd = FLOOR(365 * jc + (0.25 * jc));
+  var je = FLOOR((jb - jd)/30.6001);
    var m = je - 1;
    if (m > 12) m -= 13;
    var y = jc - 4715;
    if (m > 2) { --y; --m; }
-  var d = jb - jd - $floor(30.6001 * je);
+  var d = jb - jd - FLOOR(30.6001 * je);
    return new DayTriplet(y, m, d);
  }

+
  // Compute number of days given a year, month, date.
  // Note that month and date can lie outside the normal range.
  //   For example:
@@ -320,7 +321,7 @@
    date = TO_INTEGER(date);

    // Overflow months into year.
-  year = year + $floor(month/12);
+  year = year + FLOOR(month/12);
    month = month % 12;
    if (month < 0) {
      month += 12;
@@ -400,7 +401,7 @@
  function GetMillisecondsFrom(aDate) {
    var t = GetTimeFrom(aDate);
    if ($isNaN(t)) return t;
-  return msFromTime(LocalTime(t));
+  return msFromTime(LocalTimeNoCheck(t));
  }


@@ -414,7 +415,7 @@
  function GetSecondsFrom(aDate) {
    var t = GetTimeFrom(aDate);
    if ($isNaN(t)) return t;
-  return SecFromTime(LocalTime(t));
+  return SecFromTime(LocalTimeNoCheck(t));
  }


@@ -428,7 +429,7 @@
  function GetMinutesFrom(aDate) {
    var t = GetTimeFrom(aDate);
    if ($isNaN(t)) return t;
-  return MinFromTime(LocalTime(t));
+  return MinFromTime(LocalTimeNoCheck(t));
  }


@@ -442,7 +443,7 @@
  function GetHoursFrom(aDate) {
    var t = GetTimeFrom(aDate);
    if ($isNaN(t)) return t;
-  return HourFromTime(LocalTime(t));
+  return HourFromTime(LocalTimeNoCheck(t));
  }


@@ -456,7 +457,7 @@
  function GetFullYearFrom(aDate) {
    var t = GetTimeFrom(aDate);
    if ($isNaN(t)) return t;
-  return YearFromTime(LocalTime(t));
+  return YearFromTime(LocalTimeNoCheck(t));
  }


@@ -470,7 +471,7 @@
  function GetMonthFrom(aDate) {
    var t = GetTimeFrom(aDate);
    if ($isNaN(t)) return t;
-  return MonthFromTime(LocalTime(t));
+  return MonthFromTime(LocalTimeNoCheck(t));
  }


@@ -484,7 +485,7 @@
  function GetDateFrom(aDate) {
    var t = GetTimeFrom(aDate);
    if ($isNaN(t)) return t;
-  return DateFromTime(LocalTime(t));
+  return DateFromTime(LocalTimeNoCheck(t));
  }


@@ -526,8 +527,8 @@
  function LocalTimezoneString(time) {
    var timezoneOffset = (local_time_offset + DaylightSavingsOffset(time)) /  
msPerMinute;
    var sign = (timezoneOffset >= 0) ? 1 : -1;
-  var hours = $floor((sign * timezoneOffset)/60);
-  var min   = $floor((sign * timezoneOffset)%60);
+  var hours = FLOOR((sign * timezoneOffset)/60);
+  var min   = FLOOR((sign * timezoneOffset)%60);
    var gmt = ' GMT' + ((sign == 1) ? '+' : '-') + TwoDigitString(hours) +  
TwoDigitString(min);
    return gmt + ' (' +  LocalTimezone(time) + ')';
  }
@@ -586,7 +587,7 @@
  function DateToString() {
    var t = GetTimeFrom(this);
    if ($isNaN(t)) return kInvalidDate;
-  return DatePrintString(LocalTime(t)) + LocalTimezoneString(t);
+  return DatePrintString(LocalTimeNoCheck(t)) + LocalTimezoneString(t);
  }


@@ -594,7 +595,7 @@
  function DateToDateString() {
    var t = GetTimeFrom(this);
    if ($isNaN(t)) return kInvalidDate;
-  return DateString(LocalTime(t));
+  return DateString(LocalTimeNoCheck(t));
  }


@@ -602,7 +603,7 @@
  function DateToTimeString() {
    var t = GetTimeFrom(this);
    if ($isNaN(t)) return kInvalidDate;
-  var lt = LocalTime(t);
+  var lt = LocalTimeNoCheck(t);
    return TimeString(lt) + LocalTimezoneString(lt);
  }

@@ -623,7 +624,7 @@
  function DateToLocaleTimeString() {
    var t = GetTimeFrom(this);
    if ($isNaN(t)) return kInvalidDate;
-  var lt = LocalTime(t);
+  var lt = LocalTimeNoCheck(t);
    return TimeString(lt);
  }

@@ -680,7 +681,7 @@
  function DateGetDay() {
    var t = GetTimeFrom(this);
    if ($isNaN(t)) return t;
-  return WeekDay(LocalTime(t));
+  return WeekDay(LocalTimeNoCheck(t));
  }


@@ -744,7 +745,7 @@
  function DateGetTimezoneOffset() {
    var t = GetTimeFrom(this);
    if ($isNaN(t)) return t;
-  return (t - LocalTime(t)) / msPerMinute;
+  return (t - LocalTimeNoCheck(t)) / msPerMinute;
  }


@@ -884,7 +885,7 @@
  // ECMA 262 - 15.9.5.40
  function DateSetFullYear(year, month, date) {
    var t = GetTimeFrom(this);
-  t = $isNaN(t) ? 0 : LocalTime(t);
+  t = $isNaN(t) ? 0 : LocalTimeNoCheck(t);
    year = ToNumber(year);
    var argc = %_ArgumentsLength();
    month = argc < 2 ? MonthFromTime(t) : ToNumber(month);
@@ -924,7 +925,7 @@
  function DateGetYear() {
    var t = GetTimeFrom(this);
    if ($isNaN(t)) return $NaN;
-  return YearFromTime(LocalTime(t)) - 1900;
+  return YearFromTime(LocalTimeNoCheck(t)) - 1900;
  }



Modified: branches/bleeding_edge/src/heap.h
==============================================================================
--- branches/bleeding_edge/src/heap.h   (original)
+++ branches/bleeding_edge/src/heap.h   Tue Oct  7 03:54:50 2008
@@ -154,6 +154,8 @@
    V(object_symbol, "object")                                             \
    V(prototype_symbol, "prototype")                                       \
    V(string_symbol, "string")                                             \
+  V(String_symbol, "String")                                             \
+  V(Date_symbol, "Date")                                                 \
    V(this_symbol, "this")                                                 \
    V(to_string_symbol, "toString")                                        \
    V(char_at_symbol, "CharAt")                                            \

Modified: branches/bleeding_edge/src/macros.py
==============================================================================
--- branches/bleeding_edge/src/macros.py        (original)
+++ branches/bleeding_edge/src/macros.py        Tue Oct  7 03:54:50 2008
@@ -79,10 +79,11 @@
  macro IS_OBJECT(arg)            = (typeof(arg) === 'object');
  macro IS_BOOLEAN(arg)           = (typeof(arg) === 'boolean');
  macro IS_REGEXP(arg)            = (%ClassOf(arg) === 'RegExp');
-macro IS_ARRAY(arg)             = (%ClassOf(arg) === 'Array');
-macro IS_DATE(arg)              = (%ClassOf(arg) === 'Date');
+macro IS_ARRAY(arg)             = %IsArrayClass(arg);
+macro IS_DATE(arg)              = %IsDateClass(arg);
  macro IS_ERROR(arg)             = (%ClassOf(arg) === 'Error');
  macro IS_SCRIPT(arg)            = (%ClassOf(arg) === 'Script');
+macro FLOOR(arg)                = %Math_floor(arg);

  # Inline macros. Use %IS_VAR to make sure arg is evaluated only once.
  macro NUMBER_IS_NAN(arg) = (!%_IsSmi(%IS_VAR(arg)) && !(arg == arg));

Modified: branches/bleeding_edge/src/runtime.cc
==============================================================================
--- branches/bleeding_edge/src/runtime.cc       (original)
+++ branches/bleeding_edge/src/runtime.cc       Tue Oct  7 03:54:50 2008
@@ -221,6 +221,30 @@
    return JSObject::cast(obj)->class_name();
  }

+inline static Object* IsSpecificClassOf(Arguments args, String* name) {
+  NoHandleAllocation ha;
+  ASSERT(args.length() == 1);
+  Object* obj = args[0];
+  if (obj->IsJSObject() && (JSObject::cast(obj)->class_name() == name)) {
+    return Heap::true_value();
+  }
+  return Heap::false_value();
+}
+
+static Object* Runtime_IsStringClass(Arguments args) {
+  return IsSpecificClassOf(args, Heap::String_symbol());
+}
+
+
+static Object* Runtime_IsDateClass(Arguments args) {
+  return IsSpecificClassOf(args, Heap::Date_symbol());
+}
+
+
+static Object* Runtime_IsArrayClass(Arguments args) {
+  return IsSpecificClassOf(args, Heap::Array_symbol());
+}
+

  static Object* Runtime_IsInPrototypeChain(Arguments args) {
    NoHandleAllocation ha;
@@ -2508,8 +2532,12 @@
    int len = x->length();
    if (len != y->length()) return Smi::FromInt(NOT_EQUAL);
    if (len == 0) return Smi::FromInt(EQUAL);
-  // Fast case:  First, middle and last characters.
+
+  // Handle one elment strings.
    if (x->Get(0) != y->Get(0)) return Smi::FromInt(NOT_EQUAL);
+  if (len == 1) return Smi::FromInt(EQUAL);
+
+  // Fast case:  First, middle and last characters.
    if (x->Get(len>>1) != y->Get(len>>1)) return Smi::FromInt(NOT_EQUAL);
    if (x->Get(len - 1) != y->Get(len - 1)) return Smi::FromInt(NOT_EQUAL);


Modified: branches/bleeding_edge/src/runtime.h
==============================================================================
--- branches/bleeding_edge/src/runtime.h        (original)
+++ branches/bleeding_edge/src/runtime.h        Tue Oct  7 03:54:50 2008
@@ -164,6 +164,9 @@
    F(GetScript, 1) \
    \
    F(ClassOf, 1) \
+  F(IsDateClass, 1) \
+  F(IsStringClass, 1) \
+  F(IsArrayClass, 1) \
    F(SetCode, 2) \
    \
    F(CreateApiFunction, 1) \

Modified: branches/bleeding_edge/src/runtime.js
==============================================================================
--- branches/bleeding_edge/src/runtime.js       (original)
+++ branches/bleeding_edge/src/runtime.js       Tue Oct  7 03:54:50 2008
@@ -52,36 +52,31 @@

  // ECMA-262, section 11.9.1, page 55.
  function EQUALS(y) {
+  if (IS_STRING(this) && IS_STRING(y)) return %StringEquals(this, y);
    var x = this;

    // NOTE: We use iteration instead of recursion, because it is
    // difficult to call EQUALS with the correct setting of 'this' in
    // an efficient way.
-
    while (true) {
-
      if (IS_NUMBER(x)) {
        if (y == null) return 1;  // not equal
        return %NumberEquals(x, %ToNumber(y));
-
      } else if (IS_STRING(x)) {
        if (IS_STRING(y)) return %StringEquals(x, y);
        if (IS_NUMBER(y)) return %NumberEquals(%ToNumber(x), y);
        if (IS_BOOLEAN(y)) return %NumberEquals(%ToNumber(x), %ToNumber(y));
        if (y == null) return 1;  // not equal
        y = %ToPrimitive(y, NO_HINT);
-
      } else if (IS_BOOLEAN(x)) {
        if (IS_BOOLEAN(y)) {
          return %_ObjectEquals(x, y) ? 0 : 1;
        }
        if (y == null) return 1;  // not equal
        return %NumberEquals(%ToNumber(x), %ToNumber(y));
-
      } else if (x == null) {
        // NOTE: This checks for both null and undefined.
        return (y == null) ? 0 : 1;
-
      } else {
        if (IS_OBJECT(y)) {
          return %_ObjectEquals(x, y) ? 0 : 1;
@@ -90,12 +85,10 @@
          return %_ObjectEquals(x, y) ? 0 : 1;
        }
        x = %ToPrimitive(x, NO_HINT);
-
      }
    }
  }

-
  // ECMA-262, section 11.9.4, page 56.
  function STRICT_EQUALS(x) {
    if (IS_NUMBER(this)) {
@@ -125,11 +118,15 @@
  // ECMA-262, section 11.8.5, page 53. The 'ncr' parameter is used as
  // the result when either (or both) the operands are NaN.
  function COMPARE(x, ncr) {
-  // Improve performance for floating point compares
+  // Fast case for numbers and strings.
    if (IS_NUMBER(this) && IS_NUMBER(x)) {
      return %NumberCompare(this, x, ncr);
    }
+  if (IS_STRING(this) && IS_STRING(x)) {
+    return %StringCompare(this, x);
+  }

+  // Default implementation.
    var a = %ToPrimitive(this, NUMBER_HINT);
    var b = %ToPrimitive(x, NUMBER_HINT);
    if (IS_STRING(a) && IS_STRING(b)) {
@@ -149,10 +146,10 @@
  // ECMA-262, section 11.6.1, page 50.
  function ADD(x) {
    // Fast case: Check for number operands and do the addition.
-  if (IS_NUMBER(this) && IS_NUMBER(x)) {
-    return %NumberAdd(this, x);
-  }
+  if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x);
+  if (IS_STRING(this) && IS_STRING(x)) return %StringAdd(this, x);

+  // Default implementation.
    var a = %ToPrimitive(this, NO_HINT);
    var b = %ToPrimitive(x, NO_HINT);

@@ -397,6 +394,10 @@
  // ECMA-262, section 9.1, page 30. Use null/undefined for no hint,
  // (1) for number hint, and (2) for string hint.
  function ToPrimitive(x, hint) {
+  // Fast case check.
+  if (IS_STRING(x)) return x;
+  if ((hint != NUMBER_HINT) && %IsStringClass(x)) return %_ValueOf(x);
+  // Normal behaior.
    if (!IS_OBJECT(x) && !IS_FUNCTION(x)) return x;
    if (x == null) return x;  // check for null, undefined
    if (hint == NO_HINT) hint = (IS_DATE(x)) ? STRING_HINT : NUMBER_HINT;

Modified: branches/bleeding_edge/src/string.js
==============================================================================
--- branches/bleeding_edge/src/string.js        (original)
+++ branches/bleeding_edge/src/string.js        Tue Oct  7 03:54:50 2008
@@ -46,7 +46,7 @@

  // ECMA-262 section 15.5.4.2
  function StringToString() {
-  if (!IS_STRING(this) && %ClassOf(this) !== 'String')
+  if (!IS_STRING(this) && !%IsStringClass(this))
      throw new $TypeError('String.prototype.toString is not generic');
    return %_ValueOf(this);
  }
@@ -54,7 +54,7 @@

  // ECMA-262 section 15.5.4.3
  function StringValueOf() {
-  if (!IS_STRING(this) && %ClassOf(this) !== 'String')
+  if (!IS_STRING(this) && !%IsStringClass(this))
      throw new $TypeError('String.prototype.valueOf is not generic');
    return %_ValueOf(this);
  }

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

Reply via email to