I cannot understand: "Why this reassurance?".
This is wrapper for custom native function from dart/runtime/vm/native_entry.cc
:
It intended for the Dart programmers that want write 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;
}
This wrapper with all unnecessary checks that it performs at every invocation of wrapped native function makes these functions uncompetitive in comparison to what uses developers for themselves.
This is MACRO for defining native function from 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)
I know that it works directly with RawObject
. This is normal.
But I can not find in it all of these tests, which are performed in each call, as in the above wrapper.
I lose heart when I see that my functions work on the 3000% slower than the analogues defined via DEFINE_NATIVE_ENTRY
.
P.S
My native function
that does NOTHING
and does not returns ANYTHING
works on the 500% slower than (for example) this function.
#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(); \
} \
Is there any way to write lightweight native functions that not requires all of these scope
?