// Copyright (c) 2024, 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. #include #include typedef struct { void* isa; int flags; // There are other fields, but we just need the flags and isa. } BlockRefCountExtractor; uint64_t getBlockRetainCount(BlockRefCountExtractor* block) { // The ref count is stored in the lower bits of the flags field, but skips the // 0x1 bit. return (block->flags & 0xFFFF) >> 1; } typedef struct { uint64_t header; } ObjectRefCountExtractor; static const uint64_t k128OrMore = 128; // Returns the ref count of the object, up to 127. For counts above this, always // returns k128OrMore. uint64_t getObjectRetainCount(ObjectRefCountExtractor* object) { uint64_t count = object->header >> 56; return count < 0x80 ? count : k128OrMore; } int isReadableMemory(void* ptr) { vm_map_t task = mach_task_self(); mach_vm_address_t address = (mach_vm_address_t)ptr; mach_vm_size_t size = 0; vm_region_basic_info_data_64_t info; mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64; mach_port_t object_name; kern_return_t status = mach_vm_region(task, &address, &size, VM_REGION_BASIC_INFO_64, (vm_region_info_t)&info, &count, &object_name); if (status != KERN_SUCCESS) return 0; return ((mach_vm_address_t)ptr) >= address && (info.protection & VM_PROT_READ); }