为什么 Dart 中的原生包装函数与非常轻量级的函数相比"DEFINE NATIVE ENTRY"如此重量级?

Why native wrapped functions in Dart are such heavyweight in comparison with "DEFINE NATIVE ENTRY" functions that are very lightweight?

本文关键字:函数 ENTRY DEFINE NATIVE 重量级 轻量级 原生 Dart 包装 为什么 非常      更新时间:2023-10-16

我听不懂:"为什么要放心?"。

这是dart/runtime/vm/native_entry.cc的自定义本机功能的包装器:

它旨在为想要写native extensions的飞镖程序员。

void NativeEntry::NativeCallWrapper(Dart_NativeArguments args,
                                    Dart_NativeFunction func) {
  CHECK_STACK_ALIGNMENT;
  VERIFY_ON_TRANSITION;
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  Isolate* isolate = arguments->isolate();
  ApiState* state = isolate->api_state();
  ASSERT(state != NULL);
  ApiLocalScope* current_top_scope = state->top_scope();
  ApiLocalScope* scope = state->reusable_scope();
  TRACE_NATIVE_CALL("0x%" Px "", reinterpret_cast<uintptr_t>(func));
  if (scope == NULL) {
    scope = new ApiLocalScope(current_top_scope,
                              isolate->top_exit_frame_info());
    ASSERT(scope != NULL);
  } else {
    scope->Reinit(isolate,
                  current_top_scope,
                  isolate->top_exit_frame_info());
    state->set_reusable_scope(NULL);
  }
  state->set_top_scope(scope);  // New scope is now the top scope.
  func(args);
  ASSERT(current_top_scope == scope->previous());
  state->set_top_scope(current_top_scope);  // Reset top scope to previous.
  if (state->reusable_scope() == NULL) {
    scope->Reset(isolate);  // Reset the old scope which we just exited.
    state->set_reusable_scope(scope);
  } else {
    ASSERT(state->reusable_scope() != scope);
    delete scope;
  }
  DEOPTIMIZE_ALOT;
  VERIFY_ON_TRANSITION;
}

此包装器具有所有不必要的检查,其在包装本机功能的每次调用中都执行的所有不必要的检查使这些功能与使用开发人员的内容相比,这些功能都不竞争。

这是用于从dart/runtime/vm/native_entry.h定义本机函数的宏:

#define DEFINE_NATIVE_ENTRY(name, argument_count)                              
  static RawObject* DN_Helper##name(Isolate* isolate,                          
                                    NativeArguments* arguments);               
  void NATIVE_ENTRY_FUNCTION(name)(Dart_NativeArguments args) {                
    CHECK_STACK_ALIGNMENT;                                                     
    VERIFY_ON_TRANSITION;                                                      
    NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);     
    ASSERT(arguments->NativeArgCount() == argument_count);                     
    TRACE_NATIVE_CALL("%s", ""#name);                                          
    {                                                                          
      StackZone zone(arguments->isolate());                                    
      SET_NATIVE_RETVAL(arguments,                                             
                        DN_Helper##name(arguments->isolate(), arguments));     
      DEOPTIMIZE_ALOT;                                                         
    }                                                                          
    VERIFY_ON_TRANSITION;                                                      
  }                                                                            
  static RawObject* DN_Helper##name(Isolate* isolate,                          
                                    NativeArguments* arguments)

我知道它可以直接与RawObject一起使用。这个是正常的。

,但我在所有这些测试中都找不到每个调用中执行的测试,如上述包装器中。

当我看到我的功能在3000%上工作的速度比通过DEFINE_NATIVE_ENTRY定义的类似物慢。

慢了。

P.S

我的 native function and NOTHING且不能在500%慢的returns ANYTHING工作(例如)此功能。

#define TYPED_DATA_GETTER(getter, object, access_size)                         
DEFINE_NATIVE_ENTRY(TypedData_##getter, 2) {                                   
  GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); 
  GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); 
  if (instance.IsTypedData()) {                                                
    const TypedData& array = TypedData::Cast(instance);                        
    RangeCheck(offsetInBytes.Value(), access_size,                             
               array.LengthInBytes(), access_size);                            
    return object::New(array.getter(offsetInBytes.Value()));                   
  }                                                                            
  if (instance.IsExternalTypedData()) {                                        
    const ExternalTypedData& array = ExternalTypedData::Cast(instance);        
    RangeCheck(offsetInBytes.Value(), access_size,                             
               array.LengthInBytes(), access_size);                            
    return object::New(array.getter(offsetInBytes.Value()));                   
  }                                                                            
  const String& error = String::Handle(String::NewFormatted(                   
      "Expected a TypedData object but found %s", instance.ToCString()));      
  Exceptions::ThrowArgumentError(error);                                       
  return object::null();                                                       
}                                                                              

有什么方法可以编写不需要所有这些scope的轻量级本机函数?

这是一个古老的问题,但是本地库绝对不是最大的,而且非常重量。如今,我们通常建议用户考虑使用DART:FFI进行C-Interop,它比本机扩展更具性能,并且可以说更容易使用。