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:
parent
8898b97dc4
commit
313f9505b4
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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); }
|
||||
|
||||
|
54
src/heap.cc
54
src/heap.cc
@ -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.
|
||||
|
22
src/heap.h
22
src/heap.h
@ -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) \
|
||||
|
@ -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();
|
||||
|
@ -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()) {
|
||||
|
@ -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();
|
||||
|
@ -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 =
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user