Revision: 4288
Author: [email protected]
Date: Thu Mar 25 10:08:22 2010
Log: Simplify passing of AccessorInfo to interceptors:
* Use slots on the native stack when possible instead of Relocatable.
* Got rid of a gap in AccessorInfo fields.
* Added test for non-cacheable post-interceptor lookup.
Review URL: http://codereview.chromium.org/1327002
http://code.google.com/p/v8/source/detail?r=4288
Modified:
/branches/bleeding_edge/include/v8.h
/branches/bleeding_edge/src/arguments.h
/branches/bleeding_edge/src/arm/stub-cache-arm.cc
/branches/bleeding_edge/src/codegen.h
/branches/bleeding_edge/src/handles.cc
/branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
/branches/bleeding_edge/src/stub-cache.cc
/branches/bleeding_edge/src/x64/stub-cache-x64.cc
/branches/bleeding_edge/test/cctest/test-api.cc
=======================================
--- /branches/bleeding_edge/include/v8.h Wed Mar 24 06:24:46 2010
+++ /branches/bleeding_edge/include/v8.h Thu Mar 25 10:08:22 2010
@@ -3361,7 +3361,7 @@
Local<Value> AccessorInfo::Data() const {
- return Local<Value>(reinterpret_cast<Value*>(&args_[-3]));
+ return Local<Value>(reinterpret_cast<Value*>(&args_[-2]));
}
=======================================
--- /branches/bleeding_edge/src/arguments.h Thu Nov 12 05:55:21 2009
+++ /branches/bleeding_edge/src/arguments.h Thu Mar 25 10:08:22 2010
@@ -72,7 +72,7 @@
};
-// Cursom arguments replicate a small segment of stack that can be
+// Custom arguments replicate a small segment of stack that can be
// accessed through an Arguments object the same way the actual stack
// can.
class CustomArguments : public Relocatable {
@@ -80,15 +80,14 @@
inline CustomArguments(Object* data,
JSObject* self,
JSObject* holder) {
- values_[3] = self;
- values_[2] = holder;
- values_[1] = Smi::FromInt(0);
+ values_[2] = self;
+ values_[1] = holder;
values_[0] = data;
}
void IterateInstance(ObjectVisitor* v);
- Object** end() { return values_ + 3; }
+ Object** end() { return values_ + ARRAY_SIZE(values_) - 1; }
private:
- Object* values_[4];
+ Object* values_[3];
};
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Tue Mar 23 07:33:42
2010
+++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Thu Mar 25 10:08:22
2010
@@ -396,15 +396,14 @@
Register holder,
Register name,
JSObject* holder_obj) {
- __ push(receiver);
- __ push(holder);
__ push(name);
InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
ASSERT(!Heap::InNewSpace(interceptor));
-
- Register scratch = receiver;
+ Register scratch = name;
__ mov(scratch, Operand(Handle<Object>(interceptor)));
__ push(scratch);
+ __ push(receiver);
+ __ push(holder);
__ ldr(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset));
__ push(scratch);
}
=======================================
--- /branches/bleeding_edge/src/codegen.h Thu Mar 25 05:44:15 2010
+++ /branches/bleeding_edge/src/codegen.h Thu Mar 25 10:08:22 2010
@@ -450,7 +450,7 @@
virtual bool GetCustomCache(Code** code_out);
virtual void SetCustomCache(Code* value);
- static const int kStackSpace = 6;
+ static const int kStackSpace = 5;
static const int kArgc = 4;
private:
Handle<AccessorInfo> info() { return info_; }
=======================================
--- /branches/bleeding_edge/src/handles.cc Tue Mar 23 04:40:38 2010
+++ /branches/bleeding_edge/src/handles.cc Thu Mar 25 10:08:22 2010
@@ -541,7 +541,7 @@
void CustomArguments::IterateInstance(ObjectVisitor* v) {
- v->VisitPointers(values_, values_ + 4);
+ v->VisitPointers(values_, values_ + ARRAY_SIZE(values_));
}
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Thu Mar 25 07:20:56
2010
+++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Thu Mar 25 10:08:22
2010
@@ -276,14 +276,15 @@
Register holder,
Register name,
JSObject* holder_obj) {
- __ push(receiver);
- __ push(holder);
__ push(name);
InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
ASSERT(!Heap::InNewSpace(interceptor));
- __ mov(receiver, Immediate(Handle<Object>(interceptor)));
+ Register scratch = name;
+ __ mov(scratch, Immediate(Handle<Object>(interceptor)));
+ __ push(scratch);
__ push(receiver);
- __ push(FieldOperand(receiver, InterceptorInfo::kDataOffset));
+ __ push(holder);
+ __ push(FieldOperand(scratch, InterceptorInfo::kDataOffset));
}
@@ -1045,17 +1046,16 @@
__ push(receiver); // receiver
__ push(reg); // holder
__ mov(other, Immediate(callback_handle));
- __ push(other);
__ push(FieldOperand(other, AccessorInfo::kDataOffset)); // data
__ push(name_reg); // name
// Save a pointer to where we pushed the arguments pointer.
- // This will be passed as the const Arguments& to the C++ callback.
+ // This will be passed as the const AccessorInfo& to the C++ callback.
__ mov(eax, esp);
- __ add(Operand(eax), Immediate(5 * kPointerSize));
+ __ add(Operand(eax), Immediate(4 * kPointerSize));
__ mov(ebx, esp);
// Do call through the api.
- ASSERT_EQ(6, ApiGetterEntryStub::kStackSpace);
+ ASSERT_EQ(5, ApiGetterEntryStub::kStackSpace);
Address getter_address = v8::ToCData<Address>(callback->getter());
ApiFunction fun(getter_address);
ApiGetterEntryStub stub(callback_handle, &fun);
=======================================
--- /branches/bleeding_edge/src/stub-cache.cc Thu Mar 11 05:13:21 2010
+++ /branches/bleeding_edge/src/stub-cache.cc Thu Mar 25 10:08:22 2010
@@ -781,6 +781,10 @@
RETURN_IF_SCHEDULED_EXCEPTION();
return *value;
}
+
+
+static const int kAccessorInfoOffsetInInterceptorArgs = 2;
+
/**
* Attempts to load a property with an interceptor (which must be present),
@@ -790,11 +794,12 @@
* provide any value for the given name.
*/
Object* LoadPropertyWithInterceptorOnly(Arguments args) {
- JSObject* receiver_handle = JSObject::cast(args[0]);
- JSObject* holder_handle = JSObject::cast(args[1]);
- Handle<String> name_handle = args.at<String>(2);
- Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(3);
- Object* data_handle = args[4];
+ Handle<String> name_handle = args.at<String>(0);
+ Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(1);
+ ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2);
+ ASSERT(args[2]->IsJSObject()); // Receiver.
+ ASSERT(args[3]->IsJSObject()); // Holder.
+ ASSERT(args.length() == 5); // Last arg is data object.
Address getter_address =
v8::ToCData<Address>(interceptor_info->getter());
v8::NamedPropertyGetter getter =
@@ -803,8 +808,8 @@
{
// Use the interceptor getter.
- CustomArguments args(data_handle, receiver_handle, holder_handle);
- v8::AccessorInfo info(args.end());
+ v8::AccessorInfo info(args.arguments() -
+ kAccessorInfoOffsetInInterceptorArgs);
HandleScope scope;
v8::Handle<v8::Value> r;
{
@@ -842,11 +847,12 @@
static Object* LoadWithInterceptor(Arguments* args,
PropertyAttributes* attrs) {
- Handle<JSObject> receiver_handle = args->at<JSObject>(0);
- Handle<JSObject> holder_handle = args->at<JSObject>(1);
- Handle<String> name_handle = args->at<String>(2);
- Handle<InterceptorInfo> interceptor_info = args->at<InterceptorInfo>(3);
- Handle<Object> data_handle = args->at<Object>(4);
+ Handle<String> name_handle = args->at<String>(0);
+ Handle<InterceptorInfo> interceptor_info = args->at<InterceptorInfo>(1);
+ ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2);
+ Handle<JSObject> receiver_handle = args->at<JSObject>(2);
+ Handle<JSObject> holder_handle = args->at<JSObject>(3);
+ ASSERT(args->length() == 5); // Last arg is data object.
Address getter_address =
v8::ToCData<Address>(interceptor_info->getter());
v8::NamedPropertyGetter getter =
@@ -855,8 +861,8 @@
{
// Use the interceptor getter.
- CustomArguments args(*data_handle, *receiver_handle, *holder_handle);
- v8::AccessorInfo info(args.end());
+ v8::AccessorInfo info(args->arguments() -
+ kAccessorInfoOffsetInInterceptorArgs);
HandleScope scope;
v8::Handle<v8::Value> r;
{
@@ -891,7 +897,7 @@
// If the property is present, return it.
if (attr != ABSENT) return result;
- return ThrowReferenceError(String::cast(args[2]));
+ return ThrowReferenceError(String::cast(args[0]));
}
=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc Tue Mar 23 07:33:42
2010
+++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc Thu Mar 25 10:08:22
2010
@@ -138,14 +138,13 @@
Register holder,
Register name,
JSObject* holder_obj) {
- __ push(receiver);
- __ push(holder);
__ push(name);
InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
ASSERT(!Heap::InNewSpace(interceptor));
- __ movq(kScratchRegister, Handle<Object>(interceptor),
- RelocInfo::EMBEDDED_OBJECT);
+ __ Move(kScratchRegister, Handle<Object>(interceptor));
__ push(kScratchRegister);
+ __ push(receiver);
+ __ push(holder);
__ push(FieldOperand(kScratchRegister, InterceptorInfo::kDataOffset));
}
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Wed Mar 24 06:24:46 2010
+++ /branches/bleeding_edge/test/cctest/test-api.cc Thu Mar 25 10:08:22 2010
@@ -5972,6 +5972,38 @@
"result;",
42 * 1000);
}
+
+
+static int interceptor_load_not_handled_calls = 0;
+static v8::Handle<Value> InterceptorLoadNotHandled(Local<String> name,
+ const AccessorInfo&
info) {
+ ++interceptor_load_not_handled_calls;
+ return v8::Handle<v8::Value>();
+}
+
+
+// Test how post-interceptor lookups are done in the non-cacheable
+// case: the interceptor should not be invoked during this lookup.
+THREADED_TEST(InterceptorLoadICPostInterceptor) {
+ interceptor_load_not_handled_calls = 0;
+ CheckInterceptorLoadIC(InterceptorLoadNotHandled,
+ "receiver = new Object();"
+ "receiver.__proto__ = o;"
+ "proto = new Object();"
+ "/* Make proto a slow-case object. */"
+ "for (var i = 0; i < 1000; i++) {"
+ " proto[\"xxxxxxxx\" + i] = [];"
+ "}"
+ "proto.x = 17;"
+ "o.__proto__ = proto;"
+ "var result = 0;"
+ "for (var i = 0; i < 1000; i++) {"
+ " result += receiver.x;"
+ "}"
+ "result;",
+ 17 * 1000);
+ CHECK_EQ(1000, interceptor_load_not_handled_calls);
+}
// Test the case when we stored field into
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
To unsubscribe from this group, send email to v8-dev+unsubscribegooglegroups.com or reply
to this email with the words "REMOVE ME" as the subject.