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
-~----------~----~----~----~------~----~------~--~---