Avoid TLS accesses in Object::Lookup and Object::GetPrototype.

Both methods were among the top causes for TLS accesses.

BUG=v8:2487

Review URL: https://codereview.chromium.org/12319144

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13759 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
svenpanne@chromium.org 2013-02-27 13:22:29 +00:00
parent e819dd2869
commit c26d100b10
19 changed files with 166 additions and 120 deletions

View File

@ -42,8 +42,8 @@ namespace internal {
template <class C>
static C* FindInstanceOf(Object* obj) {
for (Object* cur = obj; !cur->IsNull(); cur = cur->GetPrototype()) {
static C* FindInstanceOf(Isolate* isolate, Object* obj) {
for (Object* cur = obj; !cur->IsNull(); cur = cur->GetPrototype(isolate)) {
if (Is<C>(cur)) return C::cast(cur);
}
return NULL;
@ -77,7 +77,7 @@ MaybeObject* Accessors::ReadOnlySetAccessor(JSObject*, Object* value, void*) {
MaybeObject* Accessors::ArrayGetLength(Object* object, void*) {
// Traverse the prototype chain until we reach an array.
JSArray* holder = FindInstanceOf<JSArray>(object);
JSArray* holder = FindInstanceOf<JSArray>(Isolate::Current(), object);
return holder == NULL ? Smi::FromInt(0) : holder->length();
}
@ -442,18 +442,19 @@ const AccessorDescriptor Accessors::ScriptEvalFromFunctionName = {
MaybeObject* Accessors::FunctionGetPrototype(Object* object, void*) {
Heap* heap = Isolate::Current()->heap();
JSFunction* function = FindInstanceOf<JSFunction>(object);
if (function == NULL) return heap->undefined_value();
Isolate* isolate = Isolate::Current();
JSFunction* function = FindInstanceOf<JSFunction>(isolate, object);
if (function == NULL) return isolate->heap()->undefined_value();
while (!function->should_have_prototype()) {
function = FindInstanceOf<JSFunction>(function->GetPrototype());
function = FindInstanceOf<JSFunction>(isolate, function->GetPrototype());
// There has to be one because we hit the getter.
ASSERT(function != NULL);
}
if (!function->has_prototype()) {
Object* prototype;
{ MaybeObject* maybe_prototype = heap->AllocateFunctionPrototype(function);
{ MaybeObject* maybe_prototype
= isolate->heap()->AllocateFunctionPrototype(function);
if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
}
Object* result;
@ -470,7 +471,7 @@ MaybeObject* Accessors::FunctionSetPrototype(JSObject* object,
void*) {
Isolate* isolate = object->GetIsolate();
Heap* heap = isolate->heap();
JSFunction* function_raw = FindInstanceOf<JSFunction>(object);
JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, object);
if (function_raw == NULL) return heap->undefined_value();
if (!function_raw->should_have_prototype()) {
// Since we hit this accessor, object will have no prototype property.
@ -522,7 +523,8 @@ const AccessorDescriptor Accessors::FunctionPrototype = {
MaybeObject* Accessors::FunctionGetLength(Object* object, void*) {
JSFunction* function = FindInstanceOf<JSFunction>(object);
Isolate* isolate = Isolate::Current();
JSFunction* function = FindInstanceOf<JSFunction>(isolate, object);
if (function == NULL) return Smi::FromInt(0);
// Check if already compiled.
if (function->shared()->is_compiled()) {
@ -530,7 +532,7 @@ MaybeObject* Accessors::FunctionGetLength(Object* object, void*) {
}
// If the function isn't compiled yet, the length is not computed correctly
// yet. Compile it now and return the right length.
HandleScope scope(function->GetIsolate());
HandleScope scope(isolate);
Handle<JSFunction> handle(function);
if (JSFunction::CompileLazy(handle, KEEP_EXCEPTION)) {
return Smi::FromInt(handle->shared()->length());
@ -552,8 +554,11 @@ const AccessorDescriptor Accessors::FunctionLength = {
MaybeObject* Accessors::FunctionGetName(Object* object, void*) {
JSFunction* holder = FindInstanceOf<JSFunction>(object);
return holder == NULL ? HEAP->undefined_value() : holder->shared()->name();
Isolate* isolate = Isolate::Current();
JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
return holder == NULL
? isolate->heap()->undefined_value()
: holder->shared()->name();
}
@ -599,7 +604,7 @@ static MaybeObject* ConstructArgumentsObjectForInlinedFunction(
MaybeObject* Accessors::FunctionGetArguments(Object* object, void*) {
Isolate* isolate = Isolate::Current();
HandleScope scope(isolate);
JSFunction* holder = FindInstanceOf<JSFunction>(object);
JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
if (holder == NULL) return isolate->heap()->undefined_value();
Handle<JSFunction> function(holder, isolate);
@ -723,7 +728,7 @@ MaybeObject* Accessors::FunctionGetCaller(Object* object, void*) {
Isolate* isolate = Isolate::Current();
HandleScope scope(isolate);
AssertNoAllocation no_alloc;
JSFunction* holder = FindInstanceOf<JSFunction>(object);
JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
if (holder == NULL) return isolate->heap()->undefined_value();
if (holder->shared()->native()) return isolate->heap()->null_value();
Handle<JSFunction> function(holder, isolate);
@ -782,18 +787,19 @@ const AccessorDescriptor Accessors::FunctionCaller = {
//
static inline Object* GetPrototypeSkipHiddenPrototypes(Object* receiver) {
Object* current = receiver->GetPrototype();
static inline Object* GetPrototypeSkipHiddenPrototypes(Isolate* isolate,
Object* receiver) {
Object* current = receiver->GetPrototype(isolate);
while (current->IsJSObject() &&
JSObject::cast(current)->map()->is_hidden_prototype()) {
current = current->GetPrototype();
current = current->GetPrototype(isolate);
}
return current;
}
MaybeObject* Accessors::ObjectGetPrototype(Object* receiver, void*) {
return GetPrototypeSkipHiddenPrototypes(receiver);
return GetPrototypeSkipHiddenPrototypes(Isolate::Current(), receiver);
}
@ -809,14 +815,14 @@ MaybeObject* Accessors::ObjectSetPrototype(JSObject* receiver_raw,
HandleScope scope(isolate);
Handle<JSObject> receiver(receiver_raw);
Handle<Object> value(value_raw, isolate);
Handle<Object> old_value(GetPrototypeSkipHiddenPrototypes(*receiver),
Handle<Object> old_value(GetPrototypeSkipHiddenPrototypes(isolate, *receiver),
isolate);
MaybeObject* result = receiver->SetPrototype(*value, kSkipHiddenPrototypes);
Handle<Object> hresult;
if (!result->ToHandle(&hresult, isolate)) return result;
Handle<Object> new_value(GetPrototypeSkipHiddenPrototypes(*receiver),
Handle<Object> new_value(GetPrototypeSkipHiddenPrototypes(isolate, *receiver),
isolate);
if (!new_value->SameValue(*old_value)) {
JSObject::EnqueueChangeRecord(receiver, "prototype",

View File

@ -2959,7 +2959,7 @@ Local<Value> v8::Object::GetPrototype() {
return Local<v8::Value>());
ENTER_V8(isolate);
i::Handle<i::Object> self = Utils::OpenHandle(this);
i::Handle<i::Object> result(self->GetPrototype(), isolate);
i::Handle<i::Object> result(self->GetPrototype(isolate), isolate);
return Utils::ToLocal(result);
}

View File

@ -1945,8 +1945,9 @@ Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
r0,
&miss);
ASSERT(!object.is_identical_to(holder));
CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
r0, holder, r1, r3, r4, name, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
r0, holder, r1, r3, r4, name, &miss);
Register receiver = r1;
Register index = r4;
@ -2025,8 +2026,9 @@ Handle<Code> CallStubCompiler::CompileStringCharAtCall(
r0,
&miss);
ASSERT(!object.is_identical_to(holder));
CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
r0, holder, r1, r3, r4, name, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
r0, holder, r1, r3, r4, name, &miss);
Register receiver = r0;
Register index = r4;
@ -2490,7 +2492,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
GenerateDirectLoadGlobalFunctionPrototype(
masm(), Context::STRING_FUNCTION_INDEX, r0, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype())),
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
r0, holder, r3, r1, r4, name, &miss);
break;
@ -2505,7 +2507,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
GenerateDirectLoadGlobalFunctionPrototype(
masm(), Context::NUMBER_FUNCTION_INDEX, r0, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype())),
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
r0, holder, r3, r1, r4, name, &miss);
break;
}
@ -2523,7 +2525,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
GenerateDirectLoadGlobalFunctionPrototype(
masm(), Context::BOOLEAN_FUNCTION_INDEX, r0, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype())),
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
r0, holder, r3, r1, r4, name, &miss);
break;
}

View File

@ -1222,7 +1222,7 @@ static inline Object* FindHidden(Heap* heap,
Object* object,
FunctionTemplateInfo* type) {
if (object->IsInstanceOf(type)) return object;
Object* proto = object->GetPrototype();
Object* proto = object->GetPrototype(heap->isolate());
if (proto->IsJSObject() &&
JSObject::cast(proto)->map()->is_hidden_prototype()) {
return FindHidden(heap, proto, type);

View File

@ -647,7 +647,7 @@ Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSReceiver> object,
// Only collect keys if access is permitted.
for (Handle<Object> p = object;
*p != isolate->heap()->null_value();
p = Handle<Object>(p->GetPrototype(), isolate)) {
p = Handle<Object>(p->GetPrototype(isolate), isolate)) {
if (p->IsJSProxy()) {
Handle<JSProxy> proxy(JSProxy::cast(*p), isolate);
Handle<Object> args[] = { proxy };

View File

@ -5989,8 +5989,10 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
proto = proto_result.holder();
} else {
// Otherwise, find the top prototype.
while (proto->GetPrototype()->IsJSObject()) proto = proto->GetPrototype();
ASSERT(proto->GetPrototype()->IsNull());
while (proto->GetPrototype(isolate())->IsJSObject()) {
proto = proto->GetPrototype(isolate());
}
ASSERT(proto->GetPrototype(isolate())->IsNull());
}
ASSERT(proto->IsJSObject());
AddInstruction(new(zone()) HCheckPrototypeMaps(

View File

@ -1874,8 +1874,9 @@ Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
eax,
&miss);
ASSERT(!object.is_identical_to(holder));
CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
eax, holder, ebx, edx, edi, name, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
eax, holder, ebx, edx, edi, name, &miss);
Register receiver = ebx;
Register index = edi;
@ -1957,8 +1958,9 @@ Handle<Code> CallStubCompiler::CompileStringCharAtCall(
eax,
&miss);
ASSERT(!object.is_identical_to(holder));
CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
eax, holder, ebx, edx, edi, name, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
eax, holder, ebx, edx, edi, name, &miss);
Register receiver = eax;
Register index = edi;
@ -2422,7 +2424,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
GenerateDirectLoadGlobalFunctionPrototype(
masm(), Context::STRING_FUNCTION_INDEX, eax, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype())),
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
eax, holder, ebx, edx, edi, name, &miss);
break;
@ -2437,7 +2439,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
GenerateDirectLoadGlobalFunctionPrototype(
masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype())),
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
eax, holder, ebx, edx, edi, name, &miss);
break;
}
@ -2453,7 +2455,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
GenerateDirectLoadGlobalFunctionPrototype(
masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype())),
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
eax, holder, ebx, edx, edi, name, &miss);
break;
}

View File

@ -129,8 +129,11 @@ InlineCacheHolderFlag IC::GetCodeCacheForObject(JSObject* object,
}
JSObject* IC::GetCodeCacheHolder(Object* object, InlineCacheHolderFlag holder) {
Object* map_owner = (holder == OWN_MAP ? object : object->GetPrototype());
JSObject* IC::GetCodeCacheHolder(Isolate* isolate,
Object* object,
InlineCacheHolderFlag holder) {
Object* map_owner =
holder == OWN_MAP ? object : object->GetPrototype(isolate);
ASSERT(map_owner->IsJSObject());
return JSObject::cast(map_owner);
}

View File

@ -174,16 +174,17 @@ static bool TryRemoveInvalidPrototypeDependentStub(Code* target,
InlineCacheHolderFlag cache_holder =
Code::ExtractCacheHolderFromFlags(target->flags());
Isolate* isolate = target->GetIsolate();
if (cache_holder == OWN_MAP && !receiver->IsJSObject()) {
// The stub was generated for JSObject but called for non-JSObject.
// IC::GetCodeCacheHolder is not applicable.
return false;
} else if (cache_holder == PROTOTYPE_MAP &&
receiver->GetPrototype()->IsNull()) {
receiver->GetPrototype(isolate)->IsNull()) {
// IC::GetCodeCacheHolder is not applicable.
return false;
}
Map* map = IC::GetCodeCacheHolder(receiver, cache_holder)->map();
Map* map = IC::GetCodeCacheHolder(isolate, receiver, cache_holder)->map();
// Decide whether the inline cache failed because of changes to the
// receiver itself or changes to one of its prototypes.
@ -734,7 +735,7 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
// GenerateMonomorphicCacheProbe. It is not the map which holds the stub.
Handle<JSObject> cache_object = object->IsJSObject()
? Handle<JSObject>::cast(object)
: Handle<JSObject>(JSObject::cast(object->GetPrototype()));
: Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())));
// Update the stub cache.
UpdateMegamorphicCache(cache_object->map(), *name, *code);
break;

View File

@ -129,7 +129,8 @@ class IC {
JSObject* holder);
static inline InlineCacheHolderFlag GetCodeCacheForObject(JSObject* object,
JSObject* holder);
static inline JSObject* GetCodeCacheHolder(Object* object,
static inline JSObject* GetCodeCacheHolder(Isolate* isolate,
Object* object,
InlineCacheHolderFlag holder);
protected:

View File

@ -1192,7 +1192,7 @@ bool Isolate::IsErrorObject(Handle<Object> obj) {
js_builtins_object()->GetPropertyNoExceptionThrown(error_key);
for (Object* prototype = *obj; !prototype->IsNull();
prototype = prototype->GetPrototype()) {
prototype = prototype->GetPrototype(this)) {
if (!prototype->IsJSObject()) return false;
if (JSObject::cast(prototype)->map()->constructor() == error_constructor) {
return true;

View File

@ -1946,8 +1946,9 @@ Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
v0,
&miss);
ASSERT(!object.is_identical_to(holder));
CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
v0, holder, a1, a3, t0, name, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
v0, holder, a1, a3, t0, name, &miss);
Register receiver = a1;
Register index = t1;
@ -2026,8 +2027,9 @@ Handle<Code> CallStubCompiler::CompileStringCharAtCall(
v0,
&miss);
ASSERT(!object.is_identical_to(holder));
CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
v0, holder, a1, a3, t0, name, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
v0, holder, a1, a3, t0, name, &miss);
Register receiver = v0;
Register index = t1;
@ -2483,7 +2485,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
GenerateDirectLoadGlobalFunctionPrototype(
masm(), Context::STRING_FUNCTION_INDEX, a0, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype())),
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
a0, holder, a3, a1, t0, name, &miss);
break;
@ -2498,7 +2500,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
GenerateDirectLoadGlobalFunctionPrototype(
masm(), Context::NUMBER_FUNCTION_INDEX, a0, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype())),
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
a0, holder, a3, a1, t0, name, &miss);
break;
}
@ -2514,7 +2516,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
GenerateDirectLoadGlobalFunctionPrototype(
masm(), Context::BOOLEAN_FUNCTION_INDEX, a0, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype())),
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
a0, holder, a3, a1, t0, name, &miss);
break;
}

