Make accessors for oddball objects return Oddball* instead of Object*.
authorfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 10 Oct 2011 09:21:48 +0000 (09:21 +0000)
committerfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 10 Oct 2011 09:21:48 +0000 (09:21 +0000)
Fix a use of the hole value and the undefined value before initialization when
initializing V8. Before we just read a NULL value from them.
Review URL: http://codereview.chromium.org/8130002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9557 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

15 files changed:
src/compiler.cc
src/debug.cc
src/factory.cc
src/factory.h
src/heap.cc
src/heap.h
src/hydrogen.cc
src/ic.cc
src/isolate.cc
src/messages.cc
src/objects.cc
src/objects.h
src/type-info.cc
src/type-info.h
src/v8utils.h

index 5a86b4e..7584fd2 100644 (file)
@@ -276,7 +276,7 @@ static bool MakeCrankshaftCode(CompilationInfo* info) {
   }
 
   Handle<Context> global_context(info->closure()->context()->global_context());
-  TypeFeedbackOracle oracle(code, global_context);
+  TypeFeedbackOracle oracle(code, global_context, info->isolate());
   HGraphBuilder builder(info, &oracle);
   HPhase phase(HPhase::kTotal);
   HGraph* graph = builder.CreateGraph();
index adce92a..3d79485 100644 (file)
@@ -2158,8 +2158,7 @@ Handle<Object> Debugger::MakeExceptionEvent(Handle<Object> exec_state,
   // Create the new exception event object.
   Handle<Object> argv[] = { exec_state,
                             exception,
-                            uncaught ? factory->true_value()
-                                     : factory->false_value() };
+                            factory->ToBoolean(uncaught) };
   return MakeJSObject(CStrVector("MakeExceptionEvent"),
                       ARRAY_SIZE(argv),
                       argv,
@@ -2187,9 +2186,7 @@ Handle<Object> Debugger::MakeCompileEvent(Handle<Script> script,
   Handle<Object> script_wrapper = GetScriptWrapper(script);
   Handle<Object> argv[] = { exec_state,
                             script_wrapper,
-                            before ? factory->true_value()
-                                   : factory->false_value() };
-
+                            factory->ToBoolean(before) };
   return MakeJSObject(CStrVector("MakeCompileEvent"),
                       ARRAY_SIZE(argv),
                       argv,
index ec64173..143b342 100644 (file)
@@ -1336,4 +1336,11 @@ Handle<Object> Factory::GlobalConstantFor(Handle<String> name) {
 }
 
 
+Handle<Object> Factory::ToBoolean(bool value) {
+  return Handle<Object>(value
+                        ? isolate()->heap()->true_value()
+                        : isolate()->heap()->false_value());
+}
+
+
 } }  // namespace v8::internal
