[fastcall] Store multiple CFunction overloads in FunctionTemplateInfo
In order to support Fast API calls with overloads, store a FixedArray of c-function addresses and a FixedArray of the corresponding FunctionInfo*. For now keep using only the first function in the array. Bug: v8:11739 Change-Id: If23381aa9d04c5cd830043951da9c53836a36328 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2876592 Reviewed-by: Camillo Bruni <cbruni@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Maya Lekova <mslekova@chromium.org> Commit-Queue: Paolo Severini <paolosev@microsoft.com> Cr-Commit-Position: refs/heads/master@{#74643}
This commit is contained in:
parent
26ee13b4f0
commit
ad4eab00e7
@ -6506,7 +6506,7 @@ class V8_EXPORT FunctionTemplate : public Template {
|
||||
Local<Signature> signature = Local<Signature>(), int length = 0,
|
||||
ConstructorBehavior behavior = ConstructorBehavior::kAllow,
|
||||
SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
|
||||
const std::vector<const CFunction*>& c_function_overloads = {});
|
||||
const MemorySpan<const CFunction>& c_function_overloads = {});
|
||||
|
||||
/**
|
||||
* Creates a function template backed/cached by a private property.
|
||||
@ -6539,7 +6539,7 @@ class V8_EXPORT FunctionTemplate : public Template {
|
||||
void SetCallHandler(
|
||||
FunctionCallback callback, Local<Value> data = Local<Value>(),
|
||||
SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
|
||||
const std::vector<const CFunction*>& c_function_overloads = {});
|
||||
const MemorySpan<const CFunction>& c_function_overloads = {});
|
||||
|
||||
/** Set the predefined length property for the FunctionTemplate. */
|
||||
void SetLength(int length);
|
||||
|
@ -1218,7 +1218,7 @@ static Local<FunctionTemplate> FunctionTemplateNew(
|
||||
bool do_not_cache,
|
||||
v8::Local<Private> cached_property_name = v8::Local<Private>(),
|
||||
SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
|
||||
const std::vector<const CFunction*>& c_function_overloads = {}) {
|
||||
const MemorySpan<const CFunction>& c_function_overloads = {}) {
|
||||
i::Handle<i::Struct> struct_obj = isolate->factory()->NewStruct(
|
||||
i::FUNCTION_TEMPLATE_INFO_TYPE, i::AllocationType::kOld);
|
||||
i::Handle<i::FunctionTemplateInfo> obj =
|
||||
@ -1260,20 +1260,15 @@ Local<FunctionTemplate> FunctionTemplate::New(
|
||||
return FunctionTemplateNew(
|
||||
i_isolate, callback, data, signature, length, behavior, false,
|
||||
Local<Private>(), side_effect_type,
|
||||
c_function ? std::vector<const CFunction*>{c_function}
|
||||
: std::vector<const CFunction*>{});
|
||||
c_function ? MemorySpan<const CFunction>{c_function, 1}
|
||||
: MemorySpan<const CFunction>{});
|
||||
}
|
||||
|
||||
Local<FunctionTemplate> FunctionTemplate::NewWithCFunctionOverloads(
|
||||
Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
|
||||
v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
|
||||
SideEffectType side_effect_type,
|
||||
const std::vector<const CFunction*>& c_function_overloads) {
|
||||
// Multiple overloads not supported yet.
|
||||
Utils::ApiCheck(c_function_overloads.size() == 1,
|
||||
"v8::FunctionTemplate::NewWithCFunctionOverloads",
|
||||
"Function overloads not supported yet.");
|
||||
|
||||
const MemorySpan<const CFunction>& c_function_overloads) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
LOG_API(i_isolate, FunctionTemplate, New);
|
||||
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
|
||||
@ -1313,7 +1308,7 @@ Local<AccessorSignature> AccessorSignature::New(
|
||||
void FunctionTemplate::SetCallHandler(
|
||||
FunctionCallback callback, v8::Local<Value> data,
|
||||
SideEffectType side_effect_type,
|
||||
const std::vector<const CFunction*>& c_function_overloads) {
|
||||
const MemorySpan<const CFunction>& c_function_overloads) {
|
||||
auto info = Utils::OpenHandle(this);
|
||||
EnsureNotPublished(info, "v8::FunctionTemplate::SetCallHandler");
|
||||
i::Isolate* isolate = info->GetIsolate();
|
||||
@ -1327,22 +1322,28 @@ void FunctionTemplate::SetCallHandler(
|
||||
data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
|
||||
}
|
||||
obj->set_data(*Utils::OpenHandle(*data));
|
||||
// Blink passes CFunction's constructed with the default constructor
|
||||
// for non-fast calls, so we should check the address too.
|
||||
if (!c_function_overloads.empty()) {
|
||||
// Multiple overloads not supported yet.
|
||||
Utils::ApiCheck(c_function_overloads.size() == 1,
|
||||
"v8::FunctionTemplate::SetCallHandler",
|
||||
"Function overloads not supported yet.");
|
||||
const CFunction* c_function = c_function_overloads[0];
|
||||
if (c_function != nullptr && c_function->GetAddress()) {
|
||||
i::FunctionTemplateInfo::SetCFunction(
|
||||
isolate, info,
|
||||
i::handle(*FromCData(isolate, c_function->GetAddress()), isolate));
|
||||
i::FunctionTemplateInfo::SetCSignature(
|
||||
isolate, info,
|
||||
i::handle(*FromCData(isolate, c_function->GetTypeInfo()), isolate));
|
||||
if (c_function_overloads.size() > 0) {
|
||||
// Stores the data for a sequence of CFunction overloads into a single
|
||||
// FixedArray, as [address_0, signature_0, ... address_n-1, signature_n-1].
|
||||
i::Handle<i::FixedArray> function_overloads =
|
||||
isolate->factory()->NewFixedArray(static_cast<int>(
|
||||
c_function_overloads.size() *
|
||||
i::FunctionTemplateInfo::kFunctionOverloadEntrySize));
|
||||
int function_count = static_cast<int>(c_function_overloads.size());
|
||||
for (int i = 0; i < function_count; i++) {
|
||||
const CFunction& c_function = c_function_overloads.data()[i];
|
||||
i::Handle<i::Object> address =
|
||||
FromCData(isolate, c_function.GetAddress());
|
||||
function_overloads->set(
|
||||
i::FunctionTemplateInfo::kFunctionOverloadEntrySize * i, *address);
|
||||
i::Handle<i::Object> signature =
|
||||
FromCData(isolate, c_function.GetTypeInfo());
|
||||
function_overloads->set(
|
||||
i::FunctionTemplateInfo::kFunctionOverloadEntrySize * i + 1,
|
||||
*signature);
|
||||
}
|
||||
i::FunctionTemplateInfo::SetCFunctionOverloads(isolate, info,
|
||||
function_overloads);
|
||||
}
|
||||
info->set_call_code(*obj, kReleaseStore);
|
||||
}
|
||||
|
@ -234,8 +234,10 @@ class FunctionTemplateInfoData : public HeapObjectData {
|
||||
|
||||
void SerializeCallCode(JSHeapBroker* broker);
|
||||
ObjectData* call_code() const { return call_code_; }
|
||||
Address c_function() const { return c_function_; }
|
||||
const CFunctionInfo* c_signature() const { return c_signature_; }
|
||||
ZoneVector<Address> c_functions() const { return c_functions_; }
|
||||
ZoneVector<const CFunctionInfo*> c_signatures() const {
|
||||
return c_signatures_;
|
||||
}
|
||||
KnownReceiversMap& known_receivers() { return known_receivers_; }
|
||||
|
||||
private:
|
||||
@ -244,8 +246,8 @@ class FunctionTemplateInfoData : public HeapObjectData {
|
||||
bool has_call_code_ = false;
|
||||
|
||||
ObjectData* call_code_ = nullptr;
|
||||
const Address c_function_;
|
||||
const CFunctionInfo* const c_signature_;
|
||||
ZoneVector<Address> c_functions_;
|
||||
ZoneVector<const CFunctionInfo*> c_signatures_;
|
||||
KnownReceiversMap known_receivers_;
|
||||
};
|
||||
|
||||
@ -265,15 +267,50 @@ class CallHandlerInfoData : public HeapObjectData {
|
||||
ObjectData* data_ = nullptr;
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
ZoneVector<Address> GetCFunctions(FixedArray function_overloads, Zone* zone) {
|
||||
const int len = function_overloads.length() /
|
||||
FunctionTemplateInfo::kFunctionOverloadEntrySize;
|
||||
ZoneVector<Address> c_functions = ZoneVector<Address>(len, zone);
|
||||
for (int i = 0; i < len; i++) {
|
||||
c_functions[i] = v8::ToCData<Address>(function_overloads.get(
|
||||
FunctionTemplateInfo::kFunctionOverloadEntrySize * i));
|
||||
}
|
||||
return c_functions;
|
||||
}
|
||||
|
||||
ZoneVector<const CFunctionInfo*> GetCSignatures(FixedArray function_overloads,
|
||||
Zone* zone) {
|
||||
const int len = function_overloads.length() /
|
||||
FunctionTemplateInfo::kFunctionOverloadEntrySize;
|
||||
ZoneVector<const CFunctionInfo*> c_signatures =
|
||||
ZoneVector<const CFunctionInfo*>(len, zone);
|
||||
for (int i = 0; i < len; i++) {
|
||||
c_signatures[i] = v8::ToCData<const CFunctionInfo*>(function_overloads.get(
|
||||
FunctionTemplateInfo::kFunctionOverloadEntrySize * i + 1));
|
||||
}
|
||||
return c_signatures;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FunctionTemplateInfoData::FunctionTemplateInfoData(
|
||||
JSHeapBroker* broker, ObjectData** storage,
|
||||
Handle<FunctionTemplateInfo> object)
|
||||
: HeapObjectData(broker, storage, object),
|
||||
c_function_(v8::ToCData<Address>(object->GetCFunction())),
|
||||
c_signature_(v8::ToCData<CFunctionInfo*>(object->GetCSignature())),
|
||||
c_functions_(broker->zone()),
|
||||
c_signatures_(broker->zone()),
|
||||
known_receivers_(broker->zone()) {
|
||||
DCHECK(!broker->is_concurrent_inlining());
|
||||
|
||||
auto function_template_info = Handle<FunctionTemplateInfo>::cast(object);
|
||||
|
||||
FixedArray function_overloads_array =
|
||||
FixedArray::cast(function_template_info->GetCFunctionOverloads());
|
||||
c_functions_ = GetCFunctions(function_overloads_array, broker->zone());
|
||||
c_signatures_ = GetCSignatures(function_overloads_array, broker->zone());
|
||||
|
||||
is_signature_undefined_ =
|
||||
function_template_info->signature().IsUndefined(broker->isolate());
|
||||
accept_any_receiver_ = function_template_info->accept_any_receiver();
|
||||
@ -3693,18 +3730,20 @@ Address CallHandlerInfoRef::callback() const {
|
||||
return HeapObjectRef::data()->AsCallHandlerInfo()->callback();
|
||||
}
|
||||
|
||||
Address FunctionTemplateInfoRef::c_function() const {
|
||||
ZoneVector<Address> FunctionTemplateInfoRef::c_functions() const {
|
||||
if (data_->should_access_heap()) {
|
||||
return v8::ToCData<Address>(object()->GetCFunction());
|
||||
return GetCFunctions(FixedArray::cast(object()->GetCFunctionOverloads()),
|
||||
broker()->zone());
|
||||
}
|
||||
return HeapObjectRef::data()->AsFunctionTemplateInfo()->c_function();
|
||||
return HeapObjectRef::data()->AsFunctionTemplateInfo()->c_functions();
|
||||
}
|
||||
|
||||
const CFunctionInfo* FunctionTemplateInfoRef::c_signature() const {
|
||||
ZoneVector<const CFunctionInfo*> FunctionTemplateInfoRef::c_signatures() const {
|
||||
if (data_->should_access_heap()) {
|
||||
return v8::ToCData<CFunctionInfo*>(object()->GetCSignature());
|
||||
return GetCSignatures(FixedArray::cast(object()->GetCFunctionOverloads()),
|
||||
broker()->zone());
|
||||
}
|
||||
return HeapObjectRef::data()->AsFunctionTemplateInfo()->c_signature();
|
||||
return HeapObjectRef::data()->AsFunctionTemplateInfo()->c_signatures();
|
||||
}
|
||||
|
||||
bool StringRef::IsSeqString() const {
|
||||
|
@ -738,8 +738,8 @@ class FunctionTemplateInfoRef : public HeapObjectRef {
|
||||
|
||||
void SerializeCallCode();
|
||||
base::Optional<CallHandlerInfoRef> call_code() const;
|
||||
Address c_function() const;
|
||||
const CFunctionInfo* c_signature() const;
|
||||
ZoneVector<Address> c_functions() const;
|
||||
ZoneVector<const CFunctionInfo*> c_signatures() const;
|
||||
|
||||
HolderLookupResult LookupHolderOfExpectedType(
|
||||
MapRef receiver_map,
|
||||
|
@ -890,8 +890,8 @@ class FastApiCallReducerAssembler : public JSCallReducerAssembler {
|
||||
Node* holder, const SharedFunctionInfoRef shared, Node* target,
|
||||
const int arity, Node* effect)
|
||||
: JSCallReducerAssembler(reducer, node),
|
||||
c_function_(function_template_info.c_function()),
|
||||
c_signature_(function_template_info.c_signature()),
|
||||
c_functions_(function_template_info.c_functions()),
|
||||
c_signatures_(function_template_info.c_signatures()),
|
||||
function_template_info_(function_template_info),
|
||||
receiver_(receiver),
|
||||
holder_(holder),
|
||||
@ -899,8 +899,8 @@ class FastApiCallReducerAssembler : public JSCallReducerAssembler {
|
||||
target_(target),
|
||||
arity_(arity) {
|
||||
DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
|
||||
DCHECK_NE(c_function_, kNullAddress);
|
||||
CHECK_NOT_NULL(c_signature_);
|
||||
CHECK_GT(c_functions_.size(), 0);
|
||||
CHECK_GT(c_signatures_.size(), 0);
|
||||
InitializeEffectControl(effect, NodeProperties::GetControlInput(node));
|
||||
}
|
||||
|
||||
@ -909,13 +909,16 @@ class FastApiCallReducerAssembler : public JSCallReducerAssembler {
|
||||
// C arguments include the receiver at index 0. Thus C index 1 corresponds
|
||||
// to the JS argument 0, etc.
|
||||
const int c_argument_count =
|
||||
static_cast<int>(c_signature_->ArgumentCount());
|
||||
static_cast<int>(c_signatures_[0]->ArgumentCount());
|
||||
CHECK_GE(c_argument_count, kReceiver);
|
||||
|
||||
int cursor = 0;
|
||||
base::SmallVector<Node*, kInlineSize> inputs(c_argument_count + arity_ +
|
||||
kExtraInputsCount);
|
||||
inputs[cursor++] = ExternalConstant(ExternalReference::Create(c_function_));
|
||||
// Multiple function overloads not supported yet, always call the first
|
||||
// overload.
|
||||
inputs[cursor++] =
|
||||
ExternalConstant(ExternalReference::Create(c_functions_[0]));
|
||||
|
||||
inputs[cursor++] = n.receiver();
|
||||
|
||||
@ -987,12 +990,12 @@ class FastApiCallReducerAssembler : public JSCallReducerAssembler {
|
||||
TNode<Object> FastApiCall(CallDescriptor* descriptor, Node** inputs,
|
||||
size_t inputs_size) {
|
||||
return AddNode<Object>(graph()->NewNode(
|
||||
simplified()->FastApiCall(c_signature_, feedback(), descriptor),
|
||||
simplified()->FastApiCall(c_signatures_[0], feedback(), descriptor),
|
||||
static_cast<int>(inputs_size), inputs));
|
||||
}
|
||||
|
||||
const Address c_function_;
|
||||
const CFunctionInfo* const c_signature_;
|
||||
const ZoneVector<Address> c_functions_;
|
||||
const ZoneVector<const CFunctionInfo*> c_signatures_;
|
||||
const FunctionTemplateInfoRef function_template_info_;
|
||||
Node* const receiver_;
|
||||
Node* const holder_;
|
||||
@ -3539,11 +3542,13 @@ bool Has64BitIntegerParamsInSignature(const CFunctionInfo* c_signature) {
|
||||
|
||||
bool CanOptimizeFastCall(
|
||||
const FunctionTemplateInfoRef& function_template_info) {
|
||||
const CFunctionInfo* c_signature = function_template_info.c_signature();
|
||||
if (function_template_info.c_functions().empty()) return false;
|
||||
|
||||
bool optimize_to_fast_call =
|
||||
FLAG_turbo_fast_api_calls &&
|
||||
function_template_info.c_function() != kNullAddress;
|
||||
// Multiple function overloads not supported yet, always call the first
|
||||
// overload.
|
||||
const CFunctionInfo* c_signature = function_template_info.c_signatures()[0];
|
||||
|
||||
bool optimize_to_fast_call = FLAG_turbo_fast_api_calls;
|
||||
#ifndef V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
|
||||
optimize_to_fast_call =
|
||||
optimize_to_fast_call && !HasFPParamsInSignature(c_signature);
|
||||
|
@ -55,6 +55,14 @@ class FastCApiObject {
|
||||
static_cast<double>(arg_i64) + static_cast<double>(arg_u64) +
|
||||
static_cast<double>(arg_f32) + arg_f64;
|
||||
}
|
||||
static double AddAllFastCallback_5Args(Local<Object> receiver,
|
||||
bool should_fallback, int32_t arg_i32,
|
||||
uint32_t arg_u32, int64_t arg_i64,
|
||||
uint64_t arg_u64, float arg_f32,
|
||||
FastApiCallbackOptions& options) {
|
||||
return AddAllFastCallback(receiver, should_fallback, arg_i32, arg_u32,
|
||||
arg_i64, arg_u64, arg_f32, 0, options);
|
||||
}
|
||||
static void AddAllSlowCallback(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
|
||||
@ -283,12 +291,16 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
|
||||
SideEffectType::kHasSideEffect, &add_all_c_func));
|
||||
|
||||
// To test function overloads.
|
||||
CFunction add_all_5args_c_func =
|
||||
CFunction::Make(FastCApiObject::AddAllFastCallback_5Args);
|
||||
const CFunction c_function_overloads[] = {add_all_c_func,
|
||||
add_all_5args_c_func};
|
||||
api_obj_ctor->PrototypeTemplate()->Set(
|
||||
isolate, "overloaded_add_all",
|
||||
FunctionTemplate::NewWithCFunctionOverloads(
|
||||
isolate, FastCApiObject::AddAllSlowCallback, Local<Value>(),
|
||||
signature, 1, ConstructorBehavior::kThrow,
|
||||
SideEffectType::kHasSideEffect, {&add_all_c_func}));
|
||||
SideEffectType::kHasSideEffect, {c_function_overloads, 2}));
|
||||
|
||||
CFunction add_32bit_int_c_func =
|
||||
CFunction::Make(FastCApiObject::Add32BitIntFastCallback);
|
||||
|
@ -1746,6 +1746,12 @@ void StackFrameInfo::StackFrameInfoVerify(Isolate* isolate) {
|
||||
#endif // V8_ENABLE_WEBASSEMBLY
|
||||
}
|
||||
|
||||
void FunctionTemplateRareData::FunctionTemplateRareDataVerify(
|
||||
Isolate* isolate) {
|
||||
CHECK(c_function_overloads().IsFixedArray() ||
|
||||
c_function_overloads().IsUndefined(isolate));
|
||||
}
|
||||
|
||||
#endif // VERIFY_HEAP
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -897,6 +897,18 @@ Handle<SwissNameDictionary> FactoryBase<Impl>::NewSwissNameDictionary(
|
||||
SwissNameDictionary::CapacityFor(at_least_space_for), allocation);
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
Handle<FunctionTemplateRareData>
|
||||
FactoryBase<Impl>::NewFunctionTemplateRareData() {
|
||||
auto function_template_rare_data =
|
||||
NewStructInternal<FunctionTemplateRareData>(
|
||||
FUNCTION_TEMPLATE_RARE_DATA_TYPE, AllocationType::kOld);
|
||||
DisallowGarbageCollection no_gc;
|
||||
function_template_rare_data.set_c_function_overloads(
|
||||
*impl()->empty_fixed_array(), SKIP_WRITE_BARRIER);
|
||||
return handle(function_template_rare_data, isolate());
|
||||
}
|
||||
|
||||
// Instantiate FactoryBase for the two variants we want.
|
||||
template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) FactoryBase<Factory>;
|
||||
template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
|
@ -228,6 +228,8 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) FactoryBase
|
||||
Handle<SwissNameDictionary> NewSwissNameDictionaryWithCapacity(
|
||||
int capacity, AllocationType allocation);
|
||||
|
||||
Handle<FunctionTemplateRareData> NewFunctionTemplateRareData();
|
||||
|
||||
protected:
|
||||
// Allocate memory for an uninitialized array (e.g., a FixedArray or similar).
|
||||
HeapObject AllocateRawArray(int size, AllocationType allocation);
|
||||
|
@ -2274,9 +2274,10 @@ void ExistingCodeLogger::LogExistingFunction(
|
||||
CALL_CODE_EVENT_HANDLER(CallbackEvent(fun_name, entry_point))
|
||||
|
||||
// Fast API function.
|
||||
Address c_function = v8::ToCData<Address>(fun_data->GetCFunction());
|
||||
if (c_function != kNullAddress) {
|
||||
CALL_CODE_EVENT_HANDLER(CallbackEvent(fun_name, c_function))
|
||||
int c_functions_count = fun_data->GetCFunctionsCount();
|
||||
for (int i = 0; i < c_functions_count; i++) {
|
||||
CALL_CODE_EVENT_HANDLER(
|
||||
CallbackEvent(fun_name, fun_data->GetCFunction(i)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1374,12 +1374,8 @@ bool FunctionTemplateInfo::IsLeafTemplateForApiObject(Object object) const {
|
||||
FunctionTemplateRareData FunctionTemplateInfo::AllocateFunctionTemplateRareData(
|
||||
Isolate* isolate, Handle<FunctionTemplateInfo> function_template_info) {
|
||||
DCHECK(function_template_info->rare_data(kAcquireLoad).IsUndefined(isolate));
|
||||
Handle<Struct> struct_obj = isolate->factory()->NewStruct(
|
||||
FUNCTION_TEMPLATE_RARE_DATA_TYPE, AllocationType::kOld);
|
||||
Handle<FunctionTemplateRareData> rare_data =
|
||||
i::Handle<FunctionTemplateRareData>::cast(struct_obj);
|
||||
rare_data->set_c_function(Smi(0));
|
||||
rare_data->set_c_signature(Smi(0));
|
||||
isolate->factory()->NewFunctionTemplateRareData();
|
||||
function_template_info->set_rare_data(*rare_data, kReleaseStore);
|
||||
return *rare_data;
|
||||
}
|
||||
@ -6661,6 +6657,25 @@ base::Optional<Name> FunctionTemplateInfo::TryGetCachedPropertyName(
|
||||
return Name::cast(maybe_name);
|
||||
}
|
||||
|
||||
int FunctionTemplateInfo::GetCFunctionsCount() const {
|
||||
i::DisallowHeapAllocation no_gc;
|
||||
return FixedArray::cast(GetCFunctionOverloads()).length() /
|
||||
kFunctionOverloadEntrySize;
|
||||
}
|
||||
|
||||
Address FunctionTemplateInfo::GetCFunction(int index) const {
|
||||
i::DisallowHeapAllocation no_gc;
|
||||
return v8::ToCData<Address>(FixedArray::cast(GetCFunctionOverloads())
|
||||
.get(index * kFunctionOverloadEntrySize));
|
||||
}
|
||||
|
||||
const CFunctionInfo* FunctionTemplateInfo::GetCSignature(int index) const {
|
||||
i::DisallowHeapAllocation no_gc;
|
||||
return v8::ToCData<CFunctionInfo*>(
|
||||
FixedArray::cast(GetCFunctionOverloads())
|
||||
.get(index * kFunctionOverloadEntrySize + 1));
|
||||
}
|
||||
|
||||
Address Smi::LexicographicCompare(Isolate* isolate, Smi x, Smi y) {
|
||||
DisallowGarbageCollection no_gc;
|
||||
DisallowJavascriptExecution no_js(isolate);
|
||||
|
@ -76,8 +76,8 @@ RARE_ACCESSORS(instance_template, InstanceTemplate, HeapObject, undefined)
|
||||
RARE_ACCESSORS(instance_call_handler, InstanceCallHandler, HeapObject,
|
||||
undefined)
|
||||
RARE_ACCESSORS(access_check_info, AccessCheckInfo, HeapObject, undefined)
|
||||
RARE_ACCESSORS(c_function, CFunction, Object, Smi(0))
|
||||
RARE_ACCESSORS(c_signature, CSignature, Object, Smi(0))
|
||||
RARE_ACCESSORS(c_function_overloads, CFunctionOverloads, FixedArray,
|
||||
GetReadOnlyRoots(cage_base).empty_fixed_array())
|
||||
#undef RARE_ACCESSORS
|
||||
|
||||
bool TemplateInfo::should_cache() const {
|
||||
|
@ -12,6 +12,9 @@
|
||||
#include "src/objects/object-macros.h"
|
||||
|
||||
namespace v8 {
|
||||
|
||||
class CFunctionInfo;
|
||||
|
||||
namespace internal {
|
||||
|
||||
#include "torque-generated/src/objects/templates-tq.inc"
|
||||
@ -45,6 +48,7 @@ class FunctionTemplateRareData
|
||||
: public TorqueGeneratedFunctionTemplateRareData<FunctionTemplateRareData,
|
||||
Struct> {
|
||||
public:
|
||||
DECL_VERIFIER(FunctionTemplateRareData)
|
||||
TQ_OBJECT_CONSTRUCTORS(FunctionTemplateRareData)
|
||||
};
|
||||
|
||||
@ -93,8 +97,7 @@ class FunctionTemplateInfo
|
||||
|
||||
DECL_RARE_ACCESSORS(access_check_info, AccessCheckInfo, HeapObject)
|
||||
|
||||
DECL_RARE_ACCESSORS(c_function, CFunction, Object)
|
||||
DECL_RARE_ACCESSORS(c_signature, CSignature, Object)
|
||||
DECL_RARE_ACCESSORS(c_function_overloads, CFunctionOverloads, FixedArray)
|
||||
#undef DECL_RARE_ACCESSORS
|
||||
|
||||
// Begin flag bits ---------------------
|
||||
@ -152,6 +155,14 @@ class FunctionTemplateInfo
|
||||
// Helper function for cached accessors.
|
||||
static base::Optional<Name> TryGetCachedPropertyName(Isolate* isolate,
|
||||
Object getter);
|
||||
// Fast API overloads.
|
||||
int GetCFunctionsCount() const;
|
||||
Address GetCFunction(int index) const;
|
||||
const CFunctionInfo* GetCSignature(int index) const;
|
||||
|
||||
// CFunction data for a set of overloads is stored into a FixedArray, as
|
||||
// [address_0, signature_0, ... address_n-1, signature_n-1].
|
||||
static const int kFunctionOverloadEntrySize = 2;
|
||||
|
||||
// Bit position in the flag, from least significant bit position.
|
||||
DEFINE_TORQUE_GENERATED_FUNCTION_TEMPLATE_INFO_FLAGS()
|
||||
|
@ -24,8 +24,7 @@ extern class FunctionTemplateRareData extends Struct {
|
||||
instance_template: ObjectTemplateInfo|Undefined;
|
||||
instance_call_handler: CallHandlerInfo|Undefined;
|
||||
access_check_info: AccessCheckInfo|Undefined;
|
||||
c_function: Foreign|Zero;
|
||||
c_signature: Foreign|Zero;
|
||||
c_function_overloads: FixedArray;
|
||||
}
|
||||
|
||||
bitfield struct FunctionTemplateInfoFlags extends uint31 {
|
||||
|
Loading…
Reference in New Issue
Block a user