Commit 2e49a1c0 authored by antonm@chromium.org's avatar antonm@chromium.org

Follow up to r2093: forgotten files and changes.



git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2094 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 06fdc015
......@@ -327,6 +327,26 @@ void StubCompiler::GenerateLoadInterceptor(MacroAssembler* masm,
Register scratch1,
Register scratch2,
Label* miss_label) {
GenerateLoadInterceptor(masm,
object,
holder,
Smi::FromInt(JSObject::kLookupInHolder),
receiver,
name,
scratch1,
scratch2,
miss_label);
}
void StubCompiler::GenerateLoadInterceptor(MacroAssembler* masm,
JSObject* object,
JSObject* holder,
Smi* lookup_hint,
Register receiver,
Register name,
Register scratch1,
Register scratch2,
Label* miss_label) {
// Check that the receiver isn't a smi.
__ test(receiver, Immediate(kSmiTagMask));
__ j(zero, miss_label, not_taken);
......@@ -340,12 +360,15 @@ 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, 3);
__ TailCallRuntime(load_ic_property, 4);
}
......@@ -670,11 +693,12 @@ 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(3));
__ mov(eax, Immediate(4));
__ mov(ebx, Immediate(load_interceptor));
CEntryStub stub;
......@@ -974,7 +998,18 @@ Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
Label miss;
__ mov(eax, (Operand(esp, kPointerSize)));
GenerateLoadInterceptor(masm(), receiver, holder, eax, ecx, edx, ebx, &miss);
// 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);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
......
......@@ -1349,6 +1349,14 @@ 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);
......@@ -1540,6 +1548,10 @@ class JSObject: public HeapObject {
void LookupInDescriptor(String* name, LookupResult* result);
Object* GetPropertyWithInterceptorProper(JSObject* receiver,
String* name,
PropertyAttributes* attributes);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
};
......
......@@ -356,6 +356,16 @@ class StubCompiler BASE_EMBEDDED {
Register scratch1,
Register scratch2,
Label* miss_label);
// TODO(antonm): Remove a function above.
static void GenerateLoadInterceptor(MacroAssembler* masm,
JSObject* object,
JSObject* holder,
Smi* lookup_hint,
Register receiver,
Register name,
Register scratch1,
Register scratch2,
Label* miss_label);
static void GenerateLoadArrayLength(MacroAssembler* masm,
Register receiver,
Register scratch,
......
......@@ -4844,6 +4844,90 @@ THREADED_TEST(InterceptorLoadIC) {
}
// 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>();
}
static void CheckInterceptorLoadIC(const char* source, int expected) {
v8::HandleScope scope;
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
templ->SetNamedPropertyHandler(InterceptorLoadXICGetter);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
v8::Handle<Value> value = CompileRun(source);
CHECK_EQ(expected, value->Int32Value());
}
THREADED_TEST(InterceptorLoadICWithFieldOnHolder) {
CheckInterceptorLoadIC(
"var result = 0;"
"o.y = 239;"
"for (var i = 0; i < 1000; i++) {"
" result = o.y;"
"}",
239);
}
THREADED_TEST(InterceptorLoadICWithSubstitutedProto) {
CheckInterceptorLoadIC(
"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(
"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(
"var result = 0;"
"for (var i = 0; i < 1000; i++) {"
" result = (o.y == undefined) ? 239 : 42;"
"}",
239);
}
THREADED_TEST(InterceptorLoadICWithOverride) {
CheckInterceptorLoadIC(
"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> InterceptorStoreICSetter(
Local<String> key, Local<Value> value, const AccessorInfo&) {
CHECK(v8_str("x")->Equals(key));
......
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