[VM/Runtime] - Deprecate Dart_UpdateExternalSize and Dart_UpdateFinalizableExternalSize from the Dart C API

https://github.com/dart-lang/sdk/issues/52568

TEST=new test added.

Change-Id: I4f4b6b607fa2e0daa14fc25e3bdf99214f6ccb6b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/314900
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Siva Annamalai <asiva@google.com>
This commit is contained in:
asiva 2023-07-20 17:06:44 +00:00 committed by Commit Queue
parent 15acd7f16a
commit 5d872a8737
8 changed files with 62 additions and 184 deletions

View file

@ -1356,4 +1356,9 @@ DART_EXPORT void DecreaseRefcount(void* peer) {
ref_counted_resource_mutex.unlock();
}
DART_EXPORT void TestDeprecatedSymbols() {
Dart_UpdateExternalSize_DL(nullptr, 0);
Dart_UpdateFinalizableExternalSize_DL(nullptr, Dart_Null(), 0);
}
} // namespace dart

View file

@ -58,10 +58,13 @@
#if __GNUC__
#define DART_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#define DART_DEPRECATED(msg) __attribute__((deprecated(msg)))
#elif _MSC_VER
#define DART_WARN_UNUSED_RESULT _Check_return_
#define DART_DEPRECATED(msg) __declspec(deprecated(msg))
#else
#define DART_WARN_UNUSED_RESULT
#define DART_DEPRECATED(msg)
#endif
/*
@ -502,14 +505,6 @@ Dart_NewWeakPersistentHandle(Dart_Handle object,
DART_EXPORT void Dart_DeleteWeakPersistentHandle(
Dart_WeakPersistentHandle object);
/**
* Updates the external memory size for the given weak persistent handle.
*
* May trigger garbage collection.
*/
DART_EXPORT void Dart_UpdateExternalSize(Dart_WeakPersistentHandle object,
intptr_t external_allocation_size);
/**
* Allocates a finalizable handle for an object.
*
@ -561,18 +556,6 @@ Dart_NewFinalizableHandle(Dart_Handle object,
DART_EXPORT void Dart_DeleteFinalizableHandle(Dart_FinalizableHandle object,
Dart_Handle strong_ref_to_object);
/**
* Updates the external memory size for the given finalizable handle.
*
* The caller has to provide the actual Dart object the handle was created from
* to prove the object (and therefore the finalizable handle) is still alive.
*
* May trigger garbage collection.
*/
DART_EXPORT void Dart_UpdateFinalizableExternalSize(
Dart_FinalizableHandle object,
Dart_Handle strong_ref_to_object,
intptr_t external_allocation_size);
/*
* ==========================

View file

@ -8,11 +8,13 @@
#include "dart_version.h" /* NOLINT */
#include "internal/dart_api_dl_impl.h" /* NOLINT */
#include <stdio.h>
#include <string.h>
#define DART_API_DL_DEFINITIONS(name, R, A) name##_Type name##_DL = NULL;
DART_API_ALL_DL_SYMBOLS(DART_API_DL_DEFINITIONS)
DART_API_DEPRECATED_DL_SYMBOLS(DART_API_DL_DEFINITIONS)
#undef DART_API_DL_DEFINITIONS
@ -27,6 +29,19 @@ DartApiEntry_function FindFunctionPointer(const DartApiEntry* entries,
return NULL;
}
DART_EXPORT void Dart_UpdateExternalSize_Deprecated(
Dart_WeakPersistentHandle object, intptr_t external_size) {
printf("Dart_UpdateExternalSize is a nop, it has been deprecated\n");
}
DART_EXPORT void Dart_UpdateFinalizableExternalSize_Deprecated(
Dart_FinalizableHandle object,
Dart_Handle strong_ref_to_object,
intptr_t external_allocation_size) {
printf("Dart_UpdateFinalizableExternalSize is a nop, "
"it has been deprecated\n");
}
intptr_t Dart_InitializeApiDL(void* data) {
DartApi* dart_api_data = (DartApi*)data;
@ -55,5 +70,10 @@ intptr_t Dart_InitializeApiDL(void* data) {
DART_API_ALL_DL_SYMBOLS(DART_API_DL_INIT)
#undef DART_API_DL_INIT
#define DART_API_DEPRECATED_DL_INIT(name, R, A) \
name##_DL = name##_Deprecated;
DART_API_DEPRECATED_DL_SYMBOLS(DART_API_DEPRECATED_DL_INIT)
#undef DART_API_DEPRECATED_DL_INIT
return 0;
}

View file

@ -80,16 +80,11 @@ typedef void (*Dart_NativeMessageHandler_DL)(Dart_Port_DL dest_port_id,
(Dart_Handle object, void* peer, intptr_t external_allocation_size, \
Dart_HandleFinalizer callback)) \
F(Dart_DeleteWeakPersistentHandle, void, (Dart_WeakPersistentHandle object)) \
F(Dart_UpdateExternalSize, void, \
(Dart_WeakPersistentHandle object, intptr_t external_allocation_size)) \
F(Dart_NewFinalizableHandle, Dart_FinalizableHandle, \
(Dart_Handle object, void* peer, intptr_t external_allocation_size, \
Dart_HandleFinalizer callback)) \
F(Dart_DeleteFinalizableHandle, void, \
(Dart_FinalizableHandle object, Dart_Handle strong_ref_to_object)) \
F(Dart_UpdateFinalizableExternalSize, void, \
(Dart_FinalizableHandle object, Dart_Handle strong_ref_to_object, \
intptr_t external_allocation_size)) \
/* Isolates */ \
F(Dart_CurrentIsolate, Dart_Isolate, (void)) \
F(Dart_ExitIsolate, void, (void)) \
@ -105,6 +100,16 @@ typedef void (*Dart_NativeMessageHandler_DL)(Dart_Port_DL dest_port_id,
/* Objects */ \
F(Dart_IsNull, bool, (Dart_Handle))
// dart_api.h symbols that have been deprecated but are retained here
// until we can make a breaking change bumping the major version number
// (DART_API_DL_MAJOR_VERSION)
#define DART_API_DEPRECATED_DL_SYMBOLS(F) \
F(Dart_UpdateExternalSize, void, \
(Dart_WeakPersistentHandle object, intptr_t external_allocation_size)) \
F(Dart_UpdateFinalizableExternalSize, void, \
(Dart_FinalizableHandle object, Dart_Handle strong_ref_to_object, \
intptr_t external_allocation_size))
#define DART_API_ALL_DL_SYMBOLS(F) \
DART_NATIVE_API_DL_SYMBOLS(F) \
DART_API_DL_SYMBOLS(F)
@ -148,6 +153,7 @@ typedef void (*Dart_NativeMessageHandler_DL)(Dart_Port_DL dest_port_id,
DART_EXPORT_DL name##_Type name##_DL;
DART_API_ALL_DL_SYMBOLS(DART_API_DL_DECLARATIONS)
DART_API_DEPRECATED_DL_SYMBOLS(DART_API_DL_DECLARATIONS)
#undef DART_API_DL_DECLARATIONS

View file

@ -1117,34 +1117,6 @@ Dart_NewFinalizableHandle(Dart_Handle object,
callback);
}
DART_EXPORT void Dart_UpdateExternalSize(Dart_WeakPersistentHandle object,
intptr_t external_size) {
Thread* T = Thread::Current();
IsolateGroup* isolate_group = T->isolate_group();
CHECK_ISOLATE_GROUP(isolate_group);
TransitionToVM transition(T);
ApiState* state = isolate_group->api_state();
ASSERT(state != nullptr);
ASSERT(state->IsActiveWeakPersistentHandle(object));
auto weak_ref = FinalizablePersistentHandle::Cast(object);
weak_ref->UpdateExternalSize(external_size, isolate_group);
}
DART_EXPORT void Dart_UpdateFinalizableExternalSize(
Dart_FinalizableHandle object,
Dart_Handle strong_ref_to_object,
intptr_t external_allocation_size) {
if (!::Dart_IdentityEquals(strong_ref_to_object,
HandleFromFinalizable(object))) {
FATAL(
"%s expects arguments 'object' and 'strong_ref_to_object' to point to "
"the same object.",
CURRENT_FUNC);
}
auto wph_object = reinterpret_cast<Dart_WeakPersistentHandle>(object);
::Dart_UpdateExternalSize(wph_object, external_allocation_size);
}
DART_EXPORT void Dart_DeletePersistentHandle(Dart_PersistentHandle object) {
Thread* T = Thread::Current();
IsolateGroup* isolate_group = T->isolate_group();

View file

@ -4514,126 +4514,6 @@ TEST_CASE(DartAPI_FinalizableHandleExternalAllocationSizeOddReferents) {
}
}
#define EXAMPLE_RESOURCE_NATIVE_LIST(V) \
V(ExampleResource_Allocate, 1) \
V(ExampleResource_Use, 1) \
V(ExampleResource_Dispose, 1)
EXAMPLE_RESOURCE_NATIVE_LIST(DECLARE_FUNCTION);
static struct NativeEntries {
const char* name_;
Dart_NativeFunction function_;
int argument_count_;
} ExampleResourceEntries[] = {EXAMPLE_RESOURCE_NATIVE_LIST(REGISTER_FUNCTION)};
static Dart_NativeFunction ExampleResourceNativeResolver(
Dart_Handle name,
int argument_count,
bool* auto_setup_scope) {
const char* function_name = nullptr;
Dart_Handle result = Dart_StringToCString(name, &function_name);
ASSERT(!Dart_IsError(result));
ASSERT(function_name != nullptr);
ASSERT(auto_setup_scope != nullptr);
*auto_setup_scope = true;
int num_entries =
sizeof(ExampleResourceEntries) / sizeof(struct NativeEntries);
for (int i = 0; i < num_entries; i++) {
struct NativeEntries* entry = &(ExampleResourceEntries[i]);
if ((strcmp(function_name, entry->name_) == 0) &&
(entry->argument_count_ == argument_count)) {
return reinterpret_cast<Dart_NativeFunction>(entry->function_);
}
}
return nullptr;
}
struct ExampleResource {
Dart_FinalizableHandle self;
void* lots_of_memory;
};
void ExampleResourceFinalizer(void* isolate_peer, void* peer) {
ExampleResource* resource = reinterpret_cast<ExampleResource*>(peer);
free(resource->lots_of_memory);
delete resource;
}
void FUNCTION_NAME(ExampleResource_Allocate)(Dart_NativeArguments native_args) {
Dart_Handle receiver = Dart_GetNativeArgument(native_args, 0);
intptr_t external_size = 10 * MB;
ExampleResource* resource = new ExampleResource();
resource->lots_of_memory = malloc(external_size);
resource->self = Dart_NewFinalizableHandle(receiver, resource, external_size,
ExampleResourceFinalizer);
EXPECT_VALID(Dart_SetNativeInstanceField(
receiver, 0, reinterpret_cast<intptr_t>(resource)));
// Some pretend resource initialization.
*reinterpret_cast<uint8_t*>(resource->lots_of_memory) = 123;
}
void FUNCTION_NAME(ExampleResource_Use)(Dart_NativeArguments native_args) {
Dart_Handle receiver = Dart_GetNativeArgument(native_args, 0);
intptr_t native_field = 0;
EXPECT_VALID(Dart_GetNativeInstanceField(receiver, 0, &native_field));
ExampleResource* resource = reinterpret_cast<ExampleResource*>(native_field);
if (resource->lots_of_memory == nullptr) {
Dart_ThrowException(Dart_NewStringFromCString(
"Attempt to use a disposed ExampleResource!"));
UNREACHABLE();
} else {
// Some pretend resource use.
EXPECT_EQ(123, *reinterpret_cast<uint8_t*>(resource->lots_of_memory));
}
}
void FUNCTION_NAME(ExampleResource_Dispose)(Dart_NativeArguments native_args) {
Dart_Handle receiver = Dart_GetNativeArgument(native_args, 0);
intptr_t native_field = 0;
EXPECT_VALID(Dart_GetNativeInstanceField(receiver, 0, &native_field));
ExampleResource* resource = reinterpret_cast<ExampleResource*>(native_field);
if (resource->lots_of_memory != nullptr) {
free(resource->lots_of_memory);
resource->lots_of_memory = nullptr;
Dart_UpdateFinalizableExternalSize(resource->self, receiver, 0);
}
}
TEST_CASE(DartAPI_WeakPersistentHandleUpdateSize) {
const char* kScriptChars = R"(
import "dart:nativewrappers";
base class ExampleResource extends NativeFieldWrapperClass1 {
ExampleResource() { _allocate(); }
@pragma("vm:external-name", "ExampleResource_Allocate")
external void _allocate();
@pragma("vm:external-name", "ExampleResource_Use")
external void use();
@pragma("vm:external-name", "ExampleResource_Dispose")
external void dispose();
}
main() {
var res = new ExampleResource();
res.use();
res.dispose();
res.dispose(); // Idempotent
bool threw = false;
try {
res.use();
} catch (_) {
threw = true;
}
if (!threw) {
throw "Exception expected";
}
}
)";
Dart_Handle lib =
TestCase::LoadTestScript(kScriptChars, ExampleResourceNativeResolver);
EXPECT_VALID(Dart_Invoke(lib, NewString("main"), 0, nullptr));
}
void FUNCTION_NAME(SecretKeeper_KeepSecret)(Dart_NativeArguments native_args) {
Dart_Handle receiver = Dart_GetNativeArgument(native_args, 0);
int64_t secret = 0;

View file

@ -235,17 +235,6 @@ class FinalizablePersistentHandle {
return isolate_group->heap()->AllocatedExternal(external_size(),
SpaceForExternal());
}
void UpdateExternalSize(intptr_t size, IsolateGroup* isolate_group) {
ASSERT(size >= 0);
intptr_t old_size = external_size();
set_external_size(size);
if (size > old_size) {
isolate_group->heap()->AllocatedExternal(size - old_size,
SpaceForExternal());
} else {
isolate_group->heap()->FreedExternal(old_size - size, SpaceForExternal());
}
}
// Called when the referent becomes unreachable.
void UpdateUnreachable(IsolateGroup* isolate_group) {

View file

@ -0,0 +1,23 @@
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
// SharedObjects=ffi_test_functions
import 'dart:ffi';
import 'dart:io';
import 'dylib_utils.dart';
final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
final initializeApi = ffiTestFunctions.lookupFunction<
IntPtr Function(Pointer<Void>),
int Function(Pointer<Void>)>("InitDartApiDL");
main() {
initializeApi(NativeApi.initializeApiDLData);
final isDeprecated =
ffiTestFunctions.lookupFunction<Void Function(), void Function()>(
"TestDeprecatedSymbols");
isDeprecated();
}