Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Unified Diff: src/codegen-ia32.cc

Issue 7014: Make strict equality checks faster on IA32 by doing... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/runtime.js » ('j') | src/runtime.js » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/codegen-ia32.cc
===================================================================
--- src/codegen-ia32.cc (revision 478)
+++ src/codegen-ia32.cc (working copy)
@@ -1490,9 +1490,8 @@
__ pop(edx);
}
+ // Check for the smi case.
Label is_smi, done;
- CompareStub stub(cc, strict);
-
__ mov(ecx, Operand(eax));
__ or_(ecx, Operand(edx));
__ test(ecx, Immediate(kSmiTagMask));
@@ -1500,8 +1499,13 @@
// When non-smi, call out to the compare stub. "parameters" setup by
// calling code in edx and eax and "result" is returned in the flags.
+ CompareStub stub(cc, strict);
__ CallStub(&stub);
- __ cmp(eax, 0);
+ if (cc == equal) {
+ __ test(eax, Operand(eax));
+ } else {
+ __ cmp(eax, 0);
+ }
__ jmp(&done);
// Test smi equality by pointer comparison.
@@ -4846,6 +4850,73 @@
void CompareStub::Generate(MacroAssembler* masm) {
Label call_builtin, done;
+
+ // If we're doing a strict equality comparison, we generate code
+ // to do fast comparison for objects and oddballs. Numbers and
+ // strings still go through the usual slow-case code.
+ if (strict_) {
+ Label slow;
+ __ test(eax, Immediate(kSmiTagMask));
+ __ j(zero, &slow);
+
+ // Get the type of the first operand.
+ __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
+ __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
+
+ // If the first object is an object, we do pointer comparison.
+ ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+ Label non_object;
+ __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
+ __ j(less, &non_object);
+ __ sub(eax, Operand(edx));
+ __ ret(0);
+
+ // Check for oddballs: true, false, null, undefined.
+ __ bind(&non_object);
+ __ cmp(ecx, ODDBALL_TYPE);
+ __ j(not_equal, &slow);
+
+ // If the oddball isn't undefined, we do pointer comparison. For
+ // the undefined value, we have to be careful and check for
+ // 'undetectable' objects too.
+ Label undefined;
+ __ cmp(Operand(eax), Immediate(Factory::undefined_value()));
+ __ j(equal, &undefined);
+ __ sub(eax, Operand(edx));
+ __ ret(0);
+
+ // Undefined case: If the other operand isn't undefined too, we
+ // have to check if it's 'undetectable'.
+ Label check_undetectable;
+ __ bind(&undefined);
+ __ cmp(Operand(edx), Immediate(Factory::undefined_value()));
+ __ j(not_equal, &check_undetectable);
+ __ Set(eax, Immediate(0));
+ __ ret(0);
+
+ // Check for undetectability of the other operand.
+ Label not_strictly_equal;
+ __ bind(&check_undetectable);
+ __ test(edx, Immediate(kSmiTagMask));
+ __ j(zero, &not_strictly_equal);
+ __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
+ __ movzx_b(ecx, FieldOperand(ecx, Map::kBitFieldOffset));
+ __ and_(ecx, 1 << Map::kIsUndetectable);
+ __ cmp(ecx, 1 << Map::kIsUndetectable);
+ __ j(not_equal, &not_strictly_equal);
+ __ Set(eax, Immediate(0));
+ __ ret(0);
+
+ // No cigar: Objects aren't strictly equal. Register eax contains
+ // a non-smi value so it can't be 0. Just return.
+ ASSERT(kHeapTag != 0);
+ __ bind(&not_strictly_equal);
+ __ ret(0);
+
+ // Fall through to the general case.
+ __ bind(&slow);
+ }
+
// Save the return address (and get it off the stack).
__ pop(ecx);
« no previous file with comments | « no previous file | src/runtime.js » ('j') | src/runtime.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698