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

Unified Diff: src/x64/code-stubs-x64.cc

Issue 7497063: Simplify and optimize ToBoolean handling. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 4 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
Index: src/x64/code-stubs-x64.cc
===================================================================
--- src/x64/code-stubs-x64.cc (revision 8868)
+++ src/x64/code-stubs-x64.cc (working copy)
@@ -242,14 +242,14 @@
}
// undefined -> false
- CheckOddball(masm, UNDEFINED, Heap::kUndefinedValueRootIndex, false, &patch);
+ CheckOddball(masm, UNDEFINED, Heap::kUndefinedValueRootIndex, false);
// Boolean -> its value
- CheckOddball(masm, BOOLEAN, Heap::kFalseValueRootIndex, false, &patch);
- CheckOddball(masm, BOOLEAN, Heap::kTrueValueRootIndex, true, &patch);
+ CheckOddball(masm, BOOLEAN, Heap::kFalseValueRootIndex, false);
+ CheckOddball(masm, BOOLEAN, Heap::kTrueValueRootIndex, true);
// 'null' -> false.
- CheckOddball(masm, NULL_TYPE, Heap::kNullValueRootIndex, false, &patch);
+ CheckOddball(masm, NULL_TYPE, Heap::kNullValueRootIndex, false);
if (types_.Contains(SMI)) {
// Smis: 0 -> false, all other -> true
@@ -269,15 +269,16 @@
if (types_.NeedsMap()) {
__ movq(map, FieldOperand(argument, HeapObject::kMapOffset));
- // Everything with a map could be undetectable, so check this now.
- __ testb(FieldOperand(map, Map::kBitFieldOffset),
- Immediate(1 << Map::kIsUndetectable));
- // Undetectable -> false.
- Label not_undetectable;
- __ j(zero, &not_undetectable, Label::kNear);
- __ Set(tos_, 0);
- __ ret(1 * kPointerSize);
- __ bind(&not_undetectable);
+ if (types_.CanBeUndetectable()) {
+ __ testb(FieldOperand(map, Map::kBitFieldOffset),
+ Immediate(1 << Map::kIsUndetectable));
+ // Undetectable -> false.
+ Label not_undetectable;
+ __ j(zero, &not_undetectable, Label::kNear);
+ __ Set(tos_, 0);
+ __ ret(1 * kPointerSize);
+ __ bind(&not_undetectable);
+ }
}
if (types_.Contains(SPEC_OBJECT)) {
@@ -285,13 +286,12 @@
Label not_js_object;
__ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
__ j(below, &not_js_object, Label::kNear);
- __ Set(tos_, 1);
+ // argument contains the correct return value already.
+ if (!tos_.is(argument)) {
+ __ Set(tos_, 1);
+ }
__ ret(1 * kPointerSize);
__ bind(&not_js_object);
- } else if (types_.Contains(INTERNAL_OBJECT)) {
- // We've seen a spec object for the first time -> patch.
- __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
- __ j(above_equal, &patch, Label::kNear);
}
if (types_.Contains(STRING)) {
@@ -302,10 +302,6 @@
__ movq(tos_, FieldOperand(argument, String::kLengthOffset));
__ ret(1 * kPointerSize); // the string length is OK as the return value
__ bind(&not_string);
- } else if (types_.Contains(INTERNAL_OBJECT)) {
- // We've seen a string for the first time -> patch
- __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
- __ j(below, &patch, Label::kNear);
}
if (types_.Contains(HEAP_NUMBER)) {
@@ -316,50 +312,42 @@
__ xorps(xmm0, xmm0);
__ ucomisd(xmm0, FieldOperand(argument, HeapNumber::kValueOffset));
__ j(zero, &false_result, Label::kNear);
- __ Set(tos_, 1);
+ // argument contains the correct return value already.
+ if (!tos_.is(argument)) {
+ __ Set(tos_, 1);
+ }
__ ret(1 * kPointerSize);
__ bind(&false_result);
__ Set(tos_, 0);
__ ret(1 * kPointerSize);
__ bind(&not_heap_number);
- } else if (types_.Contains(INTERNAL_OBJECT)) {
- // We've seen a heap number for the first time -> patch
- __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
- __ j(equal, &patch, Label::kNear);
}
- if (types_.Contains(INTERNAL_OBJECT)) {
- // internal objects -> true
- __ Set(tos_, 1);
- __ ret(1 * kPointerSize);
- }
-
- if (!types_.IsAll()) {
- __ bind(&patch);
- GenerateTypeTransition(masm);
- }
+ __ bind(&patch);
+ GenerateTypeTransition(masm);
}
void ToBooleanStub::CheckOddball(MacroAssembler* masm,
Type type,
Heap::RootListIndex value,
- bool result,
- Label* patch) {
+ bool result) {
const Register argument = rax;
if (types_.Contains(type)) {
// If we see an expected oddball, return its ToBoolean value tos_.
Label different_value;
__ CompareRoot(argument, value);
__ j(not_equal, &different_value, Label::kNear);
- __ Set(tos_, result ? 1 : 0);
+ if (!result) {
+ // If we have to return zero, there is no way around clearing tos_.
+ __ Set(tos_, 0);
+ } else if (!tos_.is(argument)) {
+ // If we have to return non-zero, we can re-use the argument if it is the
+ // same register as the result, because we never see Smi-zero here.
+ __ Set(tos_, 1);
+ }
__ ret(1 * kPointerSize);
__ bind(&different_value);
- } else if (types_.Contains(INTERNAL_OBJECT)) {
- // If we see an unexpected oddball and handle internal objects, we must
- // patch because the code for internal objects doesn't handle it explictly.
- __ CompareRoot(argument, value);
- __ j(equal, patch);
}
}

Powered by Google App Engine
This is Rietveld 408576698