Make accessors for oddball objects return Oddball* instead of Object*.

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
This commit is contained in:
fschneider@chromium.org 2011-10-10 09:21:48 +00:00
parent 8898b97dc4
commit 313f9505b4
15 changed files with 95 additions and 67 deletions

View 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();

View 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,

View 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

View 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); }

View 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;
}
Oddball::cast(undefined_value())->set_to_string(String::cast(symbol));
Oddball::cast(undefined_value())->set_to_number(nan_value());
// Allocate the null_value
// Finish initializing oddballs after creating symboltable.
{ MaybeObject* maybe_obj =
Oddball::cast(null_value())->Initialize("null",
Smi::FromInt(0),
Oddball::kNull);
undefined_value()->Initialize("undefined",
nan_value(),
Oddball::kUndefined);
if (!maybe_obj->ToObject(&obj)) return false;
}
// Initialize the null_value.
{ MaybeObject* maybe_obj =
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.

View 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) \

View 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();

View File

@ -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()) {

View 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();

View 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 =

View 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()) {

View 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);
};

View 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);
}
}

View 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);

View 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)