Refactoring of v8:Arguments similary we did with v8::AccessorInfo (http://codereview.chromium.org/242050). GC-controlled values moved to a separate array.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5746 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
serya@chromium.org 2010-11-01 10:51:44 +00:00
parent 51bc9a1493
commit fbdcbdf748
4 changed files with 80 additions and 67 deletions

View File

@ -1790,18 +1790,19 @@ class Arguments {
inline bool IsConstructCall() const;
inline Local<Value> Data() const;
private:
static const int kDataIndex = 0;
static const int kCalleeIndex = -1;
static const int kHolderIndex = -2;
friend class ImplementationUtilities;
inline Arguments(Local<Value> data,
Local<Object> holder,
Local<Function> callee,
bool is_construct_call,
void** values, int length);
Local<Value> data_;
Local<Object> holder_;
Local<Function> callee_;
bool is_construct_call_;
void** values_;
inline Arguments(internal::Object** implicit_args,
internal::Object** values,
int length,
bool is_construct_call);
internal::Object** implicit_args_;
internal::Object** values_;
int length_;
bool is_construct_call_;
};
@ -3470,14 +3471,13 @@ void Persistent<T>::ClearWeak() {
}
Arguments::Arguments(v8::Local<v8::Value> data,
v8::Local<v8::Object> holder,
v8::Local<v8::Function> callee,
bool is_construct_call,
void** values, int length)
: data_(data), holder_(holder), callee_(callee),
is_construct_call_(is_construct_call),
values_(values), length_(length) { }
Arguments::Arguments(internal::Object** implicit_args,
internal::Object** values, int length,
bool is_construct_call)
: implicit_args_(implicit_args),
values_(values),
length_(length),
is_construct_call_(is_construct_call) { }
Local<Value> Arguments::operator[](int i) const {
@ -3487,7 +3487,8 @@ Local<Value> Arguments::operator[](int i) const {
Local<Function> Arguments::Callee() const {
return callee_;
return Local<Function>(reinterpret_cast<Function*>(
&implicit_args_[kCalleeIndex]));
}
@ -3497,12 +3498,13 @@ Local<Object> Arguments::This() const {
Local<Object> Arguments::Holder() const {
return holder_;
return Local<Object>(reinterpret_cast<Object*>(
&implicit_args_[kHolderIndex]));
}
Local<Value> Arguments::Data() const {
return data_;
return Local<Value>(reinterpret_cast<Value*>(&implicit_args_[kDataIndex]));
}

View File

@ -29,7 +29,6 @@
#define V8_APIUTILS_H_
namespace v8 {
class ImplementationUtilities {
public:
static v8::Handle<v8::Primitive> Undefined();
@ -45,12 +44,21 @@ class ImplementationUtilities {
return that->names_;
}
static v8::Arguments NewArguments(Local<Value> data,
Local<Object> holder,
Local<Function> callee,
bool is_construct_call,
void** argv, int argc) {
return v8::Arguments(data, holder, callee, is_construct_call, argv, argc);
// Packs additional parameters for the NewArguments function. |implicit_args|
// is a pointer to the last element of 3-elements array controlled by GC.
static void PrepareArgumentsData(internal::Object** implicit_args,
internal::Object* data,
internal::JSFunction* callee,
internal::Object* holder) {
implicit_args[v8::Arguments::kDataIndex] = data;
implicit_args[v8::Arguments::kCalleeIndex] = callee;
implicit_args[v8::Arguments::kHolderIndex] = holder;
}
static v8::Arguments NewArguments(internal::Object** implicit_args,
internal::Object** argv, int argc,
bool is_construct_call) {
return v8::Arguments(implicit_args, argv, argc, is_construct_call);
}
// Introduce an alias for the handle scope data to allow non-friends

View File

@ -84,6 +84,15 @@ class CustomArguments : public Relocatable {
values_[1] = holder;
values_[0] = data;
}
inline CustomArguments() {
#ifdef DEBUG
for (size_t i = 0; i < ARRAY_SIZE(values_); i++) {
values_[i] = reinterpret_cast<Object*>(kZapValue);
}
#endif
}
void IterateInstance(ObjectVisitor* v);
Object** end() { return values_ + ARRAY_SIZE(values_) - 1; }
private:

View File

@ -1014,20 +1014,18 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallHelper(
Object* data_obj = call_data->data();
Object* result;
Handle<Object> data_handle(data_obj);
v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle);
ASSERT(raw_holder->IsJSObject());
v8::Local<v8::Function> callee = v8::Utils::ToLocal(function);
Handle<JSObject> holder_handle(JSObject::cast(raw_holder));
v8::Local<v8::Object> holder = v8::Utils::ToLocal(holder_handle);
LOG(ApiObjectAccess("call", JSObject::cast(*args.receiver())));
ASSERT(raw_holder->IsJSObject());
CustomArguments custom;
v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
data_obj, *function, raw_holder);
v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
data,
holder,
callee,
is_construct,
reinterpret_cast<void**>(&args[0] - 1),
args.length() - 1);
custom.end(),
&args[0] - 1,
args.length() - 1,
is_construct);
v8::Handle<v8::Value> value;
{
@ -1089,26 +1087,22 @@ BUILTIN(FastHandleApiCall) {
Handle<JSFunction> function = args.at<JSFunction>(args_length);
Object* callback_obj = args[args_length + 1];
Handle<Object> data_handle = args.at<Object>(args_length + 2);
Handle<Object> data = args.at<Object>(args_length + 2);
Handle<JSObject> checked_holder = args.at<JSObject>(args_length + 3);
#ifdef DEBUG
VerifyTypeCheck(checked_holder, function);
#endif
v8::Local<v8::Object> holder = v8::Utils::ToLocal(checked_holder);
v8::Local<v8::Function> callee = v8::Utils::ToLocal(function);
v8::InvocationCallback callback =
v8::ToCData<v8::InvocationCallback>(callback_obj);
v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle);
CustomArguments custom;
v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
*data, *function, *checked_holder);
v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
data,
holder,
callee,
is_construct,
reinterpret_cast<void**>(&args[0] - 1),
args_length - 1);
custom.end(),
&args[0] - 1,
args_length - 1,
is_construct);
HandleScope scope;
Object* result;
@ -1119,6 +1113,9 @@ BUILTIN(FastHandleApiCall) {
#ifdef ENABLE_LOGGING_AND_PROFILING
state.set_external_callback(v8::ToCData<Address>(callback_obj));
#endif
v8::InvocationCallback callback =
v8::ToCData<v8::InvocationCallback>(callback_obj);
value = callback(new_args);
}
if (value.IsEmpty()) {
@ -1161,23 +1158,20 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallAsFunctionOrConstructor(
v8::ToCData<v8::InvocationCallback>(callback_obj);
// Get the data for the call and perform the callback.
Object* data_obj = call_data->data();
Object* result;
{ HandleScope scope;
v8::Local<v8::Object> self =
v8::Utils::ToLocal(Handle<JSObject>::cast(args.receiver()));
Handle<Object> data_handle(data_obj);
v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle);
Handle<JSFunction> callee_handle(constructor);
v8::Local<v8::Function> callee = v8::Utils::ToLocal(callee_handle);
LOG(ApiObjectAccess("call non-function", JSObject::cast(*args.receiver())));
{
HandleScope scope;
LOG(ApiObjectAccess("call non-function", obj));
CustomArguments custom;
v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
call_data->data(), constructor, obj);
v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
data,
self,
callee,
is_construct_call,
reinterpret_cast<void**>(&args[0] - 1),
args.length() - 1);
custom.end(),
&args[0] - 1,
args.length() - 1,
is_construct_call);
v8::Handle<v8::Value> value;
{
// Leaving JavaScript.