View File

@ -135,7 +135,7 @@ void Object::Lookup(String* name, LookupResult* result) {
if (IsJSReceiver()) {
holder = this;
} else {
Context* native_context = Isolate::Current()->context()->native_context();
Context* native_context = result->isolate()->context()->native_context();
if (IsNumber()) {
holder = native_context->number_function()->instance_prototype();
} else if (IsString()) {
@ -613,7 +613,8 @@ MaybeObject* Object::GetProperty(Object* receiver,
// Make sure that the top context does not change when doing
// callbacks or interceptor calls.
AssertNoContextChange ncc;
Heap* heap = name->GetHeap();
Isolate* isolate = name->GetIsolate();
Heap* heap = isolate->heap();
// Traverse the prototype chain from the current object (this) to
// the holder and check for access rights. This avoids traversing the
@ -626,8 +627,10 @@ MaybeObject* Object::GetProperty(Object* receiver,
Object* last = result->IsProperty()
? result->holder()
: Object::cast(heap->null_value());
ASSERT(this != this->GetPrototype());
for (Object* current = this; true; current = current->GetPrototype()) {
ASSERT(this != this->GetPrototype(isolate));
for (Object* current = this;
true;
current = current->GetPrototype(isolate)) {
if (current->IsAccessCheckNeeded()) {
// Check if we're allowed to read from the current object. Note
// that even though we may not actually end up loading the named
@ -687,18 +690,18 @@ MaybeObject* Object::GetProperty(Object* receiver,
MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) {
Heap* heap = IsSmi()
? Isolate::Current()->heap()
: HeapObject::cast(this)->GetHeap();
Isolate* isolate = IsSmi()
? Isolate::Current()
: HeapObject::cast(this)->GetIsolate();
Heap* heap = isolate->heap();
Object* holder = this;
// Iterate up the prototype chain until an element is found or the null
// prototype is encountered.
for (holder = this;
holder != heap->null_value();
holder = holder->GetPrototype()) {
holder = holder->GetPrototype(isolate)) {
if (!holder->IsJSObject()) {
Isolate* isolate = heap->isolate();
Context* native_context = isolate->context()->native_context();
if (holder->IsNumber()) {
holder = native_context->number_function()->instance_prototype();
@ -744,10 +747,9 @@ MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) {
}
Object* Object::GetPrototype() {
Object* Object::GetPrototype(Isolate* isolate) {
if (IsSmi()) {
Heap* heap = Isolate::Current()->heap();
Context* context = heap->isolate()->context()->native_context();
Context* context = isolate->context()->native_context();
return context->number_function()->instance_prototype();
}
@ -758,8 +760,7 @@ Object* Object::GetPrototype() {
if (heap_object->IsJSReceiver()) {
return heap_object->map()->prototype();
}
Heap* heap = heap_object->GetHeap();
Context* context = heap->isolate()->context()->native_context();
Context* context = isolate->context()->native_context();
if (heap_object->IsHeapNumber()) {
return context->number_function()->instance_prototype();
@ -770,7 +771,7 @@ Object* Object::GetPrototype() {
if (heap_object->IsBoolean()) {
return context->boolean_function()->instance_prototype();
} else {
return heap->null_value();
return isolate->heap()->null_value();
}
}
@ -2100,10 +2101,10 @@ MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(
Heap* heap = GetHeap();
for (Object* pt = GetPrototype();
pt != heap->null_value();
pt = pt->GetPrototype()) {
pt = pt->GetPrototype(GetIsolate())) {
if (pt->IsJSProxy()) {
String* name;
MaybeObject* maybe = GetHeap()->Uint32ToString(index);
MaybeObject* maybe = heap->Uint32ToString(index);
if (!maybe->To<String>(&name)) {
*found = true; // Force abort
return maybe;
@ -2503,10 +2504,11 @@ void JSObject::LookupRealNamedProperty(String* name, LookupResult* result) {
void JSObject::LookupRealNamedPropertyInPrototypes(String* name,
LookupResult* result) {
Heap* heap = GetHeap();
Isolate* isolate = GetIsolate();
Heap* heap = isolate->heap();
for (Object* pt = GetPrototype();
pt != heap->null_value();
pt = pt->GetPrototype()) {
pt = pt->GetPrototype(isolate)) {
if (pt->IsJSProxy()) {
return result->HandlerResult(JSProxy::cast(pt));
}
@ -8149,13 +8151,14 @@ bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) {
return false;
}
Heap* heap = GetHeap();
Isolate* isolate = GetIsolate();
Heap* heap = isolate->heap();
// Traverse the proposed prototype chain looking for properties of the
// same names as are set by the inline constructor.
for (Object* obj = prototype;
obj != heap->null_value();
obj = obj->GetPrototype()) {
obj = obj->GetPrototype(isolate)) {
JSReceiver* receiver = JSReceiver::cast(obj);
for (int i = 0; i < this_property_assignments_count(); i++) {
LookupResult result(heap->isolate());
@ -9611,7 +9614,8 @@ MaybeObject* JSReceiver::SetPrototype(Object* value,
int size = Size();
#endif
Heap* heap = GetHeap();
Isolate* isolate = GetIsolate();
Heap* heap = isolate->heap();
// Silently ignore the change if value is not a JSObject or null.
// SpiderMonkey behaves this way.
if (!value->IsJSReceiver() && !value->IsNull()) return value;
@ -9625,22 +9629,24 @@ MaybeObject* JSReceiver::SetPrototype(Object* value,
// or [[Extensible]] must not violate the invariants defined in the preceding
// paragraph.
if (!this->map()->is_extensible()) {
HandleScope scope(heap->isolate());
Handle<Object> handle(this, heap->isolate());
return heap->isolate()->Throw(
*FACTORY->NewTypeError("non_extensible_proto",
HandleVector<Object>(&handle, 1)));
HandleScope scope(isolate);
Handle<Object> handle(this, isolate);
return isolate->Throw(
*isolate->factory()->NewTypeError("non_extensible_proto",
HandleVector<Object>(&handle, 1)));
}
// Before we can set the prototype we need to be sure
// prototype cycles are prevented.
// It is sufficient to validate that the receiver is not in the new prototype
// chain.
for (Object* pt = value; pt != heap->null_value(); pt = pt->GetPrototype()) {
for (Object* pt = value;
pt != heap->null_value();
pt = pt->GetPrototype(isolate)) {
if (JSReceiver::cast(pt) == this) {
// Cycle detected.
HandleScope scope(heap->isolate());
return heap->isolate()->Throw(
HandleScope scope(isolate);
return isolate->Throw(
*FACTORY->NewError("cyclic_proto", HandleVector<Object>(NULL, 0)));
}
}
@ -9654,7 +9660,7 @@ MaybeObject* JSReceiver::SetPrototype(Object* value,
while (current_proto->IsJSObject() &&
JSReceiver::cast(current_proto)->map()->is_hidden_prototype()) {
real_receiver = JSReceiver::cast(current_proto);
current_proto = current_proto->GetPrototype();
current_proto = current_proto->GetPrototype(isolate);
}
}

View File

@ -1019,7 +1019,7 @@ class Object : public MaybeObject {
uint32_t index);
// Return the object's prototype (might be Heap::null_value()).
Object* GetPrototype();
Object* GetPrototype(Isolate* isolate);
// Returns the permanent hash code associated with this object depending on
// the actual object type. Might return a failure in case no hash was

View File

@ -183,10 +183,12 @@ class LookupResult BASE_EMBEDDED {
}
~LookupResult() {
ASSERT(isolate_->top_lookup_result() == this);
isolate_->SetTopLookupResult(next_);
ASSERT(isolate()->top_lookup_result() == this);
isolate()->SetTopLookupResult(next_);
}
Isolate* isolate() const { return isolate_; }
void DescriptorResult(JSObject* holder, PropertyDetails details, int number) {
lookup_type_ = DESCRIPTOR_TYPE;
holder_ = holder;
@ -342,7 +344,7 @@ class LookupResult BASE_EMBEDDED {
case INTERCEPTOR:
case TRANSITION:
case NONEXISTENT:
return Isolate::Current()->heap()->the_hole_value();
return isolate()->heap()->the_hole_value();
}
UNREACHABLE();
return NULL;

View File

@ -959,7 +959,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) {
isolate->ReportFailedAccessCheck(JSObject::cast(obj), v8::ACCESS_GET);
return isolate->heap()->undefined_value();
}
obj = obj->GetPrototype();
obj = obj->GetPrototype(isolate);
} while (obj->IsJSObject() &&
JSObject::cast(obj)->map()->is_hidden_prototype());
return obj;
@ -973,7 +973,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) {
Object* O = args[0];
Object* V = args[1];
while (true) {
Object* prototype = V->GetPrototype();
Object* prototype = V->GetPrototype(isolate);
if (prototype->IsNull()) return isolate->heap()->false_value();
if (O == prototype) return isolate->heap()->true_value();
V = prototype;
@ -3899,7 +3899,7 @@ MaybeObject* Runtime::GetElementOrCharAt(Isolate* isolate,
}
if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
return object->GetPrototype()->GetElement(index);
return object->GetPrototype(isolate)->GetElement(index);
}
return object->GetElement(index);
@ -12039,7 +12039,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
// Skip the global proxy as it has no properties and always delegates to the
// real global object.
if (result->IsJSGlobalProxy()) {
result = Handle<JSObject>(JSObject::cast(result->GetPrototype()));
result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate)));
}
return *result;
@ -12153,7 +12153,8 @@ static int DebugReferencedBy(HeapIterator* iterator,
Object* instance_filter, int max_references,
FixedArray* instances, int instances_size,
JSFunction* arguments_function) {
NoHandleAllocation ha(target->GetIsolate());
Isolate* isolate = target->GetIsolate();
NoHandleAllocation ha(isolate);
AssertNoAllocation no_alloc;
// Iterate the heap.
@ -12179,7 +12180,7 @@ static int DebugReferencedBy(HeapIterator* iterator,
if (!instance_filter->IsUndefined()) {
Object* V = obj;
while (true) {
Object* prototype = V->GetPrototype();
Object* prototype = V->GetPrototype(isolate);
if (prototype->IsNull()) {
break;
}
@ -13249,7 +13250,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_UnwrapGlobalProxy) {
ASSERT(args.length() == 1);
Object* object = args[0];
if (object->IsJSGlobalProxy()) {
object = object->GetPrototype();
object = object->GetPrototype(isolate);
if (object->IsNull()) return isolate->heap()->undefined_value();
}
return object;

View File

@ -533,11 +533,13 @@ void StringStream::PrintFunction(Object* f, Object* receiver, Code** code) {
void StringStream::PrintPrototype(JSFunction* fun, Object* receiver) {
Object* name = fun->shared()->name();
bool print_name = false;
Heap* heap = HEAP;
for (Object* p = receiver; p != heap->null_value(); p = p->GetPrototype()) {
Isolate* isolate = fun->GetIsolate();
for (Object* p = receiver;
p != isolate->heap()->null_value();
p = p->GetPrototype(isolate)) {
if (p->IsJSObject()) {
Object* key = JSObject::cast(p)->SlowReverseLookup(fun);
if (key != heap->undefined_value()) {
if (key != isolate->heap()->undefined_value()) {
if (!name->IsString() ||
!key->IsString() ||
!String::cast(name)->Equals(String::cast(key))) {

View File

@ -147,7 +147,8 @@ Handle<Code> StubCache::ComputeLoadField(Handle<String> name,
PropertyIndex field) {
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*receiver, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
Handle<JSObject> map_holder(
IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::FIELD);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
isolate_);
@ -170,7 +171,8 @@ Handle<Code> StubCache::ComputeLoadCallback(
ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*receiver, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
Handle<JSObject> map_holder(
IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CALLBACKS);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@ -193,7 +195,8 @@ Handle<Code> StubCache::ComputeLoadViaGetter(Handle<String> name,
Handle<JSFunction> getter) {
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*receiver, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
Handle<JSObject> map_holder(
IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CALLBACKS);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@ -216,7 +219,8 @@ Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name,
Handle<JSFunction> value) {
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*receiver, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
Handle<JSObject> map_holder(
IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CONSTANT_FUNCTION);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@ -238,7 +242,8 @@ Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name,
Handle<JSObject> holder) {
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*receiver, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
Handle<JSObject> map_holder(
IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::INTERCEPTOR);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@ -267,7 +272,8 @@ Handle<Code> StubCache::ComputeLoadGlobal(Handle<String> name,
bool is_dont_delete) {
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*receiver, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
Handle<JSObject> map_holder(
IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::NORMAL);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@ -290,7 +296,8 @@ Handle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name,
PropertyIndex field) {
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*receiver, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
Handle<JSObject> map_holder(
IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::FIELD);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@ -312,7 +319,8 @@ Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name,
Handle<JSFunction> value) {
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*receiver, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
Handle<JSObject> map_holder(
IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC,
Code::CONSTANT_FUNCTION);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@ -334,7 +342,8 @@ Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name,
Handle<JSObject> holder) {
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*receiver, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
Handle<JSObject> map_holder(
IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::INTERCEPTOR);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@ -357,7 +366,8 @@ Handle<Code> StubCache::ComputeKeyedLoadCallback(
Handle<ExecutableAccessorInfo> callback) {
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*receiver, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
Handle<JSObject> map_holder(
IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
@ -568,7 +578,8 @@ Handle<Code> StubCache::ComputeCallConstant(int argc,
// Compute the check type and the map.
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*object, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder));
Handle<JSObject> map_holder(
IC::GetCodeCacheHolder(isolate_, *object, cache_holder));
// Compute check type based on receiver/holder.
CheckType check = RECEIVER_MAP_CHECK;
@ -618,7 +629,8 @@ Handle<Code> StubCache::ComputeCallField(int argc,
// Compute the check type and the map.
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*object, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder));
Handle<JSObject> map_holder(
IC::GetCodeCacheHolder(isolate_, *object, cache_holder));
// TODO(1233596): We cannot do receiver map check for non-JS objects
// because they may be represented as immediates without a
@ -656,7 +668,8 @@ Handle<Code> StubCache::ComputeCallInterceptor(int argc,
// Compute the check type and the map.
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*object, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder));
Handle<JSObject> map_holder(
IC::GetCodeCacheHolder(isolate_, *object, cache_holder));
// TODO(1233596): We cannot do receiver map check for non-JS objects
// because they may be represented as immediates without a
@ -695,7 +708,8 @@ Handle<Code> StubCache::ComputeCallGlobal(int argc,
Handle<JSFunction> function) {
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*receiver, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
Handle<JSObject> map_holder(
IC::GetCodeCacheHolder(isolate_, *receiver, cache_holder));
Code::Flags flags =
Code::ComputeMonomorphicFlags(kind, Code::NORMAL, extra_state,
cache_holder, argc);

View File

@ -1827,8 +1827,9 @@ Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
rax,
&miss);
ASSERT(!object.is_identical_to(holder));
CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
rax, holder, rbx, rdx, rdi, name, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
rax, holder, rbx, rdx, rdi, name, &miss);
Register receiver = rbx;
Register index = rdi;
@ -1905,8 +1906,9 @@ Handle<Code> CallStubCompiler::CompileStringCharAtCall(
rax,
&miss);
ASSERT(!object.is_identical_to(holder));
CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
rax, holder, rbx, rdx, rdi, name, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
rax, holder, rbx, rdx, rdi, name, &miss);
Register receiver = rax;
Register index = rdi;
@ -2245,7 +2247,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
GenerateDirectLoadGlobalFunctionPrototype(
masm(), Context::STRING_FUNCTION_INDEX, rax, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype())),
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
rax, holder, rbx, rdx, rdi, name, &miss);
break;
@ -2260,7 +2262,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
GenerateDirectLoadGlobalFunctionPrototype(
masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype())),
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
rax, holder, rbx, rdx, rdi, name, &miss);
break;
}
@ -2276,7 +2278,7 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
GenerateDirectLoadGlobalFunctionPrototype(
masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype())),
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
rax, holder, rbx, rdx, rdi, name, &miss);
break;
}