Do not explicitly record undetectable objects in the ToBoolean stub.

Loading the map within the stub already implies a check for an undetectable
object, so there is no need to record this separately. Furthermore, this brings
the size of the type info to record down to 8 bits, removing the need to find a
place for the ninth bit in the Code object. ;-)
Review URL: http://codereview.chromium.org/7484022

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8722 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
svenpanne@chromium.org 2011-07-22 12:42:40 +00:00
parent c081c550d6
commit 73f8cec70e
3 changed files with 24 additions and 26 deletions

View File

@ -342,7 +342,6 @@ void ToBooleanStub::Types::Print(StringStream* stream) {
if (Contains(BOOLEAN)) stream->Add("Bool");
if (Contains(SMI)) stream->Add("Smi");
if (Contains(NULL_TYPE)) stream->Add("Null");
if (Contains(UNDETECTABLE)) stream->Add("Undetectable");
if (Contains(SPEC_OBJECT)) stream->Add("SpecObject");
if (Contains(STRING)) stream->Add("String");
if (Contains(HEAP_NUMBER)) stream->Add("HeapNumber");
@ -378,22 +377,20 @@ bool ToBooleanStub::Types::Record(Handle<Object> object) {
} else if (object->IsSmi()) {
Add(SMI);
return Smi::cast(*object)->value() != 0;
} else if (object->IsUndetectableObject()) {
Add(UNDETECTABLE);
return false;
} else if (object->IsSpecObject()) {
Add(SPEC_OBJECT);
return true;
return !object->IsUndetectableObject();
} else if (object->IsString()) {
Add(STRING);
return String::cast(*object)->length() != 0;
return !object->IsUndetectableObject() &&
String::cast(*object)->length() != 0;
} else if (object->IsHeapNumber()) {
Add(HEAP_NUMBER);
double value = HeapNumber::cast(*object)->value();
return value != 0 && !isnan(value);
return !object->IsUndetectableObject() && value != 0 && !isnan(value);
} else {
Add(INTERNAL_OBJECT);
return true;
return !object->IsUndetectableObject();
}
}

View File

@ -905,7 +905,6 @@ class ToBooleanStub: public CodeStub {
BOOLEAN,
NULL_TYPE,
SMI,
UNDETECTABLE,
SPEC_OBJECT,
STRING,
HEAP_NUMBER,
@ -913,21 +912,25 @@ class ToBooleanStub: public CodeStub {
NUMBER_OF_TYPES
};
// At most 8 different types can be distinguished, because the Code object
// only has room for a single byte to hold a set of these types. :-P
STATIC_ASSERT(NUMBER_OF_TYPES <= 8);
class Types {
public:
Types() {}
explicit Types(int bits) : set_(bits) {}
explicit Types(byte bits) : set_(bits) {}
bool IsEmpty() const { return set_.IsEmpty(); }
bool Contains(Type type) const { return set_.Contains(type); }
void Add(Type type) { set_.Add(type); }
int ToInt() const { return set_.ToIntegral(); }
byte ToByte() const { return set_.ToIntegral(); }
void Print(StringStream* stream);
void TraceTransition(Types to);
bool Record(Handle<Object> object);
private:
EnumSet<Type> set_;
EnumSet<Type, byte> set_;
};
explicit ToBooleanStub(Register tos, Types types = Types())
@ -939,7 +942,11 @@ class ToBooleanStub: public CodeStub {
private:
Major MajorKey() { return ToBoolean; }
int MinorKey() { return (tos_.code() << NUMBER_OF_TYPES) | types_.ToInt(); }
int MinorKey() { return (tos_.code() << NUMBER_OF_TYPES) | types_.ToByte(); }
virtual void FinishCode(Code* code) {
code->set_to_boolean_state(types_.ToByte());
}
void CheckOddball(MacroAssembler* masm,
Type type,

View File

@ -259,7 +259,6 @@ void ToBooleanStub::Generate(MacroAssembler* masm) {
CheckOddball(masm, NULL_TYPE, factory->null_value(), false, &patch);
bool need_map =
types_.Contains(UNDETECTABLE) |
types_.Contains(SPEC_OBJECT) |
types_.Contains(STRING) |
types_.Contains(HEAP_NUMBER) |
@ -286,17 +285,12 @@ void ToBooleanStub::Generate(MacroAssembler* masm) {
// Everything with a map could be undetectable, so check this now.
__ test_b(FieldOperand(map, Map::kBitFieldOffset),
1 << Map::kIsUndetectable);
if (types_.Contains(UNDETECTABLE)) {
// Undetectable -> false.
Label not_undetectable;
__ j(zero, &not_undetectable, Label::kNear);
__ Set(tos_, Immediate(0));
__ ret(1 * kPointerSize);
__ bind(&not_undetectable);
} else {
// We've seen an undetectable value for the first time -> patch.
__ j(not_zero, &patch, Label::kNear);
}
// Undetectable -> false.
Label not_undetectable;
__ j(zero, &not_undetectable, Label::kNear);
__ Set(tos_, Immediate(0));
__ ret(1 * kPointerSize);
__ bind(&not_undetectable);
}
if (types_.Contains(SPEC_OBJECT)) {
@ -385,7 +379,7 @@ void ToBooleanStub::CheckOddball(MacroAssembler* masm,
void ToBooleanStub::GenerateTypeTransition(MacroAssembler* masm) {
__ pop(ecx); // Get return address, operand is now on top of stack.
__ push(Immediate(Smi::FromInt(tos_.code())));
__ push(Immediate(Smi::FromInt(types_.ToInt())));
__ push(Immediate(Smi::FromInt(types_.ToByte())));
__ push(ecx); // Push return address.
// Patch the caller to an appropriate specialized stub and return the
// operation result to the caller of the stub.