Commit 36eedb63 authored by Maya Lekova's avatar Maya Lekova Committed by Commit Bot

[turbofan] Serialize API calls for property access

Bug: v8:7790
Change-Id: I5c98af1745ed765ec060b2fd70006a3bd57d523a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1645317
Commit-Queue: Maya Lekova <mslekova@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62341}
parent 8daf1e6d
......@@ -2895,8 +2895,13 @@ Reduction JSCallReducer::ReduceCallApiFunction(
// TODO(turbofan): Consider introducing a JSCallApiCallback operator for
// this and lower it during JSGenericLowering, and unify this with the
// JSNativeContextSpecialization::InlineApiCall method a bit.
if (!function_template_info.call_code().has_value()) {
TRACE_BROKER_MISSING(broker(), "call code for function template info "
<< function_template_info);
return NoChange();
}
CallHandlerInfoRef call_handler_info =
function_template_info.call_code().AsCallHandlerInfo();
function_template_info.call_code()->AsCallHandlerInfo();
Callable call_api_callback = CodeFactory::CallApiCallback(isolate());
CallInterfaceDescriptor cid = call_api_callback.descriptor();
auto call_descriptor = Linkage::GetStubCallDescriptor(
......
......@@ -130,16 +130,17 @@ class FunctionTemplateInfoData : public HeapObjectData {
FunctionTemplateInfoData(JSHeapBroker* broker, ObjectData** storage,
Handle<FunctionTemplateInfo> object);
void Serialize(JSHeapBroker* broker);
ObjectData* call_code() const { return call_code_; }
bool is_signature_undefined() const { return is_signature_undefined_; }
bool accept_any_receiver() const { return accept_any_receiver_; }
bool has_call_code() const { return has_call_code_; }
void SerializeCallCode(JSHeapBroker* broker);
CallHandlerInfoData* call_code() const { return call_code_; }
KnownReceiversMap& known_receivers() { return known_receivers_; }
private:
bool serialized_ = false;
ObjectData* call_code_ = nullptr;
bool serialized_call_code_ = false;
CallHandlerInfoData* call_code_ = nullptr;
bool is_signature_undefined_ = false;
bool accept_any_receiver_ = false;
bool has_call_code_ = false;
......@@ -203,17 +204,19 @@ void PropertyCellData::Serialize(JSHeapBroker* broker) {
value_ = broker->GetOrCreateData(cell->value());
}
void FunctionTemplateInfoData::Serialize(JSHeapBroker* broker) {
if (serialized_) return;
serialized_ = true;
void FunctionTemplateInfoData::SerializeCallCode(JSHeapBroker* broker) {
if (serialized_call_code_) return;
serialized_call_code_ = true;
TraceScope tracer(broker, this, "FunctionTemplateInfoData::Serialize");
TraceScope tracer(broker, this,
"FunctionTemplateInfoData::SerializeCallCode");
auto function_template_info = Handle<FunctionTemplateInfo>::cast(object());
DCHECK_NULL(call_code_);
call_code_ = broker->GetOrCreateData(function_template_info->call_code());
call_code_ = broker->GetOrCreateData(function_template_info->call_code())
->AsCallHandlerInfo();
if (call_code_->IsCallHandlerInfo()) {
call_code_->AsCallHandlerInfo()->Serialize(broker);
call_code_->Serialize(broker);
}
}
......@@ -2717,7 +2720,16 @@ BROKER_NATIVE_CONTEXT_FIELDS(DEF_NATIVE_CONTEXT_ACCESSOR)
BIMODAL_ACCESSOR(PropertyCell, Object, value)
BIMODAL_ACCESSOR_C(PropertyCell, PropertyDetails, property_details)
BIMODAL_ACCESSOR(FunctionTemplateInfo, Object, call_code)
base::Optional<CallHandlerInfoRef> FunctionTemplateInfoRef::call_code() const {
if (broker()->mode() == JSHeapBroker::kDisabled) {
return CallHandlerInfoRef(
broker(), handle(object()->call_code(), broker()->isolate()));
}
CallHandlerInfoData* call_code =
data()->AsFunctionTemplateInfo()->call_code();
if (!call_code) return base::nullopt;
return CallHandlerInfoRef(broker(), call_code);
}
bool FunctionTemplateInfoRef::is_signature_undefined() const {
if (broker()->mode() == JSHeapBroker::kDisabled) {
......@@ -3413,10 +3425,10 @@ void PropertyCellRef::Serialize() {
data()->AsPropertyCell()->Serialize(broker());
}
void FunctionTemplateInfoRef::Serialize() {
void FunctionTemplateInfoRef::SerializeCallCode() {
if (broker()->mode() == JSHeapBroker::kDisabled) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsFunctionTemplateInfo()->Serialize(broker());
data()->AsFunctionTemplateInfo()->SerializeCallCode(broker());
}
base::Optional<PropertyCellRef> JSGlobalProxyRef::GetPropertyCell(
......
......@@ -554,12 +554,14 @@ class FunctionTemplateInfoRef : public HeapObjectRef {
using HeapObjectRef::HeapObjectRef;
Handle<FunctionTemplateInfo> object() const;
void Serialize();
ObjectRef call_code() const;
bool is_signature_undefined() const;
bool accept_any_receiver() const;
// The following returns true if the CallHandlerInfo is present.
bool has_call_code() const;
void SerializeCallCode();
base::Optional<CallHandlerInfoRef> call_code() const;
HolderLookupResult LookupHolderOfExpectedType(MapRef receiver_map,
bool serialize);
};
......
......@@ -1969,14 +1969,6 @@ Node* JSNativeContextSpecialization::InlinePropertyGetterCall(
ConvertReceiverMode::kNotNullOrUndefined),
target, receiver, context, frame_state, *effect, *control);
} else {
auto function_template_info = constant.AsFunctionTemplateInfo();
{ // TODO(mslekova): Move this to the serialization of property loads.
AllowCodeDependencyChange dependency_change_;
AllowHandleAllocation handle_allocation_;
AllowHandleDereference handle_dereference_;
AllowHeapAllocation heap_allocation_;
function_template_info.Serialize();
}
Node* holder = access_info.holder().is_null()
? receiver
: jsgraph()->Constant(ObjectRef(
......@@ -1984,8 +1976,9 @@ Node* JSNativeContextSpecialization::InlinePropertyGetterCall(
SharedFunctionInfoRef shared_info(
broker(), frame_info.shared_info().ToHandleChecked());
value = InlineApiCall(receiver, holder, frame_state, nullptr, effect,
control, shared_info, function_template_info);
value =
InlineApiCall(receiver, holder, frame_state, nullptr, effect, control,
shared_info, constant.AsFunctionTemplateInfo());
}
// Remember to rewire the IfException edge if this is inside a try-block.
if (if_exceptions != nullptr) {
......@@ -2013,15 +2006,6 @@ void JSNativeContextSpecialization::InlinePropertySetterCall(
ConvertReceiverMode::kNotNullOrUndefined),
target, receiver, value, context, frame_state, *effect, *control);
} else {
// TODO(mslekova): Move this to the serialization of property stores.
auto function_template_info = constant.AsFunctionTemplateInfo();
{ // TODO(mslekova): Remove this Serialize call.
AllowCodeDependencyChange dependency_change_;
AllowHandleAllocation handle_allocation_;
AllowHandleDereference handle_dereference_;
AllowHeapAllocation heap_allocation_;
function_template_info.Serialize();
}
Node* holder = access_info.holder().is_null()
? receiver
: jsgraph()->Constant(ObjectRef(
......@@ -2029,7 +2013,7 @@ void JSNativeContextSpecialization::InlinePropertySetterCall(
SharedFunctionInfoRef shared_info(
broker(), frame_info.shared_info().ToHandleChecked());
InlineApiCall(receiver, holder, frame_state, value, effect, control,
shared_info, function_template_info);
shared_info, constant.AsFunctionTemplateInfo());
}
// Remember to rewire the IfException edge if this is inside a try-block.
if (if_exceptions != nullptr) {
......@@ -2046,8 +2030,13 @@ Node* JSNativeContextSpecialization::InlineApiCall(
Node* receiver, Node* holder, Node* frame_state, Node* value, Node** effect,
Node** control, SharedFunctionInfoRef const& shared_info,
FunctionTemplateInfoRef const& function_template_info) {
if (!function_template_info.call_code().has_value()) {
TRACE_BROKER_MISSING(broker(), "call code for function template info "
<< function_template_info);
return nullptr;
}
auto call_handler_info =
function_template_info.call_code().AsCallHandlerInfo();
function_template_info.call_code()->AsCallHandlerInfo();
// Only setters have a value.
int const argc = value == nullptr ? 0 : 1;
......
......@@ -811,10 +811,10 @@ void SerializerForBackgroundCompilation::ProcessApiCall(
Handle<SharedFunctionInfo> target, const HintsVector& arguments) {
FunctionTemplateInfoRef target_template_info(
broker(), handle(target->function_data(), broker()->isolate()));
target_template_info.Serialize();
if (!target_template_info.has_call_code()) return;
target_template_info.SerializeCallCode();
SharedFunctionInfoRef target_ref(broker(), target);
target_ref.SerializeFunctionTemplateInfo();
......@@ -1106,9 +1106,34 @@ SerializerForBackgroundCompilation::ProcessFeedbackMapsForNamedAccess(
ProcessMapForNamedPropertyAccess(map_ref, name);
AccessInfoFactory access_info_factory(broker(), dependencies(),
broker()->zone());
access_infos.push_back(access_info_factory.ComputePropertyAccessInfo(
PropertyAccessInfo info(access_info_factory.ComputePropertyAccessInfo(
map, name.object(), mode));
access_infos.push_back(info);
// TODO(turbofan): We want to take receiver hints into account as well,
// not only the feedback maps.
// For JSNativeContextSpecialization::InlinePropertySetterCall
// and InlinePropertyGetterCall.
if (info.IsAccessorConstant() && !info.constant().is_null()) {
if (info.constant()->IsJSFunction()) {
// For JSCallReducer::ReduceCallApiFunction.
Handle<SharedFunctionInfo> sfi(
handle(Handle<JSFunction>::cast(info.constant())->shared(),
broker()->isolate()));
if (sfi->IsApiFunction()) {
FunctionTemplateInfoRef fti_ref(
broker(), handle(sfi->get_api_func_data(), broker()->isolate()));
fti_ref.SerializeCallCode();
ProcessReceiverMapForApiCall(fti_ref, map);
}
} else {
FunctionTemplateInfoRef fti_ref(
broker(), Handle<FunctionTemplateInfo>::cast(info.constant()));
fti_ref.SerializeCallCode();
}
}
}
DCHECK(!access_infos.empty());
return new (broker()->zone()) NamedAccessFeedback(name, access_infos);
}
......
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