index 85f46c5..a3615f2 100644 (file)
@@ -451,6 +451,9 @@ class Factory {
   // Returns a null handle when the given name is unknown.
   Handle<Object> GlobalConstantFor(Handle<String> name);
 
+  // Converts the given boolean condition to JavaScript boolean value.
+  Handle<Object> ToBoolean(bool value);
+
  private:
   Isolate* isolate() { return reinterpret_cast<Isolate*>(this); }
 
index d1f48ac..b40b820 100644 (file)
@@ -1804,9 +1804,16 @@ bool Heap::CreateInitialMaps() {
   { MaybeObject* maybe_obj = Allocate(oddball_map(), OLD_POINTER_SPACE);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
-  set_null_value(obj);
+  set_null_value(Oddball::cast(obj));
   Oddball::cast(obj)->set_kind(Oddball::kNull);
 
+  { MaybeObject* maybe_obj = Allocate(oddball_map(), OLD_POINTER_SPACE);
+    if (!maybe_obj->ToObject(&obj)) return false;
+  }
+  set_undefined_value(Oddball::cast(obj));
+  Oddball::cast(obj)->set_kind(Oddball::kUndefined);
+  ASSERT(!InNewSpace(undefined_value()));
+
   // Allocate the empty descriptor array.
   { MaybeObject* maybe_obj = AllocateEmptyFixedArray();
     if (!maybe_obj->ToObject(&obj)) return false;
@@ -2178,25 +2185,18 @@ bool Heap::CreateInitialObjects() {
   { MaybeObject* maybe_obj = AllocateHeapNumber(-0.0, TENURED);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
-  set_minus_zero_value(obj);
+  set_minus_zero_value(HeapNumber::cast(obj));
   ASSERT(signbit(minus_zero_value()->Number()) != 0);
 
   { MaybeObject* maybe_obj = AllocateHeapNumber(OS::nan_value(), TENURED);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
-  set_nan_value(obj);
+  set_nan_value(HeapNumber::cast(obj));
 
   { MaybeObject* maybe_obj = AllocateHeapNumber(V8_INFINITY, TENURED);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
-  set_infinity_value(obj);
-
-  { MaybeObject* maybe_obj = Allocate(oddball_map(), OLD_POINTER_SPACE);
-    if (!maybe_obj->ToObject(&obj)) return false;
-  }
-  set_undefined_value(obj);
-  Oddball::cast(obj)->set_kind(Oddball::kUndefined);
-  ASSERT(!InNewSpace(undefined_value()));
+  set_infinity_value(HeapNumber::cast(obj));
 
   // Allocate initial symbol table.
   { MaybeObject* maybe_obj = SymbolTable::Allocate(kInitialSymbolTableSize);
@@ -2205,19 +2205,17 @@ bool Heap::CreateInitialObjects() {
   // Don't use set_symbol_table() due to asserts.
   roots_[kSymbolTableRootIndex] = obj;
 
-  // Assign the print strings for oddballs after creating symboltable.
-  Object* symbol;
-  { MaybeObject* maybe_symbol = LookupAsciiSymbol("undefined");
-    if (!maybe_symbol->ToObject(&symbol)) return false;
+  // Finish initializing oddballs after creating symboltable.
+  { MaybeObject* maybe_obj =
+        undefined_value()->Initialize("undefined",
+                                      nan_value(),
+                                      Oddball::kUndefined);
+    if (!maybe_obj->ToObject(&obj)) return false;
   }
-  Oddball::cast(undefined_value())->set_to_string(String::cast(symbol));
-  Oddball::cast(undefined_value())->set_to_number(nan_value());
 
-  // Allocate the null_value
+  // Initialize the null_value.
   { MaybeObject* maybe_obj =
-        Oddball::cast(null_value())->Initialize("null",
-                                                Smi::FromInt(0),
-                                                Oddball::kNull);
+        null_value()->Initialize("null", Smi::FromInt(0), Oddball::kNull);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
 
@@ -2226,28 +2224,28 @@ bool Heap::CreateInitialObjects() {
                                            Oddball::kTrue);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
-  set_true_value(obj);
+  set_true_value(Oddball::cast(obj));
 
   { MaybeObject* maybe_obj = CreateOddball("false",
                                            Smi::FromInt(0),
                                            Oddball::kFalse);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
-  set_false_value(obj);
+  set_false_value(Oddball::cast(obj));
 
   { MaybeObject* maybe_obj = CreateOddball("hole",
                                            Smi::FromInt(-1),
                                            Oddball::kTheHole);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
-  set_the_hole_value(obj);
+  set_the_hole_value(Oddball::cast(obj));
 
   { MaybeObject* maybe_obj = CreateOddball("arguments_marker",
                                            Smi::FromInt(-2),
                                            Oddball::kArgumentMarker);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
-  set_arguments_marker(obj);
+  set_arguments_marker(Oddball::cast(obj));
 
   { MaybeObject* maybe_obj = CreateOddball("no_interceptor_result_sentinel",
                                            Smi::FromInt(-3),
@@ -2268,7 +2266,7 @@ bool Heap::CreateInitialObjects() {
                                            Oddball::kOther);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
-  set_frame_alignment_marker(obj);
+  set_frame_alignment_marker(Oddball::cast(obj));
   STATIC_ASSERT(Oddball::kLeastHiddenOddballNumber == -5);
 
   // Allocate the empty string.
index 8672db2..1192ada 100644 (file)
@@ -52,20 +52,20 @@ inline Heap* _inline_get_heap_();
 
 
 // Defines all the roots in Heap.
-#define STRONG_ROOT_LIST(V)                                      \
+#define STRONG_ROOT_LIST(V)                                                    \
   V(Map, byte_array_map, ByteArrayMap)                                         \
   V(Map, free_space_map, FreeSpaceMap)                                         \
   V(Map, one_pointer_filler_map, OnePointerFillerMap)                          \
   V(Map, two_pointer_filler_map, TwoPointerFillerMap)                          \
   /* Cluster the most popular ones in a few cache lines here at the top.    */ \
   V(Smi, store_buffer_top, StoreBufferTop)                                     \
-  V(Object, undefined_value, UndefinedValue)                                   \
-  V(Object, the_hole_value, TheHoleValue)                                      \
-  V(Object, null_value, NullValue)                                             \
-  V(Object, true_value, TrueValue)                                             \
-  V(Object, false_value, FalseValue)                                           \
-  V(Object, arguments_marker, ArgumentsMarker)                                 \
-  V(Object, frame_alignment_marker, FrameAlignmentMarker)                      \
+  V(Oddball, undefined_value, UndefinedValue)                                  \
+  V(Oddball, the_hole_value, TheHoleValue)                                     \
+  V(Oddball, null_value, NullValue)                                            \
+  V(Oddball, true_value, TrueValue)                                            \
+  V(Oddball, false_value, FalseValue)                                          \
+  V(Oddball, arguments_marker, ArgumentsMarker)                                \
+  V(Oddball, frame_alignment_marker, FrameAlignmentMarker)                     \
   V(Map, heap_number_map, HeapNumberMap)                                       \
   V(Map, global_context_map, GlobalContextMap)                                 \
   V(Map, fixed_array_map, FixedArrayMap)                                       \
@@ -126,9 +126,9 @@ inline Heap* _inline_get_heap_();
   V(Map, shared_function_info_map, SharedFunctionInfoMap)                      \
   V(Map, message_object_map, JSMessageObjectMap)                               \
   V(Map, foreign_map, ForeignMap)                                              \
-  V(Object, nan_value, NanValue)                                               \
-  V(Object, infinity_value, InfinityValue)                                     \
-  V(Object, minus_zero_value, MinusZeroValue)                                  \
+  V(HeapNumber, nan_value, NanValue)                                           \
+  V(HeapNumber, infinity_value, InfinityValue)                                 \
+  V(HeapNumber, minus_zero_value, MinusZeroValue)                              \
   V(Map, neander_map, NeanderMap)                                              \
   V(JSObject, message_listeners, MessageListeners)                             \
   V(Foreign, prototype_accessors, PrototypeAccessors)                          \
index 25e0a3d..cd97df5 100644 (file)
@@ -4663,7 +4663,8 @@ bool HGraphBuilder::TryInline(Call* expr) {
   ASSERT(target_shared->has_deoptimization_support());
   TypeFeedbackOracle target_oracle(
       Handle<Code>(target_shared->code()),
-      Handle<Context>(target->context()->global_context()));
+      Handle<Context>(target->context()->global_context()),
+      isolate());
   FunctionState target_state(this, &target_info, &target_oracle);
 
   HConstant* undefined = graph()->GetConstantUndefined();
index 4bf419c..834dbfd 100644 (file)
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -167,7 +167,7 @@ static bool HasNormalObjectsInPrototypeChain(Isolate* isolate,
                                              LookupResult* lookup,
                                              Object* receiver) {
   Object* end = lookup->IsProperty()
-      ? lookup->holder() : isolate->heap()->null_value();
+      ? lookup->holder() : Object::cast(isolate->heap()->null_value());
   for (Object* current = receiver;
        current != end;
        current = current->GetPrototype()) {
index 951f428..492694e 100644 (file)
@@ -98,6 +98,14 @@ void ThreadLocalTop::InitializeInternal() {
   failed_access_check_callback_ = NULL;
   save_context_ = NULL;
   catcher_ = NULL;
+
+  // These members are re-initialized later after deserialization
+  // is complete.
+  pending_exception_ = NULL;
+  has_pending_message_ = false;
+  pending_message_obj_ = NULL;
+  pending_message_script_ = NULL;
+  scheduled_exception_ = NULL;
 }
 
 
@@ -1284,6 +1292,9 @@ char* Isolate::ArchiveThread(char* to) {
   memcpy(to, reinterpret_cast<char*>(thread_local_top()),
          sizeof(ThreadLocalTop));
   InitializeThreadLocal();
+  clear_pending_exception();
+  clear_pending_message();
+  clear_scheduled_exception();
   return to + sizeof(ThreadLocalTop);
 }
 
@@ -1611,9 +1622,6 @@ Isolate::~Isolate() {
 void Isolate::InitializeThreadLocal() {
   thread_local_top_.isolate_ = this;
   thread_local_top_.Initialize();
-  clear_pending_exception();
-  clear_pending_message();
-  clear_scheduled_exception();
 }
 
 
@@ -1771,6 +1779,11 @@ bool Isolate::Init(Deserializer* des) {
     stub_cache_->Initialize(true);
   }
 
+  // Finish initialization of ThreadLocal after deserialization is done.
+  clear_pending_exception();
+  clear_pending_message();
+  clear_scheduled_exception();
+
   // Deserializing may put strange things in the root array's copy of the
   // stack guard.
   heap_.SetStackLimits();
index 9e80cd0..c70463d 100644 (file)
@@ -80,11 +80,11 @@ Handle<JSMessageObject> MessageHandler::MakeMessageObject(
   }
 
   Handle<Object> stack_trace_handle = stack_trace.is_null()
-      ? FACTORY->undefined_value()
+      ? Handle<Object>::cast(FACTORY->undefined_value())
       : Handle<Object>::cast(stack_trace);
 
   Handle<Object> stack_frames_handle = stack_frames.is_null()
-      ? FACTORY->undefined_value()
+      ? Handle<Object>::cast(FACTORY->undefined_value())
       : Handle<Object>::cast(stack_frames);
 
   Handle<JSMessageObject> message =
index 70bc4d5..a2a3276 100644 (file)
@@ -545,7 +545,9 @@ MaybeObject* Object::GetProperty(Object* receiver,
   // holder in the prototype chain.
   // Proxy handlers do not use the proxy's prototype, so we can skip this.
   if (!result->IsHandler()) {
-    Object* last = result->IsProperty() ? result->holder() : heap->null_value();
+    Object* last = result->IsProperty()
+        ? result->holder()
+        : Object::cast(heap->null_value());
     ASSERT(this != this->GetPrototype());
     for (Object* current = this; true; current = current->GetPrototype()) {
       if (current->IsAccessCheckNeeded()) {
index 7e531b2..d7e0b1d 100644 (file)
@@ -5216,8 +5216,6 @@ class GlobalObject: public JSObject {
   static const int kHeaderSize = kGlobalReceiverOffset + kPointerSize;
 
  private:
-  friend class AGCCVersionRequiresThisClassToHaveAFriendSoHereItIs;
-
   DISALLOW_IMPLICIT_CONSTRUCTORS(GlobalObject);
 };
 
@@ -7151,7 +7149,6 @@ class TemplateInfo: public Struct {
   static const int kPropertyListOffset = kTagOffset + kPointerSize;
   static const int kHeaderSize         = kPropertyListOffset + kPointerSize;
  protected:
-  friend class AGCCVersionRequiresThisClassToHaveAFriendSoHereItIs;
   DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo);
 };
 
index 293632b..c8d4db6 100644 (file)
@@ -60,8 +60,10 @@ TypeInfo TypeInfo::TypeFromValue(Handle<Object> value) {
 
 
 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
-                                       Handle<Context> global_context) {
+                                       Handle<Context> global_context,
+                                       Isolate* isolate) {
   global_context_ = global_context;
+  isolate_ = isolate;
   BuildDictionary(code);
   ASSERT(reinterpret_cast<Address>(*dictionary_.location()) != kHandleZapValue);
 }
@@ -71,7 +73,7 @@ Handle<Object> TypeFeedbackOracle::GetInfo(unsigned ast_id) {
   int entry = dictionary_->FindEntry(ast_id);
   return entry != NumberDictionary::kNotFound
       ? Handle<Object>(dictionary_->ValueAt(entry))
-      : Isolate::Current()->factory()->undefined_value();
+      : Handle<Object>::cast(isolate_->factory()->undefined_value());
 }
 
 
@@ -93,7 +95,7 @@ bool TypeFeedbackOracle::LoadIsMegamorphicWithTypeInfo(Property* expr) {
   Handle<Object> map_or_code = GetInfo(expr->id());
   if (map_or_code->IsCode()) {
     Handle<Code> code = Handle<Code>::cast(map_or_code);
-    Builtins* builtins = Isolate::Current()->builtins();
+    Builtins* builtins = isolate_->builtins();
     return code->is_keyed_load_stub() &&
         *code != builtins->builtin(Builtins::kKeyedLoadIC_Generic) &&
         code->ic_state() == MEGAMORPHIC;
@@ -119,7 +121,7 @@ bool TypeFeedbackOracle::StoreIsMegamorphicWithTypeInfo(Expression* expr) {
   Handle<Object> map_or_code = GetInfo(expr->id());
   if (map_or_code->IsCode()) {
     Handle<Code> code = Handle<Code>::cast(map_or_code);
-    Builtins* builtins = Isolate::Current()->builtins();
+    Builtins* builtins = isolate_->builtins();
     return code->is_keyed_store_stub() &&
         *code != builtins->builtin(Builtins::kKeyedStoreIC_Generic) &&
         *code != builtins->builtin(Builtins::kKeyedStoreIC_Generic_Strict) &&
@@ -233,7 +235,7 @@ Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(Call* expr) {
 
 bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) {
   return *GetInfo(expr->id()) ==
-      Isolate::Current()->builtins()->builtin(id);
+      isolate_->builtins()->builtin(id);
 }
 
 
@@ -403,11 +405,10 @@ void TypeFeedbackOracle::CollectReceiverTypes(unsigned ast_id,
                                               Handle<String> name,
                                               Code::Flags flags,
                                               SmallMapList* types) {
-  Isolate* isolate = Isolate::Current();
   Handle<Object> object = GetInfo(ast_id);
   if (object->IsUndefined() || object->IsSmi()) return;
 
-  if (*object == isolate->builtins()->builtin(Builtins::kStoreIC_GlobalProxy)) {
+  if (*object == isolate_->builtins()->builtin(Builtins::kStoreIC_GlobalProxy)) {
     // TODO(fschneider): We could collect the maps and signal that
     // we need a generic store (or load) here.
     ASSERT(Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC);
@@ -416,7 +417,7 @@ void TypeFeedbackOracle::CollectReceiverTypes(unsigned ast_id,
   } else if (Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC) {
     types->Reserve(4);
     ASSERT(object->IsCode());
-    isolate->stub_cache()->CollectMatchingMaps(types, *name, flags);
+    isolate_->stub_cache()->CollectMatchingMaps(types, *name, flags);
   }
 }
 
index e1ccc28..0ba10aa 100644 (file)
@@ -216,7 +216,9 @@ class UnaryOperation;
 
 class TypeFeedbackOracle BASE_EMBEDDED {
  public:
-  TypeFeedbackOracle(Handle<Code> code, Handle<Context> global_context);
+  TypeFeedbackOracle(Handle<Code> code,
+                     Handle<Context> global_context,
+                     Isolate* isolate);
 
   bool LoadIsMonomorphicNormal(Property* expr);
   bool LoadIsMegamorphicWithTypeInfo(Property* expr);
@@ -282,6 +284,7 @@ class TypeFeedbackOracle BASE_EMBEDDED {
   Handle<Object> GetInfo(unsigned ast_id);
 
   Handle<Context> global_context_;
+  Isolate* isolate_;
   Handle<NumberDictionary> dictionary_;
 
   DISALLOW_COPY_AND_ASSIGN(TypeFeedbackOracle);
index aada521..c854f04 100644 (file)
@@ -142,8 +142,14 @@ inline void CopyWords(T* dst, T* src, int num_words) {
 }
 
 
-template <typename T>
-static inline void MemsetPointer(T** dest, T* value, int counter) {
+template <typename T, typename U>
+static inline void MemsetPointer(T** dest, U* value, int counter) {
+#ifdef DEBUG
+  T* a = NULL;
+  U* b = NULL;
+  a = b;  // Fake assignment to check assignability.
+  USE(a);
+#endif  // DEBUG
 #if defined(V8_HOST_ARCH_IA32)
 #define STOS "stosl"
 #elif defined(V8_HOST_ARCH_X64)