Revision: 8722
Author:   [email protected]
Date:     Fri Jul 22 05:42:40 2011
Log: 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
http://code.google.com/p/v8/source/detail?r=8722

Modified:
 /branches/bleeding_edge/src/code-stubs.cc
 /branches/bleeding_edge/src/code-stubs.h
 /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc

=======================================
--- /branches/bleeding_edge/src/code-stubs.cc   Thu Jul 21 06:51:04 2011
+++ /branches/bleeding_edge/src/code-stubs.cc   Fri Jul 22 05:42:40 2011
@@ -342,7 +342,6 @@
   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 @@
   } 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();
   }
 }

=======================================
--- /branches/bleeding_edge/src/code-stubs.h    Thu Jul 21 06:51:04 2011
+++ /branches/bleeding_edge/src/code-stubs.h    Fri Jul 22 05:42:40 2011
@@ -905,7 +905,6 @@
     BOOLEAN,
     NULL_TYPE,
     SMI,
-    UNDETECTABLE,
     SPEC_OBJECT,
     STRING,
     HEAP_NUMBER,
@@ -913,21 +912,25 @@
     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 @@

  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,
=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Thu Jul 21 06:51:04 2011 +++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Fri Jul 22 05:42:40 2011
@@ -259,7 +259,6 @@
   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 @@
     // 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::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.

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to