为什么Dart中的原生包装功能与“#34; DEFINE NATIVE ENTRY"功能非常轻量级?

时间:2014-01-26 12:39:11

标签: c++ performance dart native-code dart-native-extension

我无法理解:“为什么要放心?”。

这是来自dart/runtime/vm/native_entry.cc的自定义本机函数的包装器:

它适用于想要写native extensions的Dart程序员。

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定义本机函数的MACRO:

#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。这个是正常的。

但我无法在其中找到所有这些在每次调用中执行的测试,如上面的包装器。

当我看到我的功能比通过DEFINE_NATIVE_ENTRY定义的类似物慢3000%时,我会灰心丧气。

P.S

native function NOTHINGreturns 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(); \ } \ 工作的速度比(例如)此函数低500%。

scope

有没有办法编写不需要所有这些{{1}}的轻量级本机函数?

1 个答案:

答案 0 :(得分:1)

这是一个古老的问题,但是本地库绝对不是最大的库,而且重量很重。这些天,我们通常建议用户考虑使用dart:ffi进行C-interop,它比本机扩展性能更好,并且使用起来更容易。