Index: src/code-stub-assembler.cc |
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc |
index eb7e49da46d352883ccad891f19f348217b8cdec..7c42f27e710daa9c09dfde5f31ad6d81b5560075 100644 |
--- a/src/code-stub-assembler.cc |
+++ b/src/code-stub-assembler.cc |
@@ -471,6 +471,66 @@ Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) { |
IntPtrConstant(0)); |
} |
+void CodeStubAssembler::BranchIfSameValueZero(Node* a, Node* b, Node* context, |
Benedikt Meurer
2016/07/15 17:59:55
Nice, this looks pretty good already. You'll have
|
+ Label* if_true, Label* if_false) { |
+ Node* number_map = HeapNumberMapConstant(); |
+ Label a_isnumber(this), a_isnotnumber(this), b_isnumber(this), a_isnan(this), |
+ float_not_equal(this); |
+ // If register A and register B are identical, goto `if_true` |
+ GotoIf(WordEqual(a, b), if_true); |
+ // If either register A or B are Smis, goto `if_false` |
+ GotoIf(WordIsSmi(a), if_false); |
+ GotoIf(WordIsSmi(b), if_false); |
+ |
+ Node* map_a = LoadMap(a); |
+ Node* map_b = LoadMap(b); |
+ Branch(WordEqual(map_a, number_map), &a_isnumber, &a_isnotnumber); |
+ |
+ // If both register A and B are HeapNumbers, return true if they are equal, |
+ // or if both are NaN |
+ Bind(&a_isnumber); |
+ { |
+ Branch(WordEqual(map_b, number_map), &b_isnumber, if_false); |
+ |
+ Bind(&b_isnumber); |
+ Node* a_value = LoadHeapNumberValue(a); |
+ Node* b_value = LoadHeapNumberValue(b); |
+ BranchIfFloat64Equal(a_value, b_value, if_true, &float_not_equal); |
+ |
+ Bind(&float_not_equal); |
+ BranchIfFloat64IsNaN(a_value, &a_isnan, if_false); |
+ |
+ Bind(&a_isnan); |
+ BranchIfFloat64IsNaN(a_value, if_true, if_false); |
+ } |
+ |
+ Bind(&a_isnotnumber); |
+ { |
+ Label a_isstring(this); |
+ Node* a_instance_type = LoadMapInstanceType(map_a); |
+ |
+ Branch(Int32LessThan(a_instance_type, Int32Constant(FIRST_NONSTRING_TYPE)), |
+ &a_isstring, if_false); |
Benedikt Meurer
2016/07/15 17:59:55
Instead of going to if_false here, you can check i
|
+ |
+ Bind(&a_isstring); |
+ { |
+ Label b_isstring(this), b_isnotstring(this); |
+ Node* b_instance_type = LoadInstanceType(map_b); |
+ |
+ Branch( |
+ Int32LessThan(b_instance_type, Int32Constant(FIRST_NONSTRING_TYPE)), |
+ &b_isstring, if_false); |
+ |
+ Bind(&b_isstring); |
+ { |
+ Callable callable = CodeFactory::StringEqual(isolate()); |
+ Node* result = CallStub(callable, context, a, b); |
+ Branch(WordEqual(BooleanConstant(true), result), if_true, if_false); |
+ } |
+ } |
+ } |
+} |
+ |
Node* CodeStubAssembler::AllocateRawUnaligned(Node* size_in_bytes, |
AllocationFlags flags, |
Node* top_address, |