Commit 01216a06 authored by kasperl@chromium.org's avatar kasperl@chromium.org

Add fast negative checks for symbol equality: If we're comparing

two symbols, they're only equal if the objects are identical.
Review URL: http://codereview.chromium.org/125184

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2188 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 52dfeca5
...@@ -150,6 +150,8 @@ var DST_offset_cache = { ...@@ -150,6 +150,8 @@ var DST_offset_cache = {
}; };
// NOTE: The implementation relies on the fact that no time zones have
// more than one daylight savings offset change per month.
function DaylightSavingsOffset(t) { function DaylightSavingsOffset(t) {
// Load the cache object from the builtins object. // Load the cache object from the builtins object.
var cache = DST_offset_cache; var cache = DST_offset_cache;
...@@ -530,7 +532,8 @@ function GetUTCHoursFrom(aDate) { ...@@ -530,7 +532,8 @@ function GetUTCHoursFrom(aDate) {
function GetFullYearFrom(aDate) { function GetFullYearFrom(aDate) {
var t = GetTimeFrom(aDate); var t = GetTimeFrom(aDate);
if ($isNaN(t)) return t; if ($isNaN(t)) return t;
return YearFromTime(LocalTimeNoCheck(t)); // Ignore the DST offset for year computations.
return YearFromTime(t + local_time_offset);
} }
......
...@@ -1806,6 +1806,12 @@ class CompareStub: public CodeStub { ...@@ -1806,6 +1806,12 @@ class CompareStub: public CodeStub {
return (static_cast<int>(cc_) << 1) | (strict_ ? 1 : 0); return (static_cast<int>(cc_) << 1) | (strict_ ? 1 : 0);
} }
// Branch to the label if the given object isn't a symbol.
void BranchIfNonSymbol(MacroAssembler* masm,
Label* label,
Register object,
Register scratch);
#ifdef DEBUG #ifdef DEBUG
void Print() { void Print() {
PrintF("CompareStub (cc %d), (strict %s)\n", PrintF("CompareStub (cc %d), (strict %s)\n",
...@@ -6992,17 +6998,16 @@ void CompareStub::Generate(MacroAssembler* masm) { ...@@ -6992,17 +6998,16 @@ void CompareStub::Generate(MacroAssembler* masm) {
__ bind(&slow); __ bind(&slow);
} }
// Save the return address (and get it off the stack). // Push arguments below the return address.
__ pop(ecx); __ pop(ecx);
// Push arguments.
__ push(eax); __ push(eax);
__ push(edx); __ push(edx);
__ push(ecx); __ push(ecx);
// Inlined floating point compare. // Inlined floating point compare.
// Call builtin if operands are not floating point or smi. // Call builtin if operands are not floating point or smi.
FloatingPointHelper::CheckFloatOperands(masm, &call_builtin, ebx); Label check_for_symbols;
FloatingPointHelper::CheckFloatOperands(masm, &check_for_symbols, ebx);
FloatingPointHelper::LoadFloatOperands(masm, ecx); FloatingPointHelper::LoadFloatOperands(masm, ecx);
__ FCmp(); __ FCmp();
...@@ -7026,6 +7031,18 @@ void CompareStub::Generate(MacroAssembler* masm) { ...@@ -7026,6 +7031,18 @@ void CompareStub::Generate(MacroAssembler* masm) {
__ mov(eax, 1); __ mov(eax, 1);
__ ret(2 * kPointerSize); // eax, edx were pushed __ ret(2 * kPointerSize); // eax, edx were pushed
// Fast negative check for symbol-to-symbol equality.
__ bind(&check_for_symbols);
if (cc_ == equal) {
BranchIfNonSymbol(masm, &call_builtin, eax, ecx);
BranchIfNonSymbol(masm, &call_builtin, edx, ecx);
// We've already checked for object identity, so if both operands
// are symbols they aren't equal. Register eax already holds a
// non-zero value, which indicates not equal, so just return.
__ ret(2 * kPointerSize);
}
__ bind(&call_builtin); __ bind(&call_builtin);
// must swap argument order // must swap argument order
__ pop(ecx); __ pop(ecx);
...@@ -7059,6 +7076,20 @@ void CompareStub::Generate(MacroAssembler* masm) { ...@@ -7059,6 +7076,20 @@ void CompareStub::Generate(MacroAssembler* masm) {
} }
void CompareStub::BranchIfNonSymbol(MacroAssembler* masm,
Label* label,
Register object,
Register scratch) {
__ test(object, Immediate(kSmiTagMask));
__ j(zero, label);
__ mov(scratch, FieldOperand(object, HeapObject::kMapOffset));
__ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
__ and_(scratch, kIsSymbolMask | kIsNotStringMask);
__ cmp(scratch, kSymbolTag | kStringTag);
__ j(not_equal, label);
}
void StackCheckStub::Generate(MacroAssembler* masm) { void StackCheckStub::Generate(MacroAssembler* masm) {
// Because builtins always remove the receiver from the stack, we // Because builtins always remove the receiver from the stack, we
// have to fake one to avoid underflowing the stack. The receiver // have to fake one to avoid underflowing the stack. The receiver
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment