diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc index 69fb8919b44..d9debad4744 100644 --- a/runtime/vm/dart_api_message.cc +++ b/runtime/vm/dart_api_message.cc @@ -12,14 +12,16 @@ namespace dart { static const int kNumInitialReferences = 4; -ApiMessageReader::ApiMessageReader(const uint8_t* buffer, - intptr_t length, - ReAlloc alloc) +ApiMessageReader::ApiMessageReader(const uint8_t* buffer, intptr_t length) : BaseReader(buffer, length), - alloc_(alloc), + zone_(NULL), backward_references_(kNumInitialReferences), vm_isolate_references_(kNumInitialReferences), vm_symbol_references_(NULL) { + // We need to have an enclosing ApiNativeScope. + ASSERT(ApiNativeScope::Current() != NULL); + zone_ = ApiNativeScope::Current()->zone(); + ASSERT(zone_ != NULL); Init(); } @@ -54,7 +56,7 @@ intptr_t ApiMessageReader::LookupInternalClass(intptr_t class_header) { Dart_CObject* ApiMessageReader::AllocateDartCObject(Dart_CObject_Type type) { Dart_CObject* value = - reinterpret_cast(alloc_(NULL, 0, sizeof(Dart_CObject))); + reinterpret_cast(allocator(sizeof(Dart_CObject))); ASSERT(value != NULL); value->type = type; return value; @@ -121,7 +123,7 @@ Dart_CObject* ApiMessageReader::AllocateDartCObjectString(intptr_t length) { // up to this area. Dart_CObject* value = reinterpret_cast( - alloc_(NULL, 0, sizeof(Dart_CObject) + length + 1)); + allocator(sizeof(Dart_CObject) + length + 1)); ASSERT(value != NULL); value->value.as_string = reinterpret_cast(value) + sizeof(*value); value->type = Dart_CObject_kString; @@ -162,7 +164,7 @@ Dart_CObject* ApiMessageReader::AllocateDartCObjectTypedData( intptr_t length_in_bytes = GetTypedDataSizeInBytes(type) * length; Dart_CObject* value = reinterpret_cast( - alloc_(NULL, 0, sizeof(Dart_CObject) + length_in_bytes)); + allocator(sizeof(Dart_CObject) + length_in_bytes)); ASSERT(value != NULL); value->type = Dart_CObject_kTypedData; value->value.as_typed_data.type = type; @@ -183,7 +185,7 @@ Dart_CObject* ApiMessageReader::AllocateDartCObjectArray(intptr_t length) { // content is set up to this area. Dart_CObject* value = reinterpret_cast( - alloc_(NULL, 0, sizeof(Dart_CObject) + length * sizeof(value))); + allocator(sizeof(Dart_CObject) + length * sizeof(value))); ASSERT(value != NULL); value->type = Dart_CObject_kArray; value->value.as_array.length = length; @@ -239,7 +241,7 @@ Dart_CObject_Internal* ApiMessageReader::AllocateDartCObjectInternal( Dart_CObject_Internal::Type type) { Dart_CObject_Internal* value = reinterpret_cast( - alloc_(NULL, 0, sizeof(Dart_CObject_Internal))); + allocator(sizeof(Dart_CObject_Internal))); ASSERT(value != NULL); value->type = static_cast(type); return value; @@ -255,7 +257,7 @@ ApiMessageReader::BackRefNode* ApiMessageReader::AllocateBackRefNode( Dart_CObject* reference, DeserializeState state) { BackRefNode* value = - reinterpret_cast(alloc_(NULL, 0, sizeof(BackRefNode))); + reinterpret_cast(allocator(sizeof(BackRefNode))); value->set_reference(reference); value->set_state(state); return value; @@ -405,7 +407,7 @@ Dart_CObject* ApiMessageReader::ReadVMSymbol(intptr_t object_id) { intptr_t size = (sizeof(*vm_symbol_references_) * Symbols::kMaxPredefinedId); vm_symbol_references_ = - reinterpret_cast(alloc_(NULL, 0, size)); + reinterpret_cast(allocator(size)); memset(vm_symbol_references_, 0, size); } @@ -621,7 +623,7 @@ Dart_CObject* ApiMessageReader::ReadInternalVMObject(intptr_t class_id, intptr_t hash = ReadSmiValue(); USE(hash); uint8_t *latin1 = - reinterpret_cast(::malloc(len * sizeof(uint8_t))); + reinterpret_cast(allocator(len * sizeof(uint8_t))); intptr_t utf8_len = 0; for (intptr_t i = 0; i < len; i++) { latin1[i] = Read(); @@ -635,15 +637,14 @@ Dart_CObject* ApiMessageReader::ReadInternalVMObject(intptr_t class_id, } *p = '\0'; ASSERT(p == (object->value.as_string + utf8_len)); - ::free(latin1); return object; } case kTwoByteStringCid: { intptr_t len = ReadSmiValue(); intptr_t hash = ReadSmiValue(); USE(hash); - uint16_t *utf16 = - reinterpret_cast(::malloc(len * sizeof(uint16_t))); + uint16_t *utf16 = reinterpret_cast( + allocator(len * sizeof(uint16_t))); intptr_t utf8_len = 0; // Read all the UTF-16 code units. for (intptr_t i = 0; i < len; i++) { @@ -670,7 +671,6 @@ Dart_CObject* ApiMessageReader::ReadInternalVMObject(intptr_t class_id, } *p = '\0'; ASSERT(p == (object->value.as_string + utf8_len)); - ::free(utf16); return object; } case kSendPortCid: { diff --git a/runtime/vm/dart_api_message.h b/runtime/vm/dart_api_message.h index 70d55f9eb75..16a138bc44b 100644 --- a/runtime/vm/dart_api_message.h +++ b/runtime/vm/dart_api_message.h @@ -41,14 +41,10 @@ struct Dart_CObject_Internal : public Dart_CObject { // Reads a message snapshot into a C structure. class ApiMessageReader : public BaseReader { public: - // The allocator passed is used to allocate memory for the C structure used - // to represent the message snapshot. This allocator must keep track of the - // memory allocated as there is no way to run through the resulting C - // structure and free the individual pieces. Using a zone based allocator is - // recommended. - ApiMessageReader(const uint8_t* buffer, - intptr_t length, - ReAlloc alloc); + // The ApiMessageReader object must be enclosed by an ApiNativeScope. + // Allocation of all C Heap objects is done in the zone associated with + // the enclosing ApiNativeScope. + ApiMessageReader(const uint8_t* buffer, intptr_t length); ~ApiMessageReader() { } Dart_CObject* ReadMessage(); @@ -139,10 +135,11 @@ class ApiMessageReader : public BaseReader { Dart_CObject* GetCanonicalMintObject(Dart_CObject_Type type, int64_t value64); - // Allocation of the structures for the decoded message happens - // either in the supplied zone or using the supplied allocation - // function. - ReAlloc alloc_; + uint8_t* allocator(intptr_t size) { + return zone_->Realloc(NULL, 0, size); + } + + Zone* zone_; // Zone in which C heap objects are allocated. ApiGrowableArray backward_references_; ApiGrowableArray vm_isolate_references_; Dart_CObject** vm_symbol_references_; diff --git a/runtime/vm/native_message_handler.cc b/runtime/vm/native_message_handler.cc index 08bc7e97175..da869e2d9c8 100644 --- a/runtime/vm/native_message_handler.cc +++ b/runtime/vm/native_message_handler.cc @@ -32,23 +32,16 @@ void NativeMessageHandler::CheckAccess() { #endif -static uint8_t* zone_allocator(uint8_t* ptr, - intptr_t old_size, - intptr_t new_size) { - Zone* zone = ApiNativeScope::Current()->zone(); - return zone->Realloc(ptr, old_size, new_size); -} - - bool NativeMessageHandler::HandleMessage(Message* message) { if (message->IsOOB()) { // We currently do not use OOB messages for native ports. UNREACHABLE(); } - // Enter a native scope for handling the message. This will create a - // zone for allocating the objects for decoding the message. + // We create a native scope for handling the message. + // All allocation of objects for decoding the message is done in the + // zone associated with this scope. ApiNativeScope scope; - ApiMessageReader reader(message->data(), message->len(), zone_allocator); + ApiMessageReader reader(message->data(), message->len()); Dart_CObject* object = reader.ReadMessage(); (*func())(message->dest_port(), object); delete message; diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc index be0e815b5a1..9c67df8e791 100644 --- a/runtime/vm/snapshot_test.cc +++ b/runtime/vm/snapshot_test.cc @@ -135,7 +135,7 @@ static void CheckEncodeDecodeMessage(Dart_CObject* root) { ApiMessageWriter writer(&buffer, &malloc_allocator); writer.WriteCMessage(root); - ApiMessageReader api_reader(buffer, writer.BytesWritten(), &zone_allocator); + ApiMessageReader api_reader(buffer, writer.BytesWritten()); Dart_CObject* new_root = api_reader.ReadMessage(); // Check that the two messages are the same. @@ -171,7 +171,7 @@ TEST_CASE(SerializeNull) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kNull, root->type); @@ -199,7 +199,7 @@ TEST_CASE(SerializeSmi1) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kInt32, root->type); @@ -228,7 +228,7 @@ TEST_CASE(SerializeSmi2) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kInt32, root->type); @@ -257,7 +257,7 @@ Dart_CObject* SerializeAndDeserializeMint(const Mint& mint) { } // Read object back from the snapshot into a C structure. - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); CheckEncodeDecodeMessage(root); @@ -331,7 +331,7 @@ TEST_CASE(SerializeDouble) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kDouble, root->type); @@ -362,7 +362,7 @@ TEST_CASE(SerializeTrue) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kBool, root->type); @@ -391,7 +391,7 @@ TEST_CASE(SerializeFalse) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kBool, root->type); @@ -427,7 +427,7 @@ TEST_CASE(SerializeCapability) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kCapability, root->type); @@ -462,7 +462,7 @@ TEST_CASE(SerializeBigint) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kBigint, root->type); @@ -498,7 +498,7 @@ Dart_CObject* SerializeAndDeserializeBigint(const Bigint& bigint) { } // Read object back from the snapshot into a C structure. - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); // Bigint not supported. EXPECT_NOTNULL(root); @@ -593,7 +593,7 @@ static void TestString(const char* cstr) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_EQ(Dart_CObject_kString, root->type); EXPECT_STREQ(cstr, root->value.as_string); @@ -643,7 +643,7 @@ TEST_CASE(SerializeArray) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -730,7 +730,7 @@ TEST_CASE(SerializeEmptyArray) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -765,7 +765,7 @@ TEST_CASE(SerializeByteArray) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_EQ(Dart_CObject_kTypedData, root->type); EXPECT_EQ(kTypedDataLength, root->value.as_typed_data.length); @@ -878,7 +878,7 @@ TEST_CASE(SerializeEmptyByteArray) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_EQ(Dart_CObject_kTypedData, root->type); EXPECT_EQ(Dart_TypedData_kUint8, root->value.as_typed_data.type); @@ -1730,9 +1730,7 @@ TEST_CASE(IntArrayMessage) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, - writer.BytesWritten(), - &zone_allocator); + ApiMessageReader api_reader(buffer, writer.BytesWritten()); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -1766,7 +1764,7 @@ static uint8_t* GetSerialized(Dart_Handle lib, // Helper function to deserialize the result into a Dart_CObject structure. static Dart_CObject* GetDeserialized(uint8_t* buffer, intptr_t buffer_len) { // Read object back from the snapshot into a C structure. - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); return api_reader.ReadMessage(); } @@ -1782,7 +1780,7 @@ static void CheckString(Dart_Handle dart_string, const char* expected) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kString, root->type); @@ -1802,7 +1800,7 @@ static void CheckStringInvalid(Dart_Handle dart_string) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kUnsupported, root->type); @@ -1912,7 +1910,7 @@ UNIT_TEST_CASE(DartGeneratedMessages) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kInt32, root->type); @@ -1930,7 +1928,7 @@ UNIT_TEST_CASE(DartGeneratedMessages) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator); + ApiMessageReader api_reader(buffer, buffer_len); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kBigint, root->type);