Revert of Do not eagerly instantiate accessors' JSFunction. (patchset #9 id:180001 of https://codereview.chromium.org/1609233002/ )
Reason for revert: [Sheriff] Breaks gcmole: https://build.chromium.org/p/client.v8/builders/V8%20Linux%20-%20gcmole/builds/6260 Original issue's description: > Do not eagerly instantiate accessors' JSFunction. > > BUG= > > Committed: https://crrev.com/4d46b510caf534d770ce19a01a11b8796304471b > Cr-Commit-Position: refs/heads/master@{#33812} TBR=verwaest@chromium.org,epertoso@chromium.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG= Review URL: https://codereview.chromium.org/1679683004 Cr-Commit-Position: refs/heads/master@{#33814}
This commit is contained in:
parent
07e9921f5a
commit
0e6f0964f0
@ -16,8 +16,8 @@ namespace internal {
|
||||
namespace {
|
||||
|
||||
MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
|
||||
Handle<ObjectTemplateInfo> data,
|
||||
bool is_hidden_prototype);
|
||||
Handle<ObjectTemplateInfo> data);
|
||||
|
||||
|
||||
MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate,
|
||||
Handle<FunctionTemplateInfo> data,
|
||||
@ -30,36 +30,32 @@ MaybeHandle<Object> Instantiate(Isolate* isolate, Handle<Object> data,
|
||||
return InstantiateFunction(isolate,
|
||||
Handle<FunctionTemplateInfo>::cast(data), name);
|
||||
} else if (data->IsObjectTemplateInfo()) {
|
||||
return InstantiateObject(isolate, Handle<ObjectTemplateInfo>::cast(data),
|
||||
false);
|
||||
return InstantiateObject(isolate, Handle<ObjectTemplateInfo>::cast(data));
|
||||
} else {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
MaybeHandle<Object> DefineAccessorProperty(
|
||||
Isolate* isolate, Handle<JSObject> object, Handle<Name> name,
|
||||
Handle<Object> getter, Handle<Object> setter, PropertyAttributes attributes,
|
||||
bool force_instantiate) {
|
||||
DCHECK(!getter->IsFunctionTemplateInfo() ||
|
||||
!FunctionTemplateInfo::cast(*getter)->do_not_cache());
|
||||
DCHECK(!setter->IsFunctionTemplateInfo() ||
|
||||
!FunctionTemplateInfo::cast(*setter)->do_not_cache());
|
||||
if (force_instantiate) {
|
||||
if (getter->IsFunctionTemplateInfo()) {
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, getter,
|
||||
InstantiateFunction(isolate,
|
||||
Handle<FunctionTemplateInfo>::cast(getter)),
|
||||
Object);
|
||||
}
|
||||
if (setter->IsFunctionTemplateInfo()) {
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, setter,
|
||||
InstantiateFunction(isolate,
|
||||
Handle<FunctionTemplateInfo>::cast(setter)),
|
||||
Object);
|
||||
}
|
||||
|
||||
MaybeHandle<Object> DefineAccessorProperty(Isolate* isolate,
|
||||
Handle<JSObject> object,
|
||||
Handle<Name> name,
|
||||
Handle<Object> getter,
|
||||
Handle<Object> setter,
|
||||
PropertyAttributes attributes) {
|
||||
if (!getter->IsUndefined()) {
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, getter,
|
||||
InstantiateFunction(isolate,
|
||||
Handle<FunctionTemplateInfo>::cast(getter)),
|
||||
Object);
|
||||
}
|
||||
if (!setter->IsUndefined()) {
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, setter,
|
||||
InstantiateFunction(isolate,
|
||||
Handle<FunctionTemplateInfo>::cast(setter)),
|
||||
Object);
|
||||
}
|
||||
RETURN_ON_EXCEPTION(isolate, JSObject::DefineAccessor(object, name, getter,
|
||||
setter, attributes),
|
||||
@ -174,8 +170,7 @@ ObjectTemplateInfo* GetParent(ObjectTemplateInfo* data) {
|
||||
|
||||
template <typename TemplateInfoT>
|
||||
MaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj,
|
||||
Handle<TemplateInfoT> data,
|
||||
bool is_hidden_prototype) {
|
||||
Handle<TemplateInfoT> data) {
|
||||
HandleScope scope(isolate);
|
||||
// Disable access checks while instantiating the object.
|
||||
AccessCheckDisableScope access_check_scope(isolate, obj);
|
||||
@ -242,10 +237,10 @@ MaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj,
|
||||
} else {
|
||||
auto getter = handle(properties.get(i++), isolate);
|
||||
auto setter = handle(properties.get(i++), isolate);
|
||||
RETURN_ON_EXCEPTION(
|
||||
isolate, DefineAccessorProperty(isolate, obj, name, getter, setter,
|
||||
attributes, is_hidden_prototype),
|
||||
JSObject);
|
||||
RETURN_ON_EXCEPTION(isolate,
|
||||
DefineAccessorProperty(isolate, obj, name, getter,
|
||||
setter, attributes),
|
||||
JSObject);
|
||||
}
|
||||
} else {
|
||||
// Intrinsic data property --- Get appropriate value from the current
|
||||
@ -282,8 +277,7 @@ void UncacheTemplateInstantiation(Isolate* isolate, Handle<Smi> serial_number) {
|
||||
}
|
||||
|
||||
MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
|
||||
Handle<ObjectTemplateInfo> info,
|
||||
bool is_hidden_prototype) {
|
||||
Handle<ObjectTemplateInfo> info) {
|
||||
// Enter a new scope. Recursion could otherwise create a lot of handles.
|
||||
HandleScope scope(isolate);
|
||||
// Fast path.
|
||||
@ -311,9 +305,7 @@ MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
|
||||
}
|
||||
auto object = isolate->factory()->NewJSObject(cons);
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, result,
|
||||
ConfigureInstance(isolate, object, info, is_hidden_prototype),
|
||||
JSFunction);
|
||||
isolate, result, ConfigureInstance(isolate, object, info), JSFunction);
|
||||
// TODO(dcarney): is this necessary?
|
||||
JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject");
|
||||
|
||||
@ -349,8 +341,7 @@ MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate,
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, prototype,
|
||||
InstantiateObject(isolate,
|
||||
Handle<ObjectTemplateInfo>::cast(prototype_templ),
|
||||
data->hidden_prototype()),
|
||||
Handle<ObjectTemplateInfo>::cast(prototype_templ)),
|
||||
JSFunction);
|
||||
}
|
||||
auto parent = handle(data->parent_template(), isolate);
|
||||
@ -382,8 +373,7 @@ MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate,
|
||||
// Cache the function.
|
||||
CacheTemplateInstantiation(isolate, serial_number, function);
|
||||
}
|
||||
auto result =
|
||||
ConfigureInstance(isolate, function, data, data->hidden_prototype());
|
||||
auto result = ConfigureInstance(isolate, function, data);
|
||||
if (result.is_null()) {
|
||||
// Uncache on error.
|
||||
if (serial_number->value()) {
|
||||
@ -447,7 +437,7 @@ MaybeHandle<JSObject> ApiNatives::InstantiateObject(
|
||||
Handle<ObjectTemplateInfo> data) {
|
||||
Isolate* isolate = data->GetIsolate();
|
||||
InvokeScope invoke_scope(isolate);
|
||||
return ::v8::internal::InstantiateObject(isolate, data, false);
|
||||
return ::v8::internal::InstantiateObject(isolate, data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -220,14 +220,17 @@ class FunctionCallbackArguments
|
||||
static const int kCalleeIndex = T::kCalleeIndex;
|
||||
static const int kContextSaveIndex = T::kContextSaveIndex;
|
||||
|
||||
FunctionCallbackArguments(internal::Isolate* isolate, internal::Object* data,
|
||||
internal::HeapObject* callee,
|
||||
internal::Object* holder, internal::Object** argv,
|
||||
int argc, bool is_construct_call)
|
||||
: Super(isolate),
|
||||
argv_(argv),
|
||||
argc_(argc),
|
||||
is_construct_call_(is_construct_call) {
|
||||
FunctionCallbackArguments(internal::Isolate* isolate,
|
||||
internal::Object* data,
|
||||
internal::JSFunction* callee,
|
||||
internal::Object* holder,
|
||||
internal::Object** argv,
|
||||
int argc,
|
||||
bool is_construct_call)
|
||||
: Super(isolate),
|
||||
argv_(argv),
|
||||
argc_(argc),
|
||||
is_construct_call_(is_construct_call) {
|
||||
Object** values = begin();
|
||||
values[T::kDataIndex] = data;
|
||||
values[T::kCalleeIndex] = callee;
|
||||
@ -239,8 +242,7 @@ class FunctionCallbackArguments
|
||||
values[T::kReturnValueDefaultValueIndex] =
|
||||
isolate->heap()->the_hole_value();
|
||||
values[T::kReturnValueIndex] = isolate->heap()->the_hole_value();
|
||||
DCHECK(values[T::kCalleeIndex]->IsJSFunction() ||
|
||||
values[T::kCalleeIndex]->IsFunctionTemplateInfo());
|
||||
DCHECK(values[T::kCalleeIndex]->IsJSFunction());
|
||||
DCHECK(values[T::kHolderIndex]->IsHeapObject());
|
||||
DCHECK(values[T::kIsolateIndex]->IsSmi());
|
||||
}
|
||||
|
@ -5375,10 +5375,11 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
|
||||
__ jmp(&leave_exit_frame);
|
||||
}
|
||||
|
||||
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
bool call_data_undefined) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r0 : callee
|
||||
// -- r4 : call_data
|
||||
@ -5414,10 +5415,8 @@ static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
|
||||
// context save
|
||||
__ push(context);
|
||||
if (!is_lazy) {
|
||||
// load context from callee
|
||||
__ ldr(context, FieldMemOperand(callee, JSFunction::kContextOffset));
|
||||
}
|
||||
// load context from callee
|
||||
__ ldr(context, FieldMemOperand(callee, JSFunction::kContextOffset));
|
||||
|
||||
// callee
|
||||
__ push(callee);
|
||||
@ -5509,7 +5508,7 @@ static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(r3), false,
|
||||
call_data_undefined, false);
|
||||
call_data_undefined);
|
||||
}
|
||||
|
||||
|
||||
@ -5517,9 +5516,8 @@ void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
call_data_undefined);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5803,10 +5803,11 @@ static void CallApiFunctionAndReturn(
|
||||
__ B(&leave_exit_frame);
|
||||
}
|
||||
|
||||
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
bool call_data_undefined) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- x0 : callee
|
||||
// -- x4 : call_data
|
||||
@ -5843,10 +5844,8 @@ static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
// FunctionCallbackArguments: context, callee and call data.
|
||||
__ Push(context, callee, call_data);
|
||||
|
||||
if (!is_lazy) {
|
||||
// Load context from callee
|
||||
__ Ldr(context, FieldMemOperand(callee, JSFunction::kContextOffset));
|
||||
}
|
||||
// Load context from callee
|
||||
__ Ldr(context, FieldMemOperand(callee, JSFunction::kContextOffset));
|
||||
|
||||
if (!call_data_undefined) {
|
||||
__ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
|
||||
@ -5931,7 +5930,7 @@ static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(x3), false,
|
||||
call_data_undefined, false);
|
||||
call_data_undefined);
|
||||
}
|
||||
|
||||
|
||||
@ -5939,9 +5938,8 @@ void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
call_data_undefined);
|
||||
}
|
||||
|
||||
|
||||
|
@ -59,8 +59,7 @@ class BuiltinArguments : public Arguments {
|
||||
return Arguments::at<Object>(0);
|
||||
}
|
||||
|
||||
template <class S>
|
||||
Handle<S> target();
|
||||
Handle<JSFunction> target();
|
||||
Handle<HeapObject> new_target();
|
||||
|
||||
// Gets the total number of arguments including the receiver (but
|
||||
@ -82,9 +81,8 @@ int BuiltinArguments<BuiltinExtraArguments::kTarget>::length() const {
|
||||
}
|
||||
|
||||
template <>
|
||||
template <class S>
|
||||
Handle<S> BuiltinArguments<BuiltinExtraArguments::kTarget>::target() {
|
||||
return Arguments::at<S>(Arguments::length() - 1);
|
||||
Handle<JSFunction> BuiltinArguments<BuiltinExtraArguments::kTarget>::target() {
|
||||
return Arguments::at<JSFunction>(Arguments::length() - 1);
|
||||
}
|
||||
|
||||
template <>
|
||||
@ -105,10 +103,9 @@ int BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget>::length()
|
||||
}
|
||||
|
||||
template <>
|
||||
template <class S>
|
||||
Handle<S>
|
||||
Handle<JSFunction>
|
||||
BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget>::target() {
|
||||
return Arguments::at<S>(Arguments::length() - 2);
|
||||
return Arguments::at<JSFunction>(Arguments::length() - 2);
|
||||
}
|
||||
|
||||
template <>
|
||||
@ -1942,7 +1939,7 @@ MaybeHandle<JSFunction> CompileString(Handle<Context> context,
|
||||
BUILTIN(GlobalEval) {
|
||||
HandleScope scope(isolate);
|
||||
Handle<Object> x = args.atOrUndefined(isolate, 1);
|
||||
Handle<JSFunction> target = args.target<JSFunction>();
|
||||
Handle<JSFunction> target = args.target();
|
||||
Handle<JSObject> target_global_proxy(target->global_proxy(), isolate);
|
||||
if (!x->IsString()) return *x;
|
||||
Handle<JSFunction> function;
|
||||
@ -2438,7 +2435,7 @@ BUILTIN(DateConstructor) {
|
||||
BUILTIN(DateConstructor_ConstructStub) {
|
||||
HandleScope scope(isolate);
|
||||
int const argc = args.length() - 1;
|
||||
Handle<JSFunction> target = args.target<JSFunction>();
|
||||
Handle<JSFunction> target = args.target();
|
||||
Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
|
||||
double time_val;
|
||||
if (argc == 0) {
|
||||
@ -3322,7 +3319,7 @@ MaybeHandle<JSFunction> CreateDynamicFunction(
|
||||
|
||||
// Compile the string in the constructor and not a helper so that errors to
|
||||
// come from here.
|
||||
Handle<JSFunction> target = args.target<JSFunction>();
|
||||
Handle<JSFunction> target = args.target();
|
||||
Handle<JSObject> target_global_proxy(target->global_proxy(), isolate);
|
||||
Handle<JSFunction> function;
|
||||
{
|
||||
@ -3507,7 +3504,7 @@ BUILTIN(ObjectProtoToString) {
|
||||
// ES6 section 24.1.2.1 ArrayBuffer ( length ) for the [[Call]] case.
|
||||
BUILTIN(ArrayBufferConstructor) {
|
||||
HandleScope scope(isolate);
|
||||
Handle<JSFunction> target = args.target<JSFunction>();
|
||||
Handle<JSFunction> target = args.target();
|
||||
DCHECK(*target == target->native_context()->array_buffer_fun() ||
|
||||
*target == target->native_context()->shared_array_buffer_fun());
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
@ -3519,7 +3516,7 @@ BUILTIN(ArrayBufferConstructor) {
|
||||
// ES6 section 24.1.2.1 ArrayBuffer ( length ) for the [[Construct]] case.
|
||||
BUILTIN(ArrayBufferConstructor_ConstructStub) {
|
||||
HandleScope scope(isolate);
|
||||
Handle<JSFunction> target = args.target<JSFunction>();
|
||||
Handle<JSFunction> target = args.target();
|
||||
Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
|
||||
Handle<Object> length = args.atOrUndefined(isolate, 1);
|
||||
DCHECK(*target == target->native_context()->array_buffer_fun() ||
|
||||
@ -3616,16 +3613,13 @@ template <bool is_construct>
|
||||
MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(
|
||||
Isolate* isolate, BuiltinArguments<BuiltinExtraArguments::kTarget> args) {
|
||||
HandleScope scope(isolate);
|
||||
Handle<HeapObject> function = args.target<HeapObject>();
|
||||
Handle<JSFunction> function = args.target();
|
||||
Handle<JSReceiver> receiver;
|
||||
// TODO(ishell): turn this back to a DCHECK.
|
||||
CHECK(function->IsFunctionTemplateInfo() ||
|
||||
Handle<JSFunction>::cast(function)->shared()->IsApiFunction());
|
||||
CHECK(function->shared()->IsApiFunction());
|
||||
|
||||
Handle<FunctionTemplateInfo> fun_data =
|
||||
function->IsFunctionTemplateInfo()
|
||||
? Handle<FunctionTemplateInfo>::cast(function)
|
||||
: handle(JSFunction::cast(*function)->shared()->get_api_func_data());
|
||||
Handle<FunctionTemplateInfo> fun_data(
|
||||
function->shared()->get_api_func_data(), isolate);
|
||||
if (is_construct) {
|
||||
DCHECK(args.receiver()->IsTheHole());
|
||||
if (fun_data->instance_template()->IsUndefined()) {
|
||||
@ -3812,7 +3806,8 @@ class RelocatableArguments
|
||||
|
||||
} // namespace
|
||||
|
||||
MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<HeapObject> function,
|
||||
|
||||
MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<JSFunction> function,
|
||||
Handle<Object> receiver,
|
||||
int argc,
|
||||
Handle<Object> args[]) {
|
||||
|
@ -385,7 +385,7 @@ class Builtins {
|
||||
bool is_initialized() const { return initialized_; }
|
||||
|
||||
MUST_USE_RESULT static MaybeHandle<Object> InvokeApiFunction(
|
||||
Handle<HeapObject> function, Handle<Object> receiver, int argc,
|
||||
Handle<JSFunction> function, Handle<Object> receiver, int argc,
|
||||
Handle<Object> args[]);
|
||||
|
||||
private:
|
||||
|
@ -1403,13 +1403,11 @@ class CallApiFunctionStub : public PlatformCodeStub {
|
||||
|
||||
class CallApiAccessorStub : public PlatformCodeStub {
|
||||
public:
|
||||
CallApiAccessorStub(Isolate* isolate, bool is_store, bool call_data_undefined,
|
||||
bool is_lazy)
|
||||
CallApiAccessorStub(Isolate* isolate, bool is_store, bool call_data_undefined)
|
||||
: PlatformCodeStub(isolate) {
|
||||
minor_key_ = IsStoreBits::encode(is_store) |
|
||||
CallDataUndefinedBits::encode(call_data_undefined) |
|
||||
ArgumentBits::encode(is_store ? 1 : 0) |
|
||||
IsLazyAccessorBits::encode(is_lazy);
|
||||
ArgumentBits::encode(is_store ? 1 : 0);
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -1424,7 +1422,6 @@ class CallApiAccessorStub : public PlatformCodeStub {
|
||||
|
||||
private:
|
||||
bool is_store() const { return IsStoreBits::decode(minor_key_); }
|
||||
bool is_lazy() const { return IsLazyAccessorBits::decode(minor_key_); }
|
||||
bool call_data_undefined() const {
|
||||
return CallDataUndefinedBits::decode(minor_key_);
|
||||
}
|
||||
@ -1433,7 +1430,6 @@ class CallApiAccessorStub : public PlatformCodeStub {
|
||||
class IsStoreBits: public BitField<bool, 0, 1> {};
|
||||
class CallDataUndefinedBits: public BitField<bool, 1, 1> {};
|
||||
class ArgumentBits : public BitField<int, 2, kArgBits> {};
|
||||
class IsLazyAccessorBits : public BitField<bool, 3 + kArgBits, 1> {};
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiAccessor);
|
||||
DEFINE_PLATFORM_CODE_STUB(CallApiAccessor, PlatformCodeStub);
|
||||
|
@ -6371,15 +6371,15 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) {
|
||||
Object* raw_accessor =
|
||||
IsLoad() ? Handle<AccessorPair>::cast(accessors)->getter()
|
||||
: Handle<AccessorPair>::cast(accessors)->setter();
|
||||
if (!raw_accessor->IsJSFunction() &&
|
||||
!raw_accessor->IsFunctionTemplateInfo())
|
||||
return false;
|
||||
Handle<Object> accessor = handle(HeapObject::cast(raw_accessor));
|
||||
CallOptimization call_optimization(accessor);
|
||||
if (call_optimization.is_simple_api_call()) {
|
||||
CallOptimization::HolderLookup holder_lookup;
|
||||
api_holder_ =
|
||||
call_optimization.LookupHolderOfExpectedType(map_, &holder_lookup);
|
||||
if (!raw_accessor->IsJSFunction()) return false;
|
||||
Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor));
|
||||
if (accessor->shared()->IsApiFunction()) {
|
||||
CallOptimization call_optimization(accessor);
|
||||
if (call_optimization.is_simple_api_call()) {
|
||||
CallOptimization::HolderLookup holder_lookup;
|
||||
api_holder_ =
|
||||
call_optimization.LookupHolderOfExpectedType(map_, &holder_lookup);
|
||||
}
|
||||
}
|
||||
accessor_ = accessor;
|
||||
} else if (IsDataConstant()) {
|
||||
@ -6617,8 +6617,7 @@ HValue* HOptimizedGraphBuilder::BuildMonomorphicAccess(
|
||||
Push(value);
|
||||
}
|
||||
|
||||
if (info->accessor()->IsJSFunction() &&
|
||||
info->NeedsWrappingFor(Handle<JSFunction>::cast(info->accessor()))) {
|
||||
if (info->NeedsWrappingFor(info->accessor())) {
|
||||
HValue* function = Add<HConstant>(info->accessor());
|
||||
PushArgumentsFromEnvironment(argument_count);
|
||||
return New<HCallFunction>(function, argument_count,
|
||||
@ -6633,12 +6632,7 @@ HValue* HOptimizedGraphBuilder::BuildMonomorphicAccess(
|
||||
}
|
||||
|
||||
PushArgumentsFromEnvironment(argument_count);
|
||||
if (!info->accessor()->IsJSFunction()) {
|
||||
Bailout(kInliningBailedOut);
|
||||
return nullptr;
|
||||
}
|
||||
return BuildCallConstantFunction(Handle<JSFunction>::cast(info->accessor()),
|
||||
argument_count);
|
||||
return BuildCallConstantFunction(info->accessor(), argument_count);
|
||||
}
|
||||
|
||||
DCHECK(info->IsDataConstant());
|
||||
@ -8672,25 +8666,24 @@ bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr,
|
||||
CONSTRUCT_CALL_RETURN);
|
||||
}
|
||||
|
||||
bool HOptimizedGraphBuilder::TryInlineGetter(Handle<Object> getter,
|
||||
|
||||
bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter,
|
||||
Handle<Map> receiver_map,
|
||||
BailoutId ast_id,
|
||||
BailoutId return_id) {
|
||||
if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true;
|
||||
return getter->IsJSFunction() &&
|
||||
TryInline(Handle<JSFunction>::cast(getter), 0, NULL, ast_id, return_id,
|
||||
GETTER_CALL_RETURN);
|
||||
return TryInline(getter, 0, NULL, ast_id, return_id, GETTER_CALL_RETURN);
|
||||
}
|
||||
|
||||
bool HOptimizedGraphBuilder::TryInlineSetter(Handle<Object> setter,
|
||||
|
||||
bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter,
|
||||
Handle<Map> receiver_map,
|
||||
BailoutId id,
|
||||
BailoutId assignment_id,
|
||||
HValue* implicit_return_value) {
|
||||
if (TryInlineApiSetter(setter, receiver_map, id)) return true;
|
||||
return setter->IsJSFunction() &&
|
||||
TryInline(Handle<JSFunction>::cast(setter), 1, implicit_return_value,
|
||||
id, assignment_id, SETTER_CALL_RETURN);
|
||||
return TryInline(setter, 1, implicit_return_value, id, assignment_id,
|
||||
SETTER_CALL_RETURN);
|
||||
}
|
||||
|
||||
|
||||
@ -9184,7 +9177,8 @@ bool HOptimizedGraphBuilder::TryInlineApiMethodCall(
|
||||
kCallApiMethod);
|
||||
}
|
||||
|
||||
bool HOptimizedGraphBuilder::TryInlineApiGetter(Handle<Object> function,
|
||||
|
||||
bool HOptimizedGraphBuilder::TryInlineApiGetter(Handle<JSFunction> function,
|
||||
Handle<Map> receiver_map,
|
||||
BailoutId ast_id) {
|
||||
SmallMapList receiver_maps(1, zone());
|
||||
@ -9197,7 +9191,8 @@ bool HOptimizedGraphBuilder::TryInlineApiGetter(Handle<Object> function,
|
||||
kCallApiGetter);
|
||||
}
|
||||
|
||||
bool HOptimizedGraphBuilder::TryInlineApiSetter(Handle<Object> function,
|
||||
|
||||
bool HOptimizedGraphBuilder::TryInlineApiSetter(Handle<JSFunction> function,
|
||||
Handle<Map> receiver_map,
|
||||
BailoutId ast_id) {
|
||||
SmallMapList receiver_maps(1, zone());
|
||||
@ -9210,14 +9205,15 @@ bool HOptimizedGraphBuilder::TryInlineApiSetter(Handle<Object> function,
|
||||
kCallApiSetter);
|
||||
}
|
||||
|
||||
bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<Object> function,
|
||||
HValue* receiver,
|
||||
SmallMapList* receiver_maps,
|
||||
int argc, BailoutId ast_id,
|
||||
ApiCallType call_type) {
|
||||
if (function->IsJSFunction() &&
|
||||
Handle<JSFunction>::cast(function)->context()->native_context() !=
|
||||
top_info()->closure()->context()->native_context()) {
|
||||
|
||||
bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<JSFunction> function,
|
||||
HValue* receiver,
|
||||
SmallMapList* receiver_maps,
|
||||
int argc,
|
||||
BailoutId ast_id,
|
||||
ApiCallType call_type) {
|
||||
if (function->context()->native_context() !=
|
||||
top_info()->closure()->context()->native_context()) {
|
||||
return false;
|
||||
}
|
||||
CallOptimization optimization(function);
|
||||
@ -9232,11 +9228,8 @@ bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<Object> function,
|
||||
// Cannot embed a direct reference to the global proxy map
|
||||
// as it maybe dropped on deserialization.
|
||||
CHECK(!isolate()->serializer_enabled());
|
||||
DCHECK(function->IsJSFunction());
|
||||
DCHECK_EQ(0, receiver_maps->length());
|
||||
receiver_maps->Add(
|
||||
handle(Handle<JSFunction>::cast(function)->global_proxy()->map()),
|
||||
zone());
|
||||
receiver_maps->Add(handle(function->global_proxy()->map()), zone());
|
||||
}
|
||||
CallOptimization::HolderLookup holder_lookup =
|
||||
CallOptimization::kHolderNotFound;
|
||||
@ -9316,8 +9309,7 @@ bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<Object> function,
|
||||
|
||||
HInstruction* call = nullptr;
|
||||
if (!is_function) {
|
||||
CallApiAccessorStub stub(isolate(), is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
CallApiAccessorStub stub(isolate(), is_store, call_data_undefined);
|
||||
Handle<Code> code = stub.GetCode();
|
||||
HConstant* code_value = Add<HConstant>(code);
|
||||
ApiAccessorDescriptor descriptor(isolate());
|
||||
|
@ -2427,10 +2427,14 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
||||
|
||||
bool TryInlineCall(Call* expr);
|
||||
bool TryInlineConstruct(CallNew* expr, HValue* implicit_return_value);
|
||||
bool TryInlineGetter(Handle<Object> getter, Handle<Map> receiver_map,
|
||||
BailoutId ast_id, BailoutId return_id);
|
||||
bool TryInlineSetter(Handle<Object> setter, Handle<Map> receiver_map,
|
||||
BailoutId id, BailoutId assignment_id,
|
||||
bool TryInlineGetter(Handle<JSFunction> getter,
|
||||
Handle<Map> receiver_map,
|
||||
BailoutId ast_id,
|
||||
BailoutId return_id);
|
||||
bool TryInlineSetter(Handle<JSFunction> setter,
|
||||
Handle<Map> receiver_map,
|
||||
BailoutId id,
|
||||
BailoutId assignment_id,
|
||||
HValue* implicit_return_value);
|
||||
bool TryInlineIndirectCall(Handle<JSFunction> function, Call* expr,
|
||||
int arguments_count);
|
||||
@ -2448,13 +2452,18 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
||||
HValue* receiver,
|
||||
SmallMapList* receiver_types);
|
||||
bool TryInlineApiFunctionCall(Call* expr, HValue* receiver);
|
||||
bool TryInlineApiGetter(Handle<Object> function, Handle<Map> receiver_map,
|
||||
bool TryInlineApiGetter(Handle<JSFunction> function,
|
||||
Handle<Map> receiver_map,
|
||||
BailoutId ast_id);
|
||||
bool TryInlineApiSetter(Handle<Object> function, Handle<Map> receiver_map,
|
||||
bool TryInlineApiSetter(Handle<JSFunction> function,
|
||||
Handle<Map> receiver_map,
|
||||
BailoutId ast_id);
|
||||
bool TryInlineApiCall(Handle<Object> function, HValue* receiver,
|
||||
SmallMapList* receiver_maps, int argc, BailoutId ast_id,
|
||||
ApiCallType call_type);
|
||||
bool TryInlineApiCall(Handle<JSFunction> function,
|
||||
HValue* receiver,
|
||||
SmallMapList* receiver_maps,
|
||||
int argc,
|
||||
BailoutId ast_id,
|
||||
ApiCallType call_type);
|
||||
static bool IsReadOnlyLengthDescriptor(Handle<Map> jsarray_map);
|
||||
static bool CanInlineArrayResizeOperation(Handle<Map> receiver_map);
|
||||
|
||||
@ -2597,7 +2606,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
||||
|
||||
Isolate* isolate() const { return builder_->isolate(); }
|
||||
Handle<JSObject> holder() { return holder_; }
|
||||
Handle<Object> accessor() { return accessor_; }
|
||||
Handle<JSFunction> accessor() { return accessor_; }
|
||||
Handle<Object> constant() { return constant_; }
|
||||
Handle<Map> transition() { return transition_; }
|
||||
SmallMapList* field_maps() { return &field_maps_; }
|
||||
@ -2703,7 +2712,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
||||
Handle<Map> map_;
|
||||
Handle<Name> name_;
|
||||
Handle<JSObject> holder_;
|
||||
Handle<Object> accessor_;
|
||||
Handle<JSFunction> accessor_;
|
||||
Handle<JSObject> api_holder_;
|
||||
Handle<Object> constant_;
|
||||
SmallMapList field_maps_;
|
||||
|
@ -5648,10 +5648,11 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
|
||||
__ jmp(&leave_exit_frame);
|
||||
}
|
||||
|
||||
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
bool call_data_undefined) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- edi : callee
|
||||
// -- ebx : call_data
|
||||
@ -5725,10 +5726,8 @@ static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
// push return address
|
||||
__ push(return_address);
|
||||
|
||||
if (!is_lazy) {
|
||||
// load context from callee
|
||||
__ mov(context, FieldOperand(callee, JSFunction::kContextOffset));
|
||||
}
|
||||
// load context from callee
|
||||
__ mov(context, FieldOperand(callee, JSFunction::kContextOffset));
|
||||
|
||||
// API function gets reference to the v8::Arguments. If CPU profiler
|
||||
// is enabled wrapper function will be called and we need to pass
|
||||
@ -5800,7 +5799,7 @@ static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(eax), false,
|
||||
call_data_undefined, false);
|
||||
call_data_undefined);
|
||||
}
|
||||
|
||||
|
||||
@ -5808,9 +5807,8 @@ void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
call_data_undefined);
|
||||
}
|
||||
|
||||
|
||||
|
@ -286,17 +286,11 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
call_data_undefined = true;
|
||||
__ LoadRoot(data, Heap::kUndefinedValueRootIndex);
|
||||
} else {
|
||||
if (optimization.is_constant_call()) {
|
||||
__ ldr(data,
|
||||
FieldMemOperand(callee, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ ldr(data,
|
||||
FieldMemOperand(data, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ ldr(data,
|
||||
FieldMemOperand(data, FunctionTemplateInfo::kCallCodeOffset));
|
||||
} else {
|
||||
__ ldr(data,
|
||||
FieldMemOperand(callee, FunctionTemplateInfo::kCallCodeOffset));
|
||||
}
|
||||
__ ldr(data,
|
||||
FieldMemOperand(callee, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ ldr(data,
|
||||
FieldMemOperand(data, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ ldr(data, FieldMemOperand(data, FunctionTemplateInfo::kCallCodeOffset));
|
||||
__ ldr(data, FieldMemOperand(data, CallHandlerInfo::kDataOffset));
|
||||
}
|
||||
|
||||
@ -315,8 +309,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
__ mov(api_function_address, Operand(ref));
|
||||
|
||||
// Jump to stub.
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined);
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
||||
|
@ -198,17 +198,11 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
call_data_undefined = true;
|
||||
__ LoadRoot(data, Heap::kUndefinedValueRootIndex);
|
||||
} else {
|
||||
if (optimization.is_constant_call()) {
|
||||
__ Ldr(data,
|
||||
FieldMemOperand(callee, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ Ldr(data,
|
||||
FieldMemOperand(data, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ Ldr(data,
|
||||
FieldMemOperand(data, FunctionTemplateInfo::kCallCodeOffset));
|
||||
} else {
|
||||
__ Ldr(data,
|
||||
FieldMemOperand(callee, FunctionTemplateInfo::kCallCodeOffset));
|
||||
}
|
||||
__ Ldr(data,
|
||||
FieldMemOperand(callee, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ Ldr(data,
|
||||
FieldMemOperand(data, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ Ldr(data, FieldMemOperand(data, FunctionTemplateInfo::kCallCodeOffset));
|
||||
__ Ldr(data, FieldMemOperand(data, CallHandlerInfo::kDataOffset));
|
||||
}
|
||||
|
||||
@ -227,8 +221,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
__ Mov(api_function_address, ref);
|
||||
|
||||
// Jump to stub.
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined);
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
||||
|
@ -8,16 +8,8 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
CallOptimization::CallOptimization(Handle<Object> function) {
|
||||
constant_function_ = Handle<JSFunction>::null();
|
||||
is_simple_api_call_ = false;
|
||||
expected_receiver_type_ = Handle<FunctionTemplateInfo>::null();
|
||||
api_call_info_ = Handle<CallHandlerInfo>::null();
|
||||
if (function->IsJSFunction()) {
|
||||
Initialize(Handle<JSFunction>::cast(function));
|
||||
} else if (function->IsFunctionTemplateInfo()) {
|
||||
Initialize(Handle<FunctionTemplateInfo>::cast(function));
|
||||
}
|
||||
CallOptimization::CallOptimization(Handle<JSFunction> function) {
|
||||
Initialize(function);
|
||||
}
|
||||
|
||||
|
||||
@ -88,20 +80,13 @@ bool CallOptimization::IsCompatibleReceiverMap(Handle<Map> map,
|
||||
return false;
|
||||
}
|
||||
|
||||
void CallOptimization::Initialize(
|
||||
Handle<FunctionTemplateInfo> function_template_info) {
|
||||
if (function_template_info->call_code()->IsUndefined()) return;
|
||||
api_call_info_ =
|
||||
handle(CallHandlerInfo::cast(function_template_info->call_code()));
|
||||
|
||||
if (!function_template_info->signature()->IsUndefined()) {
|
||||
expected_receiver_type_ =
|
||||
handle(FunctionTemplateInfo::cast(function_template_info->signature()));
|
||||
}
|
||||
is_simple_api_call_ = true;
|
||||
}
|
||||
|
||||
void CallOptimization::Initialize(Handle<JSFunction> function) {
|
||||
constant_function_ = Handle<JSFunction>::null();
|
||||
is_simple_api_call_ = false;
|
||||
expected_receiver_type_ = Handle<FunctionTemplateInfo>::null();
|
||||
api_call_info_ = Handle<CallHandlerInfo>::null();
|
||||
|
||||
if (function.is_null() || !function->is_compiled()) return;
|
||||
|
||||
constant_function_ = function;
|
||||
|
@ -15,7 +15,7 @@ namespace internal {
|
||||
// Holds information about possible function call optimizations.
|
||||
class CallOptimization BASE_EMBEDDED {
|
||||
public:
|
||||
explicit CallOptimization(Handle<Object> function);
|
||||
explicit CallOptimization(Handle<JSFunction> function);
|
||||
|
||||
bool is_constant_call() const { return !constant_function_.is_null(); }
|
||||
|
||||
@ -51,7 +51,6 @@ class CallOptimization BASE_EMBEDDED {
|
||||
|
||||
private:
|
||||
void Initialize(Handle<JSFunction> function);
|
||||
void Initialize(Handle<FunctionTemplateInfo> function_template_info);
|
||||
|
||||
// Determines whether the given function can be called using the
|
||||
// fast api call builtin.
|
||||
|
@ -197,13 +197,9 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
call_data_undefined = true;
|
||||
__ mov(data, Immediate(isolate->factory()->undefined_value()));
|
||||
} else {
|
||||
if (optimization.is_constant_call()) {
|
||||
__ mov(data, FieldOperand(callee, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ mov(data, FieldOperand(data, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ mov(data, FieldOperand(data, FunctionTemplateInfo::kCallCodeOffset));
|
||||
} else {
|
||||
__ mov(data, FieldOperand(callee, FunctionTemplateInfo::kCallCodeOffset));
|
||||
}
|
||||
__ mov(data, FieldOperand(callee, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ mov(data, FieldOperand(data, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ mov(data, FieldOperand(data, FunctionTemplateInfo::kCallCodeOffset));
|
||||
__ mov(data, FieldOperand(data, CallHandlerInfo::kDataOffset));
|
||||
}
|
||||
|
||||
@ -218,8 +214,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
__ mov(api_function_address, Immediate(function_address));
|
||||
|
||||
// Jump to stub.
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined);
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
||||
|
84
src/ic/ic.cc
84
src/ic/ic.cc
@ -986,25 +986,18 @@ bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) {
|
||||
} else if (accessors->IsAccessorPair()) {
|
||||
Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(),
|
||||
isolate);
|
||||
if (!getter->IsJSFunction() && !getter->IsFunctionTemplateInfo())
|
||||
return false;
|
||||
Handle<JSObject> holder = lookup->GetHolder<JSObject>();
|
||||
Handle<Object> receiver = lookup->GetReceiver();
|
||||
if (holder->HasFastProperties()) {
|
||||
if (getter->IsJSFunction()) {
|
||||
Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
|
||||
if (!receiver->IsJSObject() && !function->shared()->IsBuiltin() &&
|
||||
is_sloppy(function->shared()->language_mode())) {
|
||||
// Calling sloppy non-builtins with a value as the receiver
|
||||
// requires boxing.
|
||||
if (getter->IsJSFunction() && holder->HasFastProperties()) {
|
||||
Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
|
||||
if (receiver->IsJSObject() || function->shared()->IsBuiltin() ||
|
||||
!is_sloppy(function->shared()->language_mode())) {
|
||||
CallOptimization call_optimization(function);
|
||||
if (call_optimization.is_simple_api_call() &&
|
||||
!call_optimization.IsCompatibleReceiverMap(receiver_map, holder)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
CallOptimization call_optimization(getter);
|
||||
if (call_optimization.is_simple_api_call() &&
|
||||
!call_optimization.IsCompatibleReceiverMap(receiver_map, holder)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -1174,39 +1167,48 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
|
||||
return stub.GetCode();
|
||||
}
|
||||
|
||||
if (IsCompatibleReceiver(lookup, map)) {
|
||||
Handle<Object> accessors = lookup->GetAccessors();
|
||||
if (accessors->IsAccessorPair()) {
|
||||
if (!holder->HasFastProperties()) break;
|
||||
// When debugging we need to go the slow path to flood the accessor.
|
||||
if (GetSharedFunctionInfo()->HasDebugInfo()) break;
|
||||
Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(),
|
||||
isolate());
|
||||
CallOptimization call_optimization(getter);
|
||||
NamedLoadHandlerCompiler compiler(isolate(), map, holder,
|
||||
cache_holder);
|
||||
if (call_optimization.is_simple_api_call()) {
|
||||
Handle<Object> accessors = lookup->GetAccessors();
|
||||
if (accessors->IsAccessorInfo()) {
|
||||
Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
|
||||
if (v8::ToCData<Address>(info->getter()) == 0) break;
|
||||
if (!AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map)) {
|
||||
// This case should be already handled in LoadIC::UpdateCaches.
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
if (!holder->HasFastProperties()) break;
|
||||
NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
|
||||
return compiler.CompileLoadCallback(lookup->name(), info);
|
||||
}
|
||||
if (accessors->IsAccessorPair()) {
|
||||
Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(),
|
||||
isolate());
|
||||
if (!getter->IsJSFunction()) break;
|
||||
if (!holder->HasFastProperties()) break;
|
||||
// When debugging we need to go the slow path to flood the accessor.
|
||||
if (GetSharedFunctionInfo()->HasDebugInfo()) break;
|
||||
Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
|
||||
if (!receiver->IsJSObject() && !function->shared()->IsBuiltin() &&
|
||||
is_sloppy(function->shared()->language_mode())) {
|
||||
// Calling sloppy non-builtins with a value as the receiver
|
||||
// requires boxing.
|
||||
break;
|
||||
}
|
||||
CallOptimization call_optimization(function);
|
||||
NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
|
||||
if (call_optimization.is_simple_api_call()) {
|
||||
if (call_optimization.IsCompatibleReceiver(receiver, holder)) {
|
||||
return compiler.CompileLoadCallback(
|
||||
lookup->name(), call_optimization, lookup->GetAccessorIndex());
|
||||
}
|
||||
int expected_arguments = Handle<JSFunction>::cast(getter)
|
||||
->shared()
|
||||
->internal_formal_parameter_count();
|
||||
return compiler.CompileLoadViaGetter(
|
||||
lookup->name(), lookup->GetAccessorIndex(), expected_arguments);
|
||||
} else if (accessors->IsAccessorInfo()) {
|
||||
Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
|
||||
if (v8::ToCData<Address>(info->getter()) == 0) break;
|
||||
if (!AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map)) {
|
||||
} else {
|
||||
// This case should be already handled in LoadIC::UpdateCaches.
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
if (!holder->HasFastProperties()) break;
|
||||
NamedLoadHandlerCompiler compiler(isolate(), map, holder,
|
||||
cache_holder);
|
||||
return compiler.CompileLoadCallback(lookup->name(), info);
|
||||
}
|
||||
int expected_arguments =
|
||||
function->shared()->internal_formal_parameter_count();
|
||||
return compiler.CompileLoadViaGetter(
|
||||
lookup->name(), lookup->GetAccessorIndex(), expected_arguments);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -279,16 +279,9 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
call_data_undefined = true;
|
||||
__ LoadRoot(data, Heap::kUndefinedValueRootIndex);
|
||||
} else {
|
||||
if (optimization.is_constant_call()) {
|
||||
__ lw(data,
|
||||
FieldMemOperand(callee, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ lw(data,
|
||||
FieldMemOperand(data, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ lw(data, FieldMemOperand(data, FunctionTemplateInfo::kCallCodeOffset));
|
||||
} else {
|
||||
__ lw(data,
|
||||
FieldMemOperand(callee, FunctionTemplateInfo::kCallCodeOffset));
|
||||
}
|
||||
__ lw(data, FieldMemOperand(callee, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ lw(data, FieldMemOperand(data, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ lw(data, FieldMemOperand(data, FunctionTemplateInfo::kCallCodeOffset));
|
||||
__ lw(data, FieldMemOperand(data, CallHandlerInfo::kDataOffset));
|
||||
}
|
||||
|
||||
@ -306,8 +299,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
__ li(api_function_address, Operand(ref));
|
||||
|
||||
// Jump to stub.
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined);
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
||||
|
@ -279,16 +279,9 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
call_data_undefined = true;
|
||||
__ LoadRoot(data, Heap::kUndefinedValueRootIndex);
|
||||
} else {
|
||||
if (optimization.is_constant_call()) {
|
||||
__ ld(data,
|
||||
FieldMemOperand(callee, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ ld(data,
|
||||
FieldMemOperand(data, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ ld(data, FieldMemOperand(data, FunctionTemplateInfo::kCallCodeOffset));
|
||||
} else {
|
||||
__ ld(data,
|
||||
FieldMemOperand(callee, FunctionTemplateInfo::kCallCodeOffset));
|
||||
}
|
||||
__ ld(data, FieldMemOperand(callee, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ ld(data, FieldMemOperand(data, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ ld(data, FieldMemOperand(data, FunctionTemplateInfo::kCallCodeOffset));
|
||||
__ ld(data, FieldMemOperand(data, CallHandlerInfo::kDataOffset));
|
||||
}
|
||||
|
||||
@ -306,8 +299,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
__ li(api_function_address, Operand(ref));
|
||||
|
||||
// Jump to stub.
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined);
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
||||
|
@ -284,17 +284,12 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
call_data_undefined = true;
|
||||
__ LoadRoot(data, Heap::kUndefinedValueRootIndex);
|
||||
} else {
|
||||
if (optimization.is_constant_call()) {
|
||||
__ LoadP(data,
|
||||
FieldMemOperand(callee, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ LoadP(data,
|
||||
FieldMemOperand(data, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ LoadP(data,
|
||||
FieldMemOperand(data, FunctionTemplateInfo::kCallCodeOffset));
|
||||
} else {
|
||||
__ LoadP(data,
|
||||
FieldMemOperand(callee, FunctionTemplateInfo::kCallCodeOffset));
|
||||
}
|
||||
__ LoadP(data,
|
||||
FieldMemOperand(callee, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ LoadP(data,
|
||||
FieldMemOperand(data, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ LoadP(data,
|
||||
FieldMemOperand(data, FunctionTemplateInfo::kCallCodeOffset));
|
||||
__ LoadP(data, FieldMemOperand(data, CallHandlerInfo::kDataOffset));
|
||||
}
|
||||
|
||||
@ -313,8 +308,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
__ mov(api_function_address, Operand(ref));
|
||||
|
||||
// Jump to stub.
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined);
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
||||
|
@ -181,16 +181,9 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
call_data_undefined = true;
|
||||
__ LoadRoot(data, Heap::kUndefinedValueRootIndex);
|
||||
} else {
|
||||
if (optimization.is_constant_call()) {
|
||||
__ movp(data,
|
||||
FieldOperand(callee, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ movp(data,
|
||||
FieldOperand(data, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ movp(data, FieldOperand(data, FunctionTemplateInfo::kCallCodeOffset));
|
||||
} else {
|
||||
__ movp(data,
|
||||
FieldOperand(callee, FunctionTemplateInfo::kCallCodeOffset));
|
||||
}
|
||||
__ movp(data, FieldOperand(callee, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ movp(data, FieldOperand(data, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ movp(data, FieldOperand(data, FunctionTemplateInfo::kCallCodeOffset));
|
||||
__ movp(data, FieldOperand(data, CallHandlerInfo::kDataOffset));
|
||||
}
|
||||
|
||||
@ -207,8 +200,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
RelocInfo::EXTERNAL_REFERENCE);
|
||||
|
||||
// Jump to stub.
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined);
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
||||
|
@ -197,13 +197,9 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
call_data_undefined = true;
|
||||
__ mov(data, Immediate(isolate->factory()->undefined_value()));
|
||||
} else {
|
||||
if (optimization.is_constant_call()) {
|
||||
__ mov(data, FieldOperand(callee, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ mov(data, FieldOperand(data, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ mov(data, FieldOperand(data, FunctionTemplateInfo::kCallCodeOffset));
|
||||
} else {
|
||||
__ mov(data, FieldOperand(callee, FunctionTemplateInfo::kCallCodeOffset));
|
||||
}
|
||||
__ mov(data, FieldOperand(callee, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ mov(data, FieldOperand(data, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ mov(data, FieldOperand(data, FunctionTemplateInfo::kCallCodeOffset));
|
||||
__ mov(data, FieldOperand(data, CallHandlerInfo::kDataOffset));
|
||||
}
|
||||
|
||||
@ -218,8 +214,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
__ mov(api_function_address, Immediate(function_address));
|
||||
|
||||
// Jump to stub.
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined);
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
||||
|
@ -5557,10 +5557,11 @@ static void CallApiFunctionAndReturn(
|
||||
__ jmp(&leave_exit_frame);
|
||||
}
|
||||
|
||||
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
bool call_data_undefined) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- a0 : callee
|
||||
// -- t0 : call_data
|
||||
@ -5596,10 +5597,8 @@ static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
|
||||
// Save context, callee and call data.
|
||||
__ Push(context, callee, call_data);
|
||||
if (!is_lazy) {
|
||||
// Load context from callee.
|
||||
__ lw(context, FieldMemOperand(callee, JSFunction::kContextOffset));
|
||||
}
|
||||
// Load context from callee.
|
||||
__ lw(context, FieldMemOperand(callee, JSFunction::kContextOffset));
|
||||
|
||||
Register scratch = call_data;
|
||||
if (!call_data_undefined) {
|
||||
@ -5680,7 +5679,7 @@ static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(a3), false,
|
||||
call_data_undefined, false);
|
||||
call_data_undefined);
|
||||
}
|
||||
|
||||
|
||||
@ -5688,9 +5687,8 @@ void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
call_data_undefined);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5578,10 +5578,11 @@ static void CallApiFunctionAndReturn(
|
||||
__ jmp(&leave_exit_frame);
|
||||
}
|
||||
|
||||
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
bool call_data_undefined) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- a0 : callee
|
||||
// -- a4 : call_data
|
||||
@ -5617,10 +5618,8 @@ static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
|
||||
// Save context, callee and call data.
|
||||
__ Push(context, callee, call_data);
|
||||
if (!is_lazy) {
|
||||
// Load context from callee.
|
||||
__ ld(context, FieldMemOperand(callee, JSFunction::kContextOffset));
|
||||
}
|
||||
// Load context from callee.
|
||||
__ ld(context, FieldMemOperand(callee, JSFunction::kContextOffset));
|
||||
|
||||
Register scratch = call_data;
|
||||
if (!call_data_undefined) {
|
||||
@ -5705,7 +5704,7 @@ static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(a3), false,
|
||||
call_data_undefined, false);
|
||||
call_data_undefined);
|
||||
}
|
||||
|
||||
|
||||
@ -5713,9 +5712,8 @@ void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
call_data_undefined);
|
||||
}
|
||||
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "src/accessors.h"
|
||||
#include "src/allocation-site-scopes.h"
|
||||
#include "src/api.h"
|
||||
#include "src/api-natives.h"
|
||||
#include "src/arguments.h"
|
||||
#include "src/base/bits.h"
|
||||
#include "src/base/utils/random-number-generator.h"
|
||||
@ -1176,18 +1175,7 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(
|
||||
|
||||
// Regular accessor.
|
||||
Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate);
|
||||
if (getter->IsFunctionTemplateInfo()) {
|
||||
auto result = Builtins::InvokeApiFunction(
|
||||
Handle<FunctionTemplateInfo>::cast(getter), receiver, 0, nullptr);
|
||||
if (isolate->has_pending_exception()) {
|
||||
return MaybeHandle<Object>();
|
||||
}
|
||||
Handle<Object> return_value;
|
||||
if (result.ToHandle(&return_value)) {
|
||||
return_value->VerifyApiCallResultType();
|
||||
return handle(*return_value, isolate);
|
||||
}
|
||||
} else if (getter->IsCallable()) {
|
||||
if (getter->IsCallable()) {
|
||||
// TODO(rossberg): nicer would be to cast to some JSCallable here...
|
||||
return Object::GetPropertyWithDefinedGetter(
|
||||
receiver, Handle<JSReceiver>::cast(getter));
|
||||
@ -1245,16 +1233,7 @@ Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it,
|
||||
|
||||
// Regular accessor.
|
||||
Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
|
||||
if (setter->IsFunctionTemplateInfo()) {
|
||||
Handle<Object> argv[] = {value};
|
||||
auto result =
|
||||
Builtins::InvokeApiFunction(Handle<FunctionTemplateInfo>::cast(setter),
|
||||
receiver, arraysize(argv), argv);
|
||||
if (isolate->has_pending_exception()) {
|
||||
return Nothing<bool>();
|
||||
}
|
||||
return Just(true);
|
||||
} else if (setter->IsCallable()) {
|
||||
if (setter->IsCallable()) {
|
||||
// TODO(rossberg): nicer would be to cast to some JSCallable here...
|
||||
return SetPropertyWithDefinedSetter(
|
||||
receiver, Handle<JSReceiver>::cast(setter), value, should_throw);
|
||||
@ -9086,10 +9065,8 @@ MaybeHandle<Object> JSObject::DefineAccessor(LookupIterator* it,
|
||||
}
|
||||
}
|
||||
|
||||
DCHECK(getter->IsCallable() || getter->IsUndefined() || getter->IsNull() ||
|
||||
getter->IsFunctionTemplateInfo());
|
||||
DCHECK(setter->IsCallable() || setter->IsUndefined() || setter->IsNull() ||
|
||||
getter->IsFunctionTemplateInfo());
|
||||
DCHECK(getter->IsCallable() || getter->IsUndefined() || getter->IsNull());
|
||||
DCHECK(setter->IsCallable() || setter->IsUndefined() || setter->IsNull());
|
||||
// At least one of the accessors needs to be a new value.
|
||||
DCHECK(!getter->IsNull() || !setter->IsNull());
|
||||
if (!getter->IsNull()) {
|
||||
@ -11004,14 +10981,10 @@ Handle<AccessorPair> AccessorPair::Copy(Handle<AccessorPair> pair) {
|
||||
|
||||
Object* AccessorPair::GetComponent(AccessorComponent component) {
|
||||
Object* accessor = get(component);
|
||||
if (accessor->IsFunctionTemplateInfo()) {
|
||||
return *ApiNatives::InstantiateFunction(
|
||||
handle(FunctionTemplateInfo::cast(accessor)))
|
||||
.ToHandleChecked();
|
||||
}
|
||||
return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor;
|
||||
}
|
||||
|
||||
|
||||
Handle<DeoptimizationInputData> DeoptimizationInputData::New(
|
||||
Isolate* isolate, int deopt_entry_count, PretenureFlag pretenure) {
|
||||
return Handle<DeoptimizationInputData>::cast(
|
||||
|
@ -5459,10 +5459,11 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
|
||||
__ b(&leave_exit_frame);
|
||||
}
|
||||
|
||||
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
bool call_data_undefined) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r3 : callee
|
||||
// -- r7 : call_data
|
||||
@ -5498,10 +5499,8 @@ static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
|
||||
// context save
|
||||
__ push(context);
|
||||
if (!is_lazy) {
|
||||
// load context from callee
|
||||
__ LoadP(context, FieldMemOperand(callee, JSFunction::kContextOffset));
|
||||
}
|
||||
// load context from callee
|
||||
__ LoadP(context, FieldMemOperand(callee, JSFunction::kContextOffset));
|
||||
|
||||
// callee
|
||||
__ push(callee);
|
||||
@ -5600,7 +5599,7 @@ static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(r6), false,
|
||||
call_data_undefined, false);
|
||||
call_data_undefined);
|
||||
}
|
||||
|
||||
|
||||
@ -5608,9 +5607,8 @@ void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
call_data_undefined);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5365,10 +5365,11 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
|
||||
__ jmp(&leave_exit_frame);
|
||||
}
|
||||
|
||||
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
bool call_data_undefined) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- rdi : callee
|
||||
// -- rbx : call_data
|
||||
@ -5431,10 +5432,8 @@ static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
// Push return address back on stack.
|
||||
__ PushReturnAddressFrom(return_address);
|
||||
|
||||
if (!is_lazy) {
|
||||
// load context from callee
|
||||
__ movp(context, FieldOperand(callee, JSFunction::kContextOffset));
|
||||
}
|
||||
// load context from callee
|
||||
__ movp(context, FieldOperand(callee, JSFunction::kContextOffset));
|
||||
|
||||
// Allocate the v8::Arguments structure in the arguments' space since
|
||||
// it's not controlled by GC.
|
||||
@ -5507,7 +5506,7 @@ static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(rax), false,
|
||||
call_data_undefined, false);
|
||||
call_data_undefined);
|
||||
}
|
||||
|
||||
|
||||
@ -5515,9 +5514,8 @@ void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
call_data_undefined);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5210,10 +5210,11 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
|
||||
__ jmp(&leave_exit_frame);
|
||||
}
|
||||
|
||||
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
bool call_data_undefined) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- edi : callee
|
||||
// -- ebx : call_data
|
||||
@ -5287,10 +5288,8 @@ static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
// push return address
|
||||
__ push(return_address);
|
||||
|
||||
if (!is_lazy) {
|
||||
// load context from callee
|
||||
__ mov(context, FieldOperand(callee, JSFunction::kContextOffset));
|
||||
}
|
||||
// load context from callee
|
||||
__ mov(context, FieldOperand(callee, JSFunction::kContextOffset));
|
||||
|
||||
// API function gets reference to the v8::Arguments. If CPU profiler
|
||||
// is enabled wrapper function will be called and we need to pass
|
||||
@ -5362,7 +5361,7 @@ static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(eax), false,
|
||||
call_data_undefined, false);
|
||||
call_data_undefined);
|
||||
}
|
||||
|
||||
|
||||
@ -5370,9 +5369,8 @@ void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
call_data_undefined);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user