Commit 84c09c6d authored by kasperl@chromium.org's avatar kasperl@chromium.org

Experimental revert of revisions 2093, 2094, 2099, and

2106 to try to isolate a performance regression on the
page cyclers.

I'll roll the changes back in if this doesn't fix the
regression.

TBR=antonm@chromium.org
Review URL: http://codereview.chromium.org/118302

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2108 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent be11c4e9
......@@ -246,7 +246,6 @@ void StubCompiler::GenerateLoadCallback(MacroAssembler* masm,
void StubCompiler::GenerateLoadInterceptor(MacroAssembler* masm,
JSObject* object,
JSObject* holder,
Smi* lookup_hint,
Register receiver,
Register name,
Register scratch1,
......@@ -264,13 +263,11 @@ void StubCompiler::GenerateLoadInterceptor(MacroAssembler* masm,
__ push(receiver); // receiver
__ push(reg); // holder
__ push(name); // name
__ mov(scratch1, Operand(lookup_hint));
__ push(scratch1);
// Do tail-call to the runtime system.
ExternalReference load_ic_property =
ExternalReference(IC_Utility(IC::kLoadInterceptorProperty));
__ TailCallRuntime(load_ic_property, 4);
__ TailCallRuntime(load_ic_property, 3);
}
......@@ -912,15 +909,7 @@ Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* object,
__ ldr(r0, MemOperand(sp, 0));
GenerateLoadInterceptor(masm(),
object,
holder,
holder->InterceptorPropertyLookupHint(name),
r0,
r2,
r3,
r1,
&miss);
GenerateLoadInterceptor(masm(), object, holder, r0, r2, r3, r1, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
......@@ -1026,15 +1015,7 @@ Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
__ cmp(r2, Operand(Handle<String>(name)));
__ b(ne, &miss);
GenerateLoadInterceptor(masm(),
receiver,
holder,
Smi::FromInt(JSObject::kLookupInHolder),
r0,
r2,
r3,
r1,
&miss);
GenerateLoadInterceptor(masm(), receiver, holder, r0, r2, r3, r1, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
......
......@@ -322,7 +322,6 @@ void StubCompiler::GenerateLoadConstant(MacroAssembler* masm,
void StubCompiler::GenerateLoadInterceptor(MacroAssembler* masm,
JSObject* object,
JSObject* holder,
Smi* lookup_hint,
Register receiver,
Register name,
Register scratch1,
......@@ -341,15 +340,12 @@ void StubCompiler::GenerateLoadInterceptor(MacroAssembler* masm,
__ push(receiver); // receiver
__ push(reg); // holder
__ push(name); // name
// TODO(367): Maybe don't push lookup_hint for LOOKUP_IN_HOLDER and/or
// LOOKUP_IN_PROTOTYPE, but use a special version of lookup method?
__ push(Immediate(lookup_hint));
__ push(scratch2); // restore return address
// Do tail-call to the runtime system.
ExternalReference load_ic_property =
ExternalReference(IC_Utility(IC::kLoadInterceptorProperty));
__ TailCallRuntime(load_ic_property, 4);
__ TailCallRuntime(load_ic_property, 3);
}
......@@ -674,12 +670,11 @@ Object* CallStubCompiler::CompileCallInterceptor(Object* object,
__ push(edx); // receiver
__ push(reg); // holder
__ push(Operand(ebp, (argc + 3) * kPointerSize)); // name
__ push(Immediate(holder->InterceptorPropertyLookupHint(name)));
// Perform call.
ExternalReference load_interceptor =
ExternalReference(IC_Utility(IC::kLoadInterceptorProperty));
__ mov(eax, Immediate(4));
__ mov(eax, Immediate(3));
__ mov(ebx, Immediate(load_interceptor));
CEntryStub stub;
......@@ -979,18 +974,7 @@ Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
Label miss;
__ mov(eax, (Operand(esp, kPointerSize)));
// TODO(368): Compile in the whole chain: all the interceptors in
// prototypes and ultimate answer.
GenerateLoadInterceptor(masm(),
receiver,
holder,
holder->InterceptorPropertyLookupHint(name),
eax,
ecx,
edx,
ebx,
&miss);
GenerateLoadInterceptor(masm(), receiver, holder, eax, ecx, edx, ebx, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
......@@ -1105,15 +1089,7 @@ Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
__ j(not_equal, &miss, not_taken);
GenerateLoadInterceptor(masm(),
receiver,
holder,
Smi::FromInt(JSObject::kLookupInHolder),
ecx,
eax,
edx,
ebx,
&miss);
GenerateLoadInterceptor(masm(), receiver, holder, ecx, eax, edx, ebx, &miss);
__ bind(&miss);
__ DecrementCounter(&Counters::keyed_load_interceptor, 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
......
......@@ -2554,24 +2554,6 @@ bool JSObject::HasElement(uint32_t index) {
}
Smi* JSObject::InterceptorPropertyLookupHint(String* name) {
// TODO(antonm): Do we want to do any shortcuts for global object?
if (HasFastProperties()) {
LookupResult lookup;
LocalLookupRealNamedProperty(name, &lookup);
if (lookup.IsValid()) {
if (lookup.type() == FIELD && lookup.IsCacheable()) {
return Smi::FromInt(lookup.GetFieldIndex());
}
} else {
return Smi::FromInt(kLookupInPrototype);
}
}
return Smi::FromInt(kLookupInHolder);
}
bool AccessorInfo::all_can_read() {
return BooleanBit::get(flag(), kAllCanReadBit);
}
......
......@@ -5617,11 +5617,9 @@ Object* JSObject::GetPropertyPostInterceptor(JSObject* receiver,
}
bool JSObject::GetPropertyWithInterceptorProper(
JSObject* receiver,
String* name,
PropertyAttributes* attributes,
Object** result_object) {
Object* JSObject::GetPropertyWithInterceptor(JSObject* receiver,
String* name,
PropertyAttributes* attributes) {
HandleScope scope;
Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
Handle<JSObject> receiver_handle(receiver);
......@@ -5642,93 +5640,19 @@ bool JSObject::GetPropertyWithInterceptorProper(
VMState state(EXTERNAL);
result = getter(v8::Utils::ToLocal(name_handle), info);
}
if (Top::has_scheduled_exception()) {
return false;
}
RETURN_IF_SCHEDULED_EXCEPTION();
if (!result.IsEmpty()) {
*attributes = NONE;
*result_object = *v8::Utils::OpenHandle(*result);
return true;
}
}
return false;
}
Object* JSObject::GetInterceptorPropertyWithLookupHint(
JSObject* receiver,
Smi* lookup_hint,
String* name,
PropertyAttributes* attributes) {
HandleScope scope;
Handle<JSObject> receiver_handle(receiver);
Handle<JSObject> holder_handle(this);
Handle<String> name_handle(name);
Object* result = NULL;
if (GetPropertyWithInterceptorProper(receiver, name, attributes, &result)) {
return result;
} else {
RETURN_IF_SCHEDULED_EXCEPTION();
}
int property_index = lookup_hint->value();
if (property_index >= 0) {
result = holder_handle->FastPropertyAt(property_index);
} else {
switch (property_index) {
case kLookupInPrototype: {
Object* pt = holder_handle->GetPrototype();
*attributes = ABSENT;
if (pt == Heap::null_value()) return Heap::undefined_value();
result = pt->GetPropertyWithReceiver(
*receiver_handle,
*name_handle,
attributes);
RETURN_IF_SCHEDULED_EXCEPTION();
}
break;
case kLookupInHolder:
result = holder_handle->GetPropertyPostInterceptor(
*receiver_handle,
*name_handle,
attributes);
RETURN_IF_SCHEDULED_EXCEPTION();
break;
default:
UNREACHABLE();
return *v8::Utils::OpenHandle(*result);
}
}
return result;
}
Object* JSObject::GetPropertyWithInterceptor(
JSObject* receiver,
String* name,
PropertyAttributes* attributes) {
HandleScope scope;
Handle<JSObject> receiver_handle(receiver);
Handle<JSObject> holder_handle(this);
Handle<String> name_handle(name);
Object* result = NULL;
if (GetPropertyWithInterceptorProper(receiver, name, attributes, &result)) {
return result;
} else {
RETURN_IF_SCHEDULED_EXCEPTION();
}
result = holder_handle->GetPropertyPostInterceptor(
Object* raw_result = holder_handle->GetPropertyPostInterceptor(
*receiver_handle,
*name_handle,
attributes);
RETURN_IF_SCHEDULED_EXCEPTION();
return result;
return raw_result;
}
......
......@@ -1349,14 +1349,6 @@ class JSObject: public HeapObject {
Object* LookupCallbackSetterInPrototypes(uint32_t index);
void LookupCallback(String* name, LookupResult* result);
inline Smi* InterceptorPropertyLookupHint(String* name);
Object* GetInterceptorPropertyWithLookupHint(JSObject* receiver,
Smi* lookup_hint,
String* name,
PropertyAttributes* attributes);
static const int kLookupInHolder = -1;
static const int kLookupInPrototype = -2;
// Returns the number of properties on this object filtering out properties
// with the specified attributes (ignoring interceptors).
int NumberOfLocalProperties(PropertyAttributes filter);
......@@ -1548,14 +1540,6 @@ class JSObject: public HeapObject {
void LookupInDescriptor(String* name, LookupResult* result);
// Attempts to get property with a named interceptor getter. Returns
// |true| and stores result into |result| if succesful, otherwise
// returns |false|
bool GetPropertyWithInterceptorProper(JSObject* receiver,
String* name,
PropertyAttributes* attributes,
Object** result);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
};
......
......@@ -719,12 +719,10 @@ Object* LoadInterceptorProperty(Arguments args) {
JSObject* recv = JSObject::cast(args[0]);
JSObject* holder = JSObject::cast(args[1]);
String* name = String::cast(args[2]);
Smi* lookup_hint = Smi::cast(args[3]);
ASSERT(holder->HasNamedInterceptor());
PropertyAttributes attr = NONE;
Object* result = holder->GetPropertyWithInterceptor(recv, name, &attr);
Object* result = holder->GetInterceptorPropertyWithLookupHint(
recv, lookup_hint, name, &attr);
if (result->IsFailure()) return result;
// If the property is present, return it.
......
......@@ -351,7 +351,6 @@ class StubCompiler BASE_EMBEDDED {
static void GenerateLoadInterceptor(MacroAssembler* masm,
JSObject* object,
JSObject* holder,
Smi* lookup_hint,
Register receiver,
Register name,
Register scratch1,
......
......@@ -4827,23 +4827,6 @@ THREADED_TEST(InterceptorHasOwnPropertyCausingGC) {
}
typedef v8::Handle<Value> (*NamedPropertyGetter)(Local<String> property,
const AccessorInfo& info);
static void CheckInterceptorLoadIC(NamedPropertyGetter getter,
const char* source,
int expected) {
v8::HandleScope scope;
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
templ->SetNamedPropertyHandler(getter);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
v8::Handle<Value> value = CompileRun(source);
CHECK_EQ(expected, value->Int32Value());
}
static v8::Handle<Value> InterceptorLoadICGetter(Local<String> name,
const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
......@@ -4854,100 +4837,17 @@ static v8::Handle<Value> InterceptorLoadICGetter(Local<String> name,
// This test should hit the load IC for the interceptor case.
THREADED_TEST(InterceptorLoadIC) {
CheckInterceptorLoadIC(InterceptorLoadICGetter,
v8::HandleScope scope;
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
templ->SetNamedPropertyHandler(InterceptorLoadICGetter);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
v8::Handle<Value> value = CompileRun(
"var result = 0;"
"for (var i = 0; i < 1000; i++) {"
" result = o.x;"
"}",
42);
}
// Below go several tests which verify that JITing for various
// configurations of interceptor and explicit fields works fine
// (those cases are special cased to get better performance).
static v8::Handle<Value> InterceptorLoadXICGetter(Local<String> name,
const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
return v8_str("x")->Equals(name)
? v8::Integer::New(42) : v8::Handle<v8::Value>();
}
THREADED_TEST(InterceptorLoadICWithFieldOnHolder) {
CheckInterceptorLoadIC(InterceptorLoadXICGetter,
"var result = 0;"
"o.y = 239;"
"for (var i = 0; i < 1000; i++) {"
" result = o.y;"
"}",
239);
}
THREADED_TEST(InterceptorLoadICWithSubstitutedProto) {
CheckInterceptorLoadIC(InterceptorLoadXICGetter,
"var result = 0;"
"o.__proto__ = { 'y': 239 };"
"for (var i = 0; i < 1000; i++) {"
" result = o.y + o.x;"
"}",
239 + 42);
}
THREADED_TEST(InterceptorLoadICWithPropertyOnProto) {
CheckInterceptorLoadIC(InterceptorLoadXICGetter,
"var result = 0;"
"o.__proto__.y = 239;"
"for (var i = 0; i < 1000; i++) {"
" result = o.y + o.x;"
"}",
239 + 42);
}
THREADED_TEST(InterceptorLoadICUndefined) {
CheckInterceptorLoadIC(InterceptorLoadXICGetter,
"var result = 0;"
"for (var i = 0; i < 1000; i++) {"
" result = (o.y == undefined) ? 239 : 42;"
"}",
239);
}
THREADED_TEST(InterceptorLoadICWithOverride) {
CheckInterceptorLoadIC(InterceptorLoadXICGetter,
"fst = new Object(); fst.__proto__ = o;"
"snd = new Object(); snd.__proto__ = fst;"
"var result1 = 0;"
"for (var i = 0; i < 1000; i++) {"
" result1 = snd.x;"
"}"
"fst.x = 239;"
"var result = 0;"
"for (var i = 0; i < 1000; i++) {"
" result = snd.x;"
"}"
"result + result1",
239 + 42);
}
static v8::Handle<Value> InterceptorLoadICGetter0(Local<String> name,
const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
CHECK(v8_str("x")->Equals(name));
return v8::Integer::New(0);
}
THREADED_TEST(InterceptorReturningZero) {
CheckInterceptorLoadIC(InterceptorLoadICGetter0,
"o.x == undefined ? 1 : 0",
0);
"}");
CHECK_EQ(42, value->Int32Value());
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment