Changed structure of accessor arguments passing to allow accessor

callbacks to be called directly from native code.

Review URL: http://codereview.chromium.org/242050


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2995 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent fb038bf1
...@@ -130,6 +130,7 @@ class Data; ...@@ -130,6 +130,7 @@ class Data;
namespace internal { namespace internal {
class Object; class Object;
class Arguments;
} }
...@@ -1408,17 +1409,13 @@ class V8EXPORT Arguments { ...@@ -1408,17 +1409,13 @@ class V8EXPORT Arguments {
*/ */
class V8EXPORT AccessorInfo { class V8EXPORT AccessorInfo {
public: public:
inline AccessorInfo(Local<Object> self, inline AccessorInfo(internal::Object** args)
Local<Value> data, : args_(args) { }
Local<Object> holder)
: self_(self), data_(data), holder_(holder) { }
inline Local<Value> Data() const; inline Local<Value> Data() const;
inline Local<Object> This() const; inline Local<Object> This() const;
inline Local<Object> Holder() const; inline Local<Object> Holder() const;
private: private:
Local<Object> self_; internal::Object** args_;
Local<Value> data_;
Local<Object> holder_;
}; };
...@@ -2873,21 +2870,6 @@ int Arguments::Length() const { ...@@ -2873,21 +2870,6 @@ int Arguments::Length() const {
} }
Local<Value> AccessorInfo::Data() const {
return data_;
}
Local<Object> AccessorInfo::This() const {
return self_;
}
Local<Object> AccessorInfo::Holder() const {
return holder_;
}
template <class T> template <class T>
Local<T> HandleScope::Close(Handle<T> value) { Local<T> HandleScope::Close(Handle<T> value) {
internal::Object** before = reinterpret_cast<internal::Object**>(*value); internal::Object** before = reinterpret_cast<internal::Object**>(*value);
...@@ -3085,6 +3067,21 @@ External* External::Cast(v8::Value* value) { ...@@ -3085,6 +3067,21 @@ External* External::Cast(v8::Value* value) {
} }
Local<Value> AccessorInfo::Data() const {
return Local<Value>(reinterpret_cast<Value*>(&args_[-3]));
}
Local<Object> AccessorInfo::This() const {
return Local<Object>(reinterpret_cast<Object*>(&args_[0]));
}
Local<Object> AccessorInfo::Holder() const {
return Local<Object>(reinterpret_cast<Object*>(&args_[-1]));
}
/** /**
* \example shell.cc * \example shell.cc
* A simple shell that takes a list of expressions on the * A simple shell that takes a list of expressions on the
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "v8.h" #include "v8.h"
#include "api.h" #include "api.h"
#include "arguments.h"
#include "bootstrapper.h" #include "bootstrapper.h"
#include "compiler.h" #include "compiler.h"
#include "debug.h" #include "debug.h"
......
...@@ -45,6 +45,9 @@ namespace internal { ...@@ -45,6 +45,9 @@ namespace internal {
class Arguments BASE_EMBEDDED { class Arguments BASE_EMBEDDED {
public: public:
Arguments(int length, Object** arguments)
: length_(length), arguments_(arguments) { }
Object*& operator[] (int index) { Object*& operator[] (int index) {
ASSERT(0 <= index && index < length_); ASSERT(0 <= index && index < length_);
return arguments_[-index]; return arguments_[-index];
...@@ -61,11 +64,34 @@ class Arguments BASE_EMBEDDED { ...@@ -61,11 +64,34 @@ class Arguments BASE_EMBEDDED {
// Get the total number of arguments including the receiver. // Get the total number of arguments including the receiver.
int length() const { return length_; } int length() const { return length_; }
Object** arguments() { return arguments_; }
private: private:
int length_; int length_;
Object** arguments_; Object** arguments_;
}; };
// Cursom 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 {
public:
inline CustomArguments(Object *data,
JSObject *self,
JSObject *holder) {
values_[3] = self;
values_[2] = holder;
values_[1] = Smi::FromInt(0);
values_[0] = data;
}
void IterateInstance(ObjectVisitor* v);
Object** end() { return values_ + 3; }
private:
Object* values_[4];
};
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_ARGUMENTS_H_ #endif // V8_ARGUMENTS_H_
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "accessors.h" #include "accessors.h"
#include "api.h" #include "api.h"
#include "arguments.h"
#include "bootstrapper.h" #include "bootstrapper.h"
#include "compiler.h" #include "compiler.h"
#include "debug.h" #include "debug.h"
...@@ -479,15 +480,17 @@ int GetScriptLineNumber(Handle<Script> script, int code_pos) { ...@@ -479,15 +480,17 @@ int GetScriptLineNumber(Handle<Script> script, int code_pos) {
} }
void CustomArguments::IterateInstance(ObjectVisitor* v) {
v->VisitPointers(values_, values_ + 4);
}
// Compute the property keys from the interceptor. // Compute the property keys from the interceptor.
v8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSObject> receiver, v8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSObject> receiver,
Handle<JSObject> object) { Handle<JSObject> object) {
Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
Handle<Object> data(interceptor->data()); CustomArguments args(interceptor->data(), *receiver, *object);
v8::AccessorInfo info( v8::AccessorInfo info(args.end());
v8::Utils::ToLocal(receiver),
v8::Utils::ToLocal(data),
v8::Utils::ToLocal(object));
v8::Handle<v8::Array> result; v8::Handle<v8::Array> result;
if (!interceptor->enumerator()->IsUndefined()) { if (!interceptor->enumerator()->IsUndefined()) {
v8::NamedPropertyEnumerator enum_fun = v8::NamedPropertyEnumerator enum_fun =
...@@ -507,11 +510,8 @@ v8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSObject> receiver, ...@@ -507,11 +510,8 @@ v8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSObject> receiver,
v8::Handle<v8::Array> GetKeysForIndexedInterceptor(Handle<JSObject> receiver, v8::Handle<v8::Array> GetKeysForIndexedInterceptor(Handle<JSObject> receiver,
Handle<JSObject> object) { Handle<JSObject> object) {
Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
Handle<Object> data(interceptor->data()); CustomArguments args(interceptor->data(), *receiver, *object);
v8::AccessorInfo info( v8::AccessorInfo info(args.end());
v8::Utils::ToLocal(receiver),
v8::Utils::ToLocal(data),
v8::Utils::ToLocal(object));
v8::Handle<v8::Array> result; v8::Handle<v8::Array> result;
if (!interceptor->enumerator()->IsUndefined()) { if (!interceptor->enumerator()->IsUndefined()) {
v8::IndexedPropertyEnumerator enum_fun = v8::IndexedPropertyEnumerator enum_fun =
......
...@@ -497,8 +497,8 @@ void Heap::PostGarbageCollectionProcessing() { ...@@ -497,8 +497,8 @@ void Heap::PostGarbageCollectionProcessing() {
DisableAssertNoAllocation allow_allocation; DisableAssertNoAllocation allow_allocation;
GlobalHandles::PostGarbageCollectionProcessing(); GlobalHandles::PostGarbageCollectionProcessing();
} }
// Update flat string readers. // Update relocatables.
FlatStringReader::PostGarbageCollectionProcessing(); Relocatable::PostGarbageCollectionProcessing();
} }
...@@ -3088,6 +3088,8 @@ void Heap::IterateStrongRoots(ObjectVisitor* v) { ...@@ -3088,6 +3088,8 @@ void Heap::IterateStrongRoots(ObjectVisitor* v) {
SYNCHRONIZE_TAG("bootstrapper"); SYNCHRONIZE_TAG("bootstrapper");
Top::Iterate(v); Top::Iterate(v);
SYNCHRONIZE_TAG("top"); SYNCHRONIZE_TAG("top");
Relocatable::Iterate(v);
SYNCHRONIZE_TAG("relocatable");
#ifdef ENABLE_DEBUGGER_SUPPORT #ifdef ENABLE_DEBUGGER_SUPPORT
Debug::Iterate(v); Debug::Iterate(v);
......
This diff is collapsed.
...@@ -4219,25 +4219,44 @@ class ExternalTwoByteString: public ExternalString { ...@@ -4219,25 +4219,44 @@ class ExternalTwoByteString: public ExternalString {
}; };
// Utility superclass for stack-allocated objects that must be updated
// on gc. It provides two ways for the gc to update instances, either
// iterating or updating after gc.
class Relocatable BASE_EMBEDDED {
public:
inline Relocatable() : prev_(top_) { top_ = this; }
virtual ~Relocatable() { ASSERT_EQ(top_, this); top_ = prev_; }
virtual void IterateInstance(ObjectVisitor* v) { }
virtual void PostGarbageCollection() { }
static void PostGarbageCollectionProcessing();
static int ArchiveSpacePerThread();
static char* ArchiveState(char* to);
static char* RestoreState(char* from);
static void Iterate(ObjectVisitor* v);
static void Iterate(ObjectVisitor* v, Relocatable* top);
static char* Iterate(ObjectVisitor* v, char* t);
private:
static Relocatable* top_;
Relocatable* prev_;
};
// A flat string reader provides random access to the contents of a // A flat string reader provides random access to the contents of a
// string independent of the character width of the string. The handle // string independent of the character width of the string. The handle
// must be valid as long as the reader is being used. // must be valid as long as the reader is being used.
class FlatStringReader BASE_EMBEDDED { class FlatStringReader : public Relocatable {
public: public:
explicit FlatStringReader(Handle<String> str); explicit FlatStringReader(Handle<String> str);
explicit FlatStringReader(Vector<const char> input); explicit FlatStringReader(Vector<const char> input);
~FlatStringReader(); void PostGarbageCollection();
void RefreshState();
inline uc32 Get(int index); inline uc32 Get(int index);
int length() { return length_; } int length() { return length_; }
static void PostGarbageCollectionProcessing();
private: private:
String** str_; String** str_;
bool is_ascii_; bool is_ascii_;
int length_; int length_;
const void* start_; const void* start_;
FlatStringReader* prev_;
static FlatStringReader* top_;
}; };
......
...@@ -735,28 +735,17 @@ Handle<Code> ComputeCallMiss(int argc) { ...@@ -735,28 +735,17 @@ Handle<Code> ComputeCallMiss(int argc) {
Object* LoadCallbackProperty(Arguments args) { Object* LoadCallbackProperty(Arguments args) {
Handle<JSObject> recv = args.at<JSObject>(0);
Handle<JSObject> holder = args.at<JSObject>(1);
AccessorInfo* callback = AccessorInfo::cast(args[2]); AccessorInfo* callback = AccessorInfo::cast(args[2]);
Handle<Object> data = args.at<Object>(3);
Address getter_address = v8::ToCData<Address>(callback->getter()); Address getter_address = v8::ToCData<Address>(callback->getter());
v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address); v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address);
ASSERT(fun != NULL); ASSERT(fun != NULL);
Handle<String> name = args.at<String>(4); v8::AccessorInfo info(args.arguments());
// NOTE: If we can align the structure of an AccessorInfo with the
// locations of the arguments to this function maybe we don't have
// to explicitly create the structure but can just pass a pointer
// into the stack.
LOG(ApiNamedPropertyAccess("load", *recv, *name));
v8::AccessorInfo info(v8::Utils::ToLocal(recv),
v8::Utils::ToLocal(data),
v8::Utils::ToLocal(holder));
HandleScope scope; HandleScope scope;
v8::Handle<v8::Value> result; v8::Handle<v8::Value> result;
{ {
// Leaving JavaScript. // Leaving JavaScript.
VMState state(EXTERNAL); VMState state(EXTERNAL);
result = fun(v8::Utils::ToLocal(name), info); result = fun(v8::Utils::ToLocal(args.at<String>(4)), info);
} }
RETURN_IF_SCHEDULED_EXCEPTION(); RETURN_IF_SCHEDULED_EXCEPTION();
if (result.IsEmpty()) return Heap::undefined_value(); if (result.IsEmpty()) return Heap::undefined_value();
...@@ -765,7 +754,7 @@ Object* LoadCallbackProperty(Arguments args) { ...@@ -765,7 +754,7 @@ Object* LoadCallbackProperty(Arguments args) {
Object* StoreCallbackProperty(Arguments args) { Object* StoreCallbackProperty(Arguments args) {
Handle<JSObject> recv = args.at<JSObject>(0); JSObject* recv = JSObject::cast(args[0]);
AccessorInfo* callback = AccessorInfo::cast(args[1]); AccessorInfo* callback = AccessorInfo::cast(args[1]);
Address setter_address = v8::ToCData<Address>(callback->setter()); Address setter_address = v8::ToCData<Address>(callback->setter());
v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address); v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address);
...@@ -773,11 +762,9 @@ Object* StoreCallbackProperty(Arguments args) { ...@@ -773,11 +762,9 @@ Object* StoreCallbackProperty(Arguments args) {
Handle<String> name = args.at<String>(2); Handle<String> name = args.at<String>(2);
Handle<Object> value = args.at<Object>(3); Handle<Object> value = args.at<Object>(3);
HandleScope scope; HandleScope scope;
Handle<Object> data(callback->data()); LOG(ApiNamedPropertyAccess("store", recv, *name));
LOG(ApiNamedPropertyAccess("store", *recv, *name)); CustomArguments custom_args(callback->data(), recv, recv);
v8::AccessorInfo info(v8::Utils::ToLocal(recv), v8::AccessorInfo info(custom_args.end());
v8::Utils::ToLocal(data),
v8::Utils::ToLocal(recv));
{ {
// Leaving JavaScript. // Leaving JavaScript.
VMState state(EXTERNAL); VMState state(EXTERNAL);
...@@ -795,11 +782,11 @@ Object* StoreCallbackProperty(Arguments args) { ...@@ -795,11 +782,11 @@ Object* StoreCallbackProperty(Arguments args) {
* provide any value for the given name. * provide any value for the given name.
*/ */
Object* LoadPropertyWithInterceptorOnly(Arguments args) { Object* LoadPropertyWithInterceptorOnly(Arguments args) {
Handle<JSObject> receiver_handle = args.at<JSObject>(0); JSObject* receiver_handle = JSObject::cast(args[0]);
Handle<JSObject> holder_handle = args.at<JSObject>(1); JSObject* holder_handle = JSObject::cast(args[1]);
Handle<String> name_handle = args.at<String>(2); Handle<String> name_handle = args.at<String>(2);
Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(3); Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(3);
Handle<Object> data_handle = args.at<Object>(4); Object* data_handle = args[4];
Address getter_address = v8::ToCData<Address>(interceptor_info->getter()); Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
v8::NamedPropertyGetter getter = v8::NamedPropertyGetter getter =
...@@ -808,9 +795,8 @@ Object* LoadPropertyWithInterceptorOnly(Arguments args) { ...@@ -808,9 +795,8 @@ Object* LoadPropertyWithInterceptorOnly(Arguments args) {
{ {
// Use the interceptor getter. // Use the interceptor getter.
v8::AccessorInfo info(v8::Utils::ToLocal(receiver_handle), CustomArguments args(data_handle, receiver_handle, holder_handle);
v8::Utils::ToLocal(data_handle), v8::AccessorInfo info(args.end());
v8::Utils::ToLocal(holder_handle));
HandleScope scope; HandleScope scope;
v8::Handle<v8::Value> r; v8::Handle<v8::Value> r;
{ {
...@@ -861,9 +847,8 @@ static Object* LoadWithInterceptor(Arguments* args, ...@@ -861,9 +847,8 @@ static Object* LoadWithInterceptor(Arguments* args,
{ {
// Use the interceptor getter. // Use the interceptor getter.
v8::AccessorInfo info(v8::Utils::ToLocal(receiver_handle), CustomArguments args(*data_handle, *receiver_handle, *holder_handle);
v8::Utils::ToLocal(data_handle), v8::AccessorInfo info(args.end());
v8::Utils::ToLocal(holder_handle));
HandleScope scope; HandleScope scope;
v8::Handle<v8::Value> r; v8::Handle<v8::Value> r;
{ {
......
...@@ -146,6 +146,7 @@ bool ThreadManager::RestoreThread() { ...@@ -146,6 +146,7 @@ bool ThreadManager::RestoreThread() {
char* from = state->data(); char* from = state->data();
from = HandleScopeImplementer::RestoreThread(from); from = HandleScopeImplementer::RestoreThread(from);
from = Top::RestoreThread(from); from = Top::RestoreThread(from);
from = Relocatable::RestoreState(from);
#ifdef ENABLE_DEBUGGER_SUPPORT #ifdef ENABLE_DEBUGGER_SUPPORT
from = Debug::RestoreDebug(from); from = Debug::RestoreDebug(from);
#endif #endif
...@@ -185,7 +186,8 @@ static int ArchiveSpacePerThread() { ...@@ -185,7 +186,8 @@ static int ArchiveSpacePerThread() {
#endif #endif
StackGuard::ArchiveSpacePerThread() + StackGuard::ArchiveSpacePerThread() +
RegExpStack::ArchiveSpacePerThread() + RegExpStack::ArchiveSpacePerThread() +
Bootstrapper::ArchiveSpacePerThread(); Bootstrapper::ArchiveSpacePerThread() +
Relocatable::ArchiveSpacePerThread();
} }
...@@ -275,6 +277,7 @@ void ThreadManager::EagerlyArchiveThread() { ...@@ -275,6 +277,7 @@ void ThreadManager::EagerlyArchiveThread() {
// in ThreadManager::Iterate(ObjectVisitor*). // in ThreadManager::Iterate(ObjectVisitor*).
to = HandleScopeImplementer::ArchiveThread(to); to = HandleScopeImplementer::ArchiveThread(to);
to = Top::ArchiveThread(to); to = Top::ArchiveThread(to);
to = Relocatable::ArchiveState(to);
#ifdef ENABLE_DEBUGGER_SUPPORT #ifdef ENABLE_DEBUGGER_SUPPORT
to = Debug::ArchiveDebug(to); to = Debug::ArchiveDebug(to);
#endif #endif
...@@ -311,6 +314,7 @@ void ThreadManager::Iterate(ObjectVisitor* v) { ...@@ -311,6 +314,7 @@ void ThreadManager::Iterate(ObjectVisitor* v) {
char* data = state->data(); char* data = state->data();
data = HandleScopeImplementer::Iterate(v, data); data = HandleScopeImplementer::Iterate(v, data);
data = Top::Iterate(v, data); data = Top::Iterate(v, data);
data = Relocatable::Iterate(v, data);
} }
} }
......
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