/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/v8/src/ic/call-optimization.cc
150 строк
5 KB
Michaël Zasso
deps: update V8 to 13.6.233.8
02 май 2025, 16:06
Не верифицирован
02 май 2025, 16:06
918fe04
Код
Авторство
О чём код?
// Copyright 2014 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/ic/call-optimization.h" #include <optional> #include "src/objects/objects-inl.h" namespace v8 { namespace internal { template <class IsolateT> CallOptimization::CallOptimization(IsolateT* isolate, Handle<Object> function) { if (IsJSFunction(*function)) { Initialize(isolate, Cast<JSFunction>(function)); } else if (IsFunctionTemplateInfo(*function)) { Initialize(isolate, Cast<FunctionTemplateInfo>(function)); } } // Instantiations. template CallOptimization::CallOptimization(Isolate* isolate, Handle<Object> function); template CallOptimization::CallOptimization(LocalIsolate* isolate, Handle<Object> function); std::optional<Tagged<NativeContext>> CallOptimization::GetAccessorContext( Tagged<Map> holder_map) const { if (is_constant_call()) { return constant_function_->native_context(); } Tagged<Object> maybe_native_context = holder_map->map()->native_context_or_null(); if (IsNull(maybe_native_context)) { // The holder is a remote object which doesn't have a creation context. return {}; } DCHECK(IsNativeContext(maybe_native_context)); return Cast<NativeContext>(maybe_native_context); } bool CallOptimization::IsCrossContextLazyAccessorPair( Tagged<NativeContext> native_context, Tagged<Map> holder_map) const { DCHECK(IsNativeContext(native_context)); if (is_constant_call()) return false; std::optional<Tagged<NativeContext>> maybe_context = GetAccessorContext(holder_map); if (!maybe_context.has_value()) { // The holder is a remote object which doesn't have a creation context. return true; } return native_context != maybe_context.value(); } template <class IsolateT> Handle<JSObject> CallOptimization::LookupHolderOfExpectedType( IsolateT* isolate, DirectHandle<Map> object_map, HolderLookup* holder_lookup) const { DCHECK(is_simple_api_call()); if (!IsJSObjectMap(*object_map)) { *holder_lookup = kHolderNotFound; return Handle<JSObject>::null(); } if (expected_receiver_type_.is_null() || expected_receiver_type_->IsTemplateFor(*object_map)) { *holder_lookup = kHolderIsReceiver; return Handle<JSObject>::null(); } if (IsJSGlobalProxyMap(*object_map) && !IsNull(object_map->prototype())) { Tagged<JSObject> raw_prototype = Cast<JSObject>(object_map->prototype()); Handle<JSObject> prototype(raw_prototype, isolate); object_map = direct_handle(prototype->map(), isolate); if (expected_receiver_type_->IsTemplateFor(*object_map)) { *holder_lookup = kHolderFound; return prototype; } } *holder_lookup = kHolderNotFound; return Handle<JSObject>::null(); } // Instantiations. template Handle<JSObject> CallOptimization::LookupHolderOfExpectedType( Isolate* isolate, DirectHandle<Map> object_map, HolderLookup* holder_lookup) const; template Handle<JSObject> CallOptimization::LookupHolderOfExpectedType( LocalIsolate* isolate, DirectHandle<Map> object_map, HolderLookup* holder_lookup) const; bool CallOptimization::IsCompatibleReceiverMap( DirectHandle<JSObject> api_holder, Handle<JSObject> holder, HolderLookup holder_lookup) const { DCHECK(is_simple_api_call()); switch (holder_lookup) { case kHolderNotFound: return false; case kHolderIsReceiver: return true; case kHolderFound: if (api_holder.is_identical_to(holder)) return true; // Check if holder is in prototype chain of api_holder. { Tagged<JSObject> object = *api_holder; while (true) { Tagged<Object> prototype = object->map()->prototype(); if (!IsJSObject(prototype)) return false; if (prototype == *holder) return true; object = Cast<JSObject>(prototype); } } } UNREACHABLE(); } template <class IsolateT> void CallOptimization::Initialize( IsolateT* isolate, Handle<FunctionTemplateInfo> function_template_info) { if (!function_template_info->has_callback(isolate)) return; api_call_info_ = function_template_info; Tagged<HeapObject> signature = function_template_info->signature(); if (!IsUndefined(signature, isolate)) { expected_receiver_type_ = handle(Cast<FunctionTemplateInfo>(signature), isolate); } is_simple_api_call_ = true; accept_any_receiver_ = function_template_info->accept_any_receiver(); } template <class IsolateT> void CallOptimization::Initialize(IsolateT* isolate, Handle<JSFunction> function) { if (function.is_null() || !function->is_compiled(isolate)) return; constant_function_ = function; AnalyzePossibleApiFunction(isolate, function); } template <class IsolateT> void CallOptimization::AnalyzePossibleApiFunction( IsolateT* isolate, DirectHandle<JSFunction> function) { if (!function->shared()->IsApiFunction()) return; Handle<FunctionTemplateInfo> function_template_info( function->shared()->api_func_data(), isolate); Initialize(isolate, function_template_info); } } // namespace internal } // namespace v8