Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit bdb07f4

Browse files
sjindel-googlecommit-bot@chromium.org
authored andcommitted
[vm/ffi] Fix garbage collection of ffi.Pointer subtypes.
Fixes dart-lang/sdk#36125. Change-Id: Ib9069d1e15684c785b86954ed8c14e5fdde35fec Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/95652 Commit-Queue: Samir Jindel <sjindel@google.com> Reviewed-by: Daco Harkes <dacoharkes@google.com>
1 parent cab4a7b commit bdb07f4

File tree

8 files changed

+108
-76
lines changed

8 files changed

+108
-76
lines changed

runtime/lib/ffi.cc

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -231,14 +231,15 @@ DEFINE_NATIVE_ENTRY(Ffi_allocate, 1, 1) {
231231
CheckRange(argCount, 1, max_count, "count");
232232

233233
size_t size = ffi::ElementSizeInBytes(type_cid) * count;
234-
uint8_t* memory = reinterpret_cast<uint8_t*>(malloc(size));
235-
if (memory == NULL) {
234+
intptr_t memory = reinterpret_cast<intptr_t>(malloc(size));
235+
if (memory == 0) {
236236
const String& error = String::Handle(String::NewFormatted(
237237
"allocating (%" Pd ") bytes of memory failed", size));
238238
Exceptions::ThrowArgumentError(error);
239239
}
240240

241-
RawPointer* result = Pointer::New(type_arg, memory);
241+
RawPointer* result =
242+
Pointer::New(type_arg, Integer::Handle(zone, Integer::New(memory)));
242243
return result;
243244
}
244245

@@ -250,27 +251,27 @@ DEFINE_NATIVE_ENTRY(Ffi_fromAddress, 1, 1) {
250251
CheckIsConcreteNativeType(native_type);
251252
GET_NON_NULL_NATIVE_ARGUMENT(Integer, arg_ptr, arguments->NativeArgAt(0));
252253

253-
uint8_t* address = reinterpret_cast<uint8_t*>(arg_ptr.AsInt64Value());
254-
// TODO(dacoharkes): should this return NULL if addres is 0?
254+
// TODO(dacoharkes): should this return NULL if address is 0?
255255
// https://github.com/dart-lang/sdk/issues/35756
256256

257257
RawPointer* result =
258-
Pointer::New(native_type, address, type_arg.type_class_id());
258+
Pointer::New(native_type, arg_ptr, type_arg.type_class_id());
259259
return result;
260260
}
261261

262262
DEFINE_NATIVE_ENTRY(Ffi_elementAt, 0, 2) {
263263
GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
264264
GET_NON_NULL_NATIVE_ARGUMENT(Integer, index, arguments->NativeArgAt(1));
265265
AbstractType& pointer_type_arg =
266-
AbstractType::Handle(pointer.type_argument());
266+
AbstractType::Handle(zone, pointer.type_argument());
267267
CheckSized(pointer_type_arg);
268268

269269
classid_t class_id = pointer_type_arg.type_class_id();
270-
uint8_t* address = pointer.GetCMemoryAddress();
271-
uint8_t* address_new =
272-
address + index.AsInt64Value() * ffi::ElementSizeInBytes(class_id);
273-
RawPointer* result = Pointer::New(pointer_type_arg, address_new);
270+
Integer& address = Integer::Handle(zone, pointer.GetCMemoryAddress());
271+
address =
272+
Integer::New(address.AsInt64Value() +
273+
index.AsInt64Value() * ffi::ElementSizeInBytes(class_id));
274+
RawPointer* result = Pointer::New(pointer_type_arg, address);
274275
return result;
275276
}
276277

@@ -280,9 +281,11 @@ DEFINE_NATIVE_ENTRY(Ffi_offsetBy, 0, 2) {
280281
AbstractType& pointer_type_arg =
281282
AbstractType::Handle(pointer.type_argument());
282283

283-
uint8_t* address = pointer.GetCMemoryAddress();
284-
uint8_t* address_new = address + offset.AsInt64Value();
285-
RawPointer* result = Pointer::New(pointer_type_arg, address_new);
284+
intptr_t address =
285+
Integer::Handle(zone, pointer.GetCMemoryAddress()).AsInt64Value() +
286+
offset.AsInt64Value();
287+
RawPointer* result = Pointer::New(
288+
pointer_type_arg, Integer::Handle(zone, Integer::New(address)));
286289
return result;
287290
}
288291

@@ -294,7 +297,7 @@ DEFINE_NATIVE_ENTRY(Ffi_cast, 1, 1) {
294297
type_args.TypeAtNullSafe(Pointer::kNativeTypeArgPos));
295298
CheckIsConcreteNativeType(native_type);
296299

297-
uint8_t* address = pointer.GetCMemoryAddress();
300+
const Integer& address = Integer::Handle(zone, pointer.GetCMemoryAddress());
298301
RawPointer* result =
299302
Pointer::New(native_type, address, type_arg.type_class_id());
300303
return result;
@@ -303,35 +306,37 @@ DEFINE_NATIVE_ENTRY(Ffi_cast, 1, 1) {
303306
DEFINE_NATIVE_ENTRY(Ffi_free, 0, 1) {
304307
GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
305308

306-
uint8_t* address = pointer.GetCMemoryAddress();
307-
free(address);
308-
pointer.SetCMemoryAddress(0);
309+
const Integer& address = Integer::Handle(zone, pointer.GetCMemoryAddress());
310+
free(reinterpret_cast<void*>(address.AsInt64Value()));
311+
pointer.SetCMemoryAddress(Integer::Handle(zone, Integer::New(0)));
309312
return Object::null();
310313
}
311314

312315
DEFINE_NATIVE_ENTRY(Ffi_address, 0, 1) {
313316
GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
314-
315-
uint8_t* address = pointer.GetCMemoryAddress();
316-
intptr_t int_ptr = reinterpret_cast<intptr_t>(address);
317-
return Integer::NewFromUint64(int_ptr);
317+
return pointer.GetCMemoryAddress();
318318
}
319319

320-
static RawInstance* BoxLoadPointer(uint8_t* address,
320+
static RawInstance* BoxLoadPointer(Zone* zone,
321+
uint8_t* address,
321322
const AbstractType& instance_type_arg,
322323
intptr_t type_cid) {
323324
// TODO(dacoharkes): should this return NULL if addres is 0?
324325
// https://github.com/dart-lang/sdk/issues/35756
325-
if (address == 0) { // 0 is the c++ null pointer
326+
if (address == nullptr) {
326327
return Instance::null();
327328
}
328329
AbstractType& type_arg =
329330
AbstractType::Handle(TypeArguments::Handle(instance_type_arg.arguments())
330331
.TypeAt(Pointer::kNativeTypeArgPos));
331-
return Pointer::New(type_arg, address, type_cid);
332+
return Pointer::New(
333+
type_arg,
334+
Integer::Handle(zone, Integer::New(reinterpret_cast<intptr_t>(address))),
335+
type_cid);
332336
}
333337

334-
static RawInstance* LoadValue(uint8_t* address,
338+
static RawInstance* LoadValue(Zone* zone,
339+
uint8_t* address,
335340
const AbstractType& instance_type_arg) {
336341
classid_t type_cid = instance_type_arg.type_class_id();
337342
switch (type_cid) {
@@ -360,7 +365,7 @@ static RawInstance* LoadValue(uint8_t* address,
360365
case kFfiPointerCid:
361366
default:
362367
ASSERT(IsPointerType(instance_type_arg));
363-
return BoxLoadPointer(*reinterpret_cast<uint8_t**>(address),
368+
return BoxLoadPointer(zone, *reinterpret_cast<uint8_t**>(address),
364369
instance_type_arg, type_cid);
365370
}
366371
}
@@ -373,14 +378,17 @@ DEFINE_NATIVE_ENTRY(Ffi_load, 1, 1) {
373378
CheckSized(pointer_type_arg);
374379
ASSERT(DartAndCTypeCorrespond(pointer_type_arg, type_arg));
375380

376-
uint8_t* address = pointer.GetCMemoryAddress();
377-
return LoadValue(address, pointer_type_arg);
381+
uint8_t* address = reinterpret_cast<uint8_t*>(
382+
Integer::Handle(pointer.GetCMemoryAddress()).AsInt64Value());
383+
return LoadValue(zone, address, pointer_type_arg);
378384
}
379385

380-
static void StoreValue(const Pointer& pointer,
386+
static void StoreValue(Zone* zone,
387+
const Pointer& pointer,
381388
classid_t type_cid,
382389
const Instance& new_value) {
383-
uint8_t* address = pointer.GetCMemoryAddress();
390+
uint8_t* address = reinterpret_cast<uint8_t*>(
391+
Integer::Handle(pointer.GetCMemoryAddress()).AsInt64Value());
384392
AbstractType& pointer_type_arg =
385393
AbstractType::Handle(pointer.type_argument());
386394
switch (type_cid) {
@@ -428,14 +436,16 @@ static void StoreValue(const Pointer& pointer,
428436
case kFfiPointerCid:
429437
default: {
430438
ASSERT(IsPointerType(pointer_type_arg));
431-
uint8_t* new_value_unwrapped = nullptr;
439+
intptr_t new_value_unwrapped = 0;
432440
if (!new_value.IsNull()) {
433441
ASSERT(new_value.IsPointer());
434-
new_value_unwrapped = AsPointer(new_value).GetCMemoryAddress();
442+
new_value_unwrapped =
443+
Integer::Handle(AsPointer(new_value).GetCMemoryAddress())
444+
.AsInt64Value();
435445
// TODO(dacoharkes): should this return NULL if addres is 0?
436446
// https://github.com/dart-lang/sdk/issues/35756
437447
}
438-
*reinterpret_cast<uint8_t**>(address) = new_value_unwrapped;
448+
*reinterpret_cast<intptr_t*>(address) = new_value_unwrapped;
439449
} break;
440450
}
441451
}
@@ -450,7 +460,7 @@ DEFINE_NATIVE_ENTRY(Ffi_store, 0, 2) {
450460
ASSERT(DartAndCTypeCorrespond(pointer_type_arg, arg_type));
451461

452462
classid_t type_cid = pointer_type_arg.type_class_id();
453-
StoreValue(pointer, type_cid, new_value);
463+
StoreValue(zone, pointer, type_cid, new_value);
454464
return Object::null();
455465
}
456466

@@ -561,9 +571,7 @@ DEFINE_NATIVE_ENTRY(Ffi_asFunction, 1, 1) {
561571
// the function so that we can reuse the function for each c function with
562572
// the same signature.
563573
Context& context = Context::Handle(Context::New(1));
564-
context.SetAt(0,
565-
Object::Handle(Integer::NewFromUint64(
566-
reinterpret_cast<intptr_t>(pointer.GetCMemoryAddress()))));
574+
context.SetAt(0, Integer::Handle(zone, pointer.GetCMemoryAddress()));
567575

568576
RawClosure* raw_closure =
569577
Closure::New(Object::null_type_arguments(), Object::null_type_arguments(),
@@ -623,7 +631,8 @@ DEFINE_NATIVE_ENTRY(Ffi_fromFunction, 1, 1) {
623631
THR_Print("Ffi_fromFunction: %p\n", entryPoint);
624632
THR_Print("Ffi_fromFunction: %" Pd "\n", code.Size());
625633

626-
void* address = GenerateFfiInverseTrampoline(c_signature, entryPoint);
634+
intptr_t address = reinterpret_cast<intptr_t>(
635+
GenerateFfiInverseTrampoline(c_signature, entryPoint));
627636

628637
TypeArguments& type_args = TypeArguments::Handle(zone);
629638
type_args = TypeArguments::New(1);
@@ -642,8 +651,8 @@ DEFINE_NATIVE_ENTRY(Ffi_fromFunction, 1, 1) {
642651

643652
address = 0; // https://github.com/dart-lang/sdk/issues/35761
644653

645-
Pointer& result = Pointer::Handle(
646-
Pointer::New(native_function_type, reinterpret_cast<uint8_t*>(address)));
654+
Pointer& result = Pointer::Handle(Pointer::New(
655+
native_function_type, Integer::Handle(zone, Integer::New(address))));
647656

648657
return result.raw();
649658
}

runtime/lib/ffi_dynamic_library.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ DEFINE_NATIVE_ENTRY(Ffi_dl_lookup, 1, 2) {
5151
void* handle = dlib.GetHandle();
5252

5353
dlerror(); // Clear any errors.
54-
uint8_t* pointer =
55-
reinterpret_cast<uint8_t*>(dlsym(handle, argSymbolName.ToCString()));
54+
intptr_t pointer =
55+
reinterpret_cast<intptr_t>(dlsym(handle, argSymbolName.ToCString()));
5656
char* error;
5757
if ((error = dlerror()) != NULL) {
5858
const String& msg = String::Handle(
@@ -62,7 +62,8 @@ DEFINE_NATIVE_ENTRY(Ffi_dl_lookup, 1, 2) {
6262

6363
// TODO(dacoharkes): should this return NULL if addres is 0?
6464
// https://github.com/dart-lang/sdk/issues/35756
65-
RawPointer* result = Pointer::New(type_arg, pointer);
65+
RawPointer* result =
66+
Pointer::New(type_arg, Integer::Handle(zone, Integer::New(pointer)));
6667
return result;
6768
#endif
6869
}

runtime/vm/ffi_trampoline_stubs_x64.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,8 @@ static void GenerateMarshalPointer(Assembler* assembler, Register reg) {
231231

232232
// If not null but a Pointer, load the address.
233233
__ Bind(&not_null);
234-
__ movq(reg, FieldAddress(reg, Pointer::address_offset()));
234+
__ movq(reg, FieldAddress(reg, Pointer::c_memory_address_offset()));
235+
GenerateMarshalInt64(assembler, reg);
235236
__ Bind(&done);
236237
}
237238

@@ -256,9 +257,9 @@ static void GenerateUnmarshalPointer(Assembler* assembler,
256257
__ LoadObject(RAX, Object::null_object());
257258
__ jmp(&done);
258259

259-
// Backup result value (to avoid GC).
260260
__ Bind(&not_null);
261-
GenerateSaveInt64GCSafe(assembler, RAX);
261+
GenerateUnmarshalInt64(assembler);
262+
__ pushq(RAX);
262263

263264
// Allocate object (can call into runtime).
264265
__ movq(TMP, closure_dart);
@@ -269,8 +270,8 @@ static void GenerateUnmarshalPointer(Assembler* assembler,
269270
__ popq(TMP); // Pop type arguments.
270271

271272
// Store the result value.
272-
GenerateLoadInt64GCSafe(assembler, RDX);
273-
__ movq(FieldAddress(RAX, Pointer::address_offset()), RDX);
273+
__ popq(RDX);
274+
__ movq(FieldAddress(RAX, Pointer::c_memory_address_offset()), RDX);
274275
__ Bind(&done);
275276
}
276277

runtime/vm/object.cc

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7785,8 +7785,9 @@ RawString* Function::GetSource() const {
77857785
uint16_t end_char = src.CharAt(end_token_pos().value());
77867786
if ((end_char == ',') || // Case 1.
77877787
(end_char == ')') || // Case 2.
7788-
(end_char == ';' && String::Handle(zone, name())
7789-
.Equals("<anonymous closure>"))) { // Case 3.
7788+
(end_char == ';' &&
7789+
String::Handle(zone, name())
7790+
.Equals("<anonymous closure>"))) { // Case 3.
77907791
to_length = 0;
77917792
}
77927793
}
@@ -12738,28 +12739,25 @@ static int PrintVarInfo(char* buffer,
1273812739
const RawLocalVarDescriptors::VarInfoKind kind = info.kind();
1273912740
const int32_t index = info.index();
1274012741
if (kind == RawLocalVarDescriptors::kContextLevel) {
12741-
return Utils::SNPrint(buffer, len,
12742-
"%2" Pd
12743-
" %-13s level=%-3d"
12744-
" begin=%-3d end=%d\n",
12742+
return Utils::SNPrint(buffer, len, "%2" Pd
12743+
" %-13s level=%-3d"
12744+
" begin=%-3d end=%d\n",
1274512745
i, LocalVarDescriptors::KindToCString(kind), index,
1274612746
static_cast<int>(info.begin_pos.value()),
1274712747
static_cast<int>(info.end_pos.value()));
1274812748
} else if (kind == RawLocalVarDescriptors::kContextVar) {
1274912749
return Utils::SNPrint(
12750-
buffer, len,
12751-
"%2" Pd
12752-
" %-13s level=%-3d index=%-3d"
12753-
" begin=%-3d end=%-3d name=%s\n",
12750+
buffer, len, "%2" Pd
12751+
" %-13s level=%-3d index=%-3d"
12752+
" begin=%-3d end=%-3d name=%s\n",
1275412753
i, LocalVarDescriptors::KindToCString(kind), info.scope_id, index,
1275512754
static_cast<int>(info.begin_pos.Pos()),
1275612755
static_cast<int>(info.end_pos.Pos()), var_name.ToCString());
1275712756
} else {
1275812757
return Utils::SNPrint(
12759-
buffer, len,
12760-
"%2" Pd
12761-
" %-13s scope=%-3d index=%-3d"
12762-
" begin=%-3d end=%-3d name=%s\n",
12758+
buffer, len, "%2" Pd
12759+
" %-13s scope=%-3d index=%-3d"
12760+
" begin=%-3d end=%-3d name=%s\n",
1276312761
i, LocalVarDescriptors::KindToCString(kind), info.scope_id, index,
1276412762
static_cast<int>(info.begin_pos.Pos()),
1276512763
static_cast<int>(info.end_pos.Pos()), var_name.ToCString());
@@ -20914,7 +20912,7 @@ const char* ExternalTypedData::ToCString() const {
2091420912
}
2091520913

2091620914
RawPointer* Pointer::New(const AbstractType& type_arg,
20917-
uint8_t* c_memory_address,
20915+
const Integer& c_memory_address,
2091820916
intptr_t cid,
2091920917
Heap::Space space) {
2092020918
Thread* thread = Thread::Current();
@@ -20941,7 +20939,8 @@ const char* Pointer::ToCString() const {
2094120939
String& type_args_name = String::Handle(type_args.UserVisibleName());
2094220940
return OS::SCreate(Thread::Current()->zone(), "Pointer%s: address=0x%" Px,
2094320941
type_args_name.ToCString(),
20944-
reinterpret_cast<uintptr_t>(GetCMemoryAddress()));
20942+
static_cast<intptr_t>(
20943+
Integer::Handle(GetCMemoryAddress()).AsInt64Value()));
2094520944
}
2094620945

2094720946
RawDynamicLibrary* DynamicLibrary::New(void* handle, Heap::Space space) {

runtime/vm/object.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8499,7 +8499,7 @@ class ByteBuffer : public AllStatic {
84998499
class Pointer : public Instance {
85008500
public:
85018501
static RawPointer* New(const AbstractType& type_arg,
8502-
uint8_t* c_memory_address,
8502+
const Integer& c_memory_address,
85038503
intptr_t class_id = kFfiPointerCid,
85048504
Heap::Space space = Heap::kNew);
85058505

@@ -8509,20 +8509,17 @@ class Pointer : public Instance {
85098509

85108510
static bool IsPointer(const Instance& obj);
85118511

8512-
uint8_t* GetCMemoryAddress() const {
8513-
ASSERT(!IsNull());
8514-
return raw_ptr()->c_memory_address_;
8515-
}
8512+
RawInteger* GetCMemoryAddress() const { return raw_ptr()->c_memory_address_; }
85168513

8517-
void SetCMemoryAddress(uint8_t* value) const {
8518-
StoreNonPointer(&raw_ptr()->c_memory_address_, value);
8514+
void SetCMemoryAddress(const Integer& value) const {
8515+
StorePointer(&raw_ptr()->c_memory_address_, value.raw());
85198516
}
85208517

85218518
static intptr_t type_arguments_offset() {
85228519
return OFFSET_OF(RawPointer, type_arguments_);
85238520
}
85248521

8525-
static intptr_t address_offset() {
8522+
static intptr_t c_memory_address_offset() {
85268523
return OFFSET_OF(RawPointer, c_memory_address_);
85278524
}
85288525

runtime/vm/raw_object.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2263,8 +2263,8 @@ class RawPointer : public RawInstance {
22632263
RAW_HEAP_OBJECT_IMPLEMENTATION(Pointer);
22642264
VISIT_FROM(RawCompressed, type_arguments_)
22652265
RawTypeArguments* type_arguments_;
2266-
VISIT_TO(RawCompressed, type_arguments_)
2267-
uint8_t* c_memory_address_;
2266+
RawInteger* c_memory_address_;
2267+
VISIT_TO(RawCompressed, c_memory_address_)
22682268

22692269
friend class Pointer;
22702270
};

0 commit comments

Comments
 (0)