Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: runtime/vm/dart_api_message.cc

Issue 14142008: Add support for more typed data types on native ports (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/dart_api_message.h" 5 #include "vm/dart_api_message.h"
6 #include "vm/object.h" 6 #include "vm/object.h"
7 #include "vm/snapshot_ids.h" 7 #include "vm/snapshot_ids.h"
8 #include "vm/symbols.h" 8 #include "vm/symbols.h"
9 #include "vm/unicode.h" 9 #include "vm/unicode.h"
10 10
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 Dart_CObject* value = 118 Dart_CObject* value =
119 reinterpret_cast<Dart_CObject*>( 119 reinterpret_cast<Dart_CObject*>(
120 alloc_(NULL, 0, sizeof(Dart_CObject) + length + 1)); 120 alloc_(NULL, 0, sizeof(Dart_CObject) + length + 1));
121 ASSERT(value != NULL); 121 ASSERT(value != NULL);
122 value->value.as_string = reinterpret_cast<char*>(value) + sizeof(*value); 122 value->value.as_string = reinterpret_cast<char*>(value) + sizeof(*value);
123 value->type = Dart_CObject::kString; 123 value->type = Dart_CObject::kString;
124 return value; 124 return value;
125 } 125 }
126 126
127 127
128 Dart_CObject* ApiMessageReader::AllocateDartCObjectUint8Array(intptr_t length) { 128 static int SizeInBytes(Dart_CObject::TypedDataType type) {
129 switch (type) {
130 case Dart_CObject::kInt8Array:
131 case Dart_CObject::kUint8Array:
132 return 1;
133 case Dart_CObject::kInt16Array:
134 case Dart_CObject::kUint16Array:
135 return 2;
136 default:
137 break;
138 }
139 UNREACHABLE();
140 return -1;
141 }
142
143
144 Dart_CObject* ApiMessageReader::AllocateDartCObjectTypedData(
145 Dart_CObject::TypedDataType type, intptr_t length) {
129 // Allocate a Dart_CObject structure followed by an array of bytes 146 // Allocate a Dart_CObject structure followed by an array of bytes
130 // for the byte array content. The pointer to the byte array content 147 // for the byte array content. The pointer to the byte array content
131 // is set up to this area. 148 // is set up to this area.
149 intptr_t length_in_bytes = SizeInBytes(type) * length;
siva 2013/04/15 23:28:45 The code for SizeInBytes is duplicated here and in
132 Dart_CObject* value = 150 Dart_CObject* value =
133 reinterpret_cast<Dart_CObject*>( 151 reinterpret_cast<Dart_CObject*>(
134 alloc_(NULL, 0, sizeof(Dart_CObject) + length)); 152 alloc_(NULL, 0, sizeof(Dart_CObject) + length_in_bytes));
135 ASSERT(value != NULL); 153 ASSERT(value != NULL);
136 value->type = Dart_CObject::kUint8Array; 154 value->type = Dart_CObject::kTypedData;
137 value->value.as_array.length = length; 155 value->value.as_typed_data.type = type;
156 value->value.as_typed_data.length = length_in_bytes;
138 if (length > 0) { 157 if (length > 0) {
139 value->value.as_byte_array.values = 158 value->value.as_typed_data.values =
140 reinterpret_cast<uint8_t*>(value) + sizeof(*value); 159 reinterpret_cast<uint8_t*>(value) + sizeof(*value);
141 } else { 160 } else {
142 value->value.as_byte_array.values = NULL; 161 value->value.as_typed_data.values = NULL;
143 } 162 }
144 return value; 163 return value;
145 } 164 }
146 165
147 166
148 Dart_CObject* ApiMessageReader::AllocateDartCObjectArray(intptr_t length) { 167 Dart_CObject* ApiMessageReader::AllocateDartCObjectArray(intptr_t length) {
149 // Allocate a Dart_CObject structure followed by an array of 168 // Allocate a Dart_CObject structure followed by an array of
150 // pointers to Dart_CObject structures. The pointer to the array 169 // pointers to Dart_CObject structures. The pointer to the array
151 // content is set up to this area. 170 // content is set up to this area.
152 Dart_CObject* value = 171 Dart_CObject* value =
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 Dart_CObject* reference, 203 Dart_CObject* reference,
185 DeserializeState state) { 204 DeserializeState state) {
186 BackRefNode* value = 205 BackRefNode* value =
187 reinterpret_cast<BackRefNode*>(alloc_(NULL, 0, sizeof(BackRefNode))); 206 reinterpret_cast<BackRefNode*>(alloc_(NULL, 0, sizeof(BackRefNode)));
188 value->set_reference(reference); 207 value->set_reference(reference);
189 value->set_state(state); 208 value->set_state(state);
190 return value; 209 return value;
191 } 210 }
192 211
193 212
213 static Dart_CObject::TypedDataType GetTypedDataTypeFromView(
214 Dart_CObject_Internal* object) {
215 struct {
216 const char* name;
217 Dart_CObject::TypedDataType type;
218 } view_class_names[] = {
219 { "_Int8ArrayView", Dart_CObject::kInt8Array },
220 { "_Uint8ArrayView", Dart_CObject::kUint8Array },
221 { "_Int16ArrayView", Dart_CObject::kInt16Array },
222 { "_Uint16ArrayView", Dart_CObject::kUint16Array },
223 { NULL, Dart_CObject::kNumberOfTypedDataTypes },
224 };
225
226 char* library_url =
227 object->cls->internal.as_class.library_url->value.as_string;
228 char* class_name =
229 object->cls->internal.as_class.class_name->value.as_string;
230 if (strcmp("dart:typeddata", library_url) != 0) {
231 return Dart_CObject::kNumberOfTypedDataTypes;
232 }
233 int i = 0;
234 while (view_class_names[i].name != NULL) {
235 if (strncmp(view_class_names[i].name,
236 class_name,
237 strlen(view_class_names[i].name)) == 0) {
238 return view_class_names[i].type;
239 }
240 i++;
241 }
242 return Dart_CObject::kNumberOfTypedDataTypes;
243 }
244
245
246 static int GetTypedDataTypeElementSize(Dart_CObject::TypedDataType type) {
247 switch (type) {
248 case Dart_CObject::kInt8Array:
249 case Dart_CObject::kUint8Array:
250 return 1;
251 case Dart_CObject::kInt16Array:
252 case Dart_CObject::kUint16Array:
253 return 2;
254 default:
255 break;
256 }
257 UNREACHABLE();
258 return -1;
259 }
siva 2013/04/15 23:28:45 Ditto comment about GetTypedDataTypeElementSize, m
260
261
194 Dart_CObject* ApiMessageReader::ReadInlinedObject(intptr_t object_id) { 262 Dart_CObject* ApiMessageReader::ReadInlinedObject(intptr_t object_id) {
195 // Read the class header information and lookup the class. 263 // Read the class header information and lookup the class.
196 intptr_t class_header = ReadIntptrValue(); 264 intptr_t class_header = ReadIntptrValue();
197 intptr_t tags = ReadIntptrValue(); 265 intptr_t tags = ReadIntptrValue();
198 USE(tags); 266 USE(tags);
199 intptr_t class_id; 267 intptr_t class_id;
200 268
201 // There is limited support for reading regular dart instances. Only 269 // There is limited support for reading regular dart instances. Only
202 // typed data views are currently handled. 270 // typed data views are currently handled.
203 if (SerializedHeaderData::decode(class_header) == kInstanceObjectId) { 271 if (SerializedHeaderData::decode(class_header) == kInstanceObjectId) {
204 Dart_CObject_Internal* object = 272 Dart_CObject_Internal* object =
205 reinterpret_cast<Dart_CObject_Internal*>(GetBackRef(object_id)); 273 reinterpret_cast<Dart_CObject_Internal*>(GetBackRef(object_id));
206 if (object == NULL) { 274 if (object == NULL) {
207 object = 275 object =
208 AllocateDartCObjectInternal(Dart_CObject_Internal::kUninitialized); 276 AllocateDartCObjectInternal(Dart_CObject_Internal::kUninitialized);
209 AddBackRef(object_id, object, kIsDeserialized); 277 AddBackRef(object_id, object, kIsDeserialized);
210 // Read class of object. 278 // Read class of object.
211 object->cls = reinterpret_cast<Dart_CObject_Internal*>(ReadObjectImpl()); 279 object->cls = reinterpret_cast<Dart_CObject_Internal*>(ReadObjectImpl());
212 ASSERT(object->cls->type == 280 ASSERT(object->cls->type ==
213 static_cast<Dart_CObject::Type>(Dart_CObject_Internal::kClass)); 281 static_cast<Dart_CObject::Type>(Dart_CObject_Internal::kClass));
214 } 282 }
215 ASSERT(object->type == 283 ASSERT(object->type ==
216 static_cast<Dart_CObject::Type>( 284 static_cast<Dart_CObject::Type>(
217 Dart_CObject_Internal::kUninitialized)); 285 Dart_CObject_Internal::kUninitialized));
218 286
219 // Handle typed data views. 287 // Handle typed data views.
220 char* library_url = 288 Dart_CObject::TypedDataType type = GetTypedDataTypeFromView(object);
221 object->cls->internal.as_class.library_url->value.as_string; 289 if (type != Dart_CObject::kNumberOfTypedDataTypes) {
222 char* class_name =
223 object->cls->internal.as_class.class_name->value.as_string;
224 if (strcmp("dart:typeddata", library_url) == 0 &&
225 strncmp("_Uint8ArrayView", class_name, 15) == 0) {
226 object->type = 290 object->type =
227 static_cast<Dart_CObject::Type>(Dart_CObject_Internal::kView); 291 static_cast<Dart_CObject::Type>(Dart_CObject_Internal::kView);
228 // Skip type arguments. 292 ReadObjectImpl(); // Skip type arguments.
229 ReadObjectImpl();
230 object->internal.as_view.buffer = ReadObjectImpl(); 293 object->internal.as_view.buffer = ReadObjectImpl();
231 object->internal.as_view.offset_in_bytes = ReadSmiValue(); 294 object->internal.as_view.offset_in_bytes = ReadSmiValue();
232 object->internal.as_view.length = ReadSmiValue(); 295 object->internal.as_view.length = ReadSmiValue();
296 ReadObjectImpl(); // Skip last field.
233 297
234 // The buffer is fully read now as typed data objects are 298 // The buffer is fully read now as typed data objects are
235 // serialized in-line. 299 // serialized in-line.
236 Dart_CObject* buffer = object->internal.as_view.buffer; 300 Dart_CObject* buffer = object->internal.as_view.buffer;
237 ASSERT(buffer->type == Dart_CObject::kUint8Array); 301 ASSERT(buffer->type == Dart_CObject::kTypedData);
238 302
239 // Now turn the view into a byte array. 303 // Now turn the view into a byte array.
240 object->type = Dart_CObject::kUint8Array; 304 object->type = Dart_CObject::kTypedData;
241 object->value.as_byte_array.length = object->internal.as_view.length; 305 object->value.as_typed_data.type = type;
242 object->value.as_byte_array.values = 306 object->value.as_typed_data.length =
243 buffer->value.as_byte_array.values + 307 object->internal.as_view.length *
308 GetTypedDataTypeElementSize(type);
309 object->value.as_typed_data.values =
310 buffer->value.as_typed_data.values +
244 object->internal.as_view.offset_in_bytes; 311 object->internal.as_view.offset_in_bytes;
245 } else { 312 } else {
246 // TODO(sgjesse): Handle other instances. Currently this will 313 // TODO(sgjesse): Handle other instances. Currently this will
247 // skew the reading as the fields of the instance is not read. 314 // skew the reading as the fields of the instance is not read.
248 } 315 }
249 return object; 316 return object;
250 } 317 }
251 318
252 ASSERT((class_header & kSmiTagMask) != 0); 319 ASSERT((class_header & kSmiTagMask) != 0);
253 class_id = LookupInternalClass(class_header); 320 class_id = LookupInternalClass(class_header);
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 char* p = object->value.as_string; 569 char* p = object->value.as_string;
503 i = 0; 570 i = 0;
504 while (i < len) { 571 while (i < len) {
505 p += Utf8::Encode(Utf16::Next(utf16, &i, len), p); 572 p += Utf8::Encode(Utf16::Next(utf16, &i, len), p);
506 } 573 }
507 *p = '\0'; 574 *p = '\0';
508 ASSERT(p == (object->value.as_string + utf8_len)); 575 ASSERT(p == (object->value.as_string + utf8_len));
509 ::free(utf16); 576 ::free(utf16);
510 return object; 577 return object;
511 } 578 }
579
580 #define READ_TYPED_DATA(type, ctype) \
581 { \
582 intptr_t len = ReadSmiValue(); \
583 Dart_CObject* object = \
584 AllocateDartCObjectTypedData(Dart_CObject::k##type##Array, len); \
585 AddBackRef(object_id, object, kIsDeserialized); \
586 if (len > 0) { \
587 ctype* p = \
588 reinterpret_cast<ctype*>(object->value.as_typed_data.values); \
589 for (intptr_t i = 0; i < len; i++) { \
590 p[i] = Read<ctype>(); \
591 } \
592 } \
593 return object; \
594 } \
595
596 case kTypedDataInt8ArrayCid:
597 case kExternalTypedDataInt8ArrayCid:
598 READ_TYPED_DATA(Int8, int8_t);
599
512 case kTypedDataUint8ArrayCid: 600 case kTypedDataUint8ArrayCid:
513 case kExternalTypedDataUint8ArrayCid: { 601 case kExternalTypedDataUint8ArrayCid:
514 intptr_t len = ReadSmiValue(); 602 READ_TYPED_DATA(Uint8, uint8_t);
515 Dart_CObject* object = AllocateDartCObjectUint8Array(len); 603
516 AddBackRef(object_id, object, kIsDeserialized); 604 case kTypedDataInt16ArrayCid:
517 if (len > 0) { 605 case kExternalTypedDataInt16ArrayCid:
518 uint8_t* p = object->value.as_byte_array.values; 606 READ_TYPED_DATA(Int16, int16_t);
519 for (intptr_t i = 0; i < len; i++) { 607
520 p[i] = Read<uint8_t>(); 608 case kTypedDataUint16ArrayCid:
521 } 609 case kExternalTypedDataUint16ArrayCid:
522 } 610 READ_TYPED_DATA(Uint16, uint16_t);
523 return object; 611
524 }
525 case kGrowableObjectArrayCid: { 612 case kGrowableObjectArrayCid: {
526 // A GrowableObjectArray is serialized as its length followed by 613 // A GrowableObjectArray is serialized as its length followed by
527 // its backing store. The backing store is an array with a 614 // its backing store. The backing store is an array with a
528 // length which might be longer than the length of the 615 // length which might be longer than the length of the
529 // GrowableObjectArray. 616 // GrowableObjectArray.
530 intptr_t len = ReadSmiValue(); 617 intptr_t len = ReadSmiValue();
531 618
532 Dart_CObject* value = GetBackRef(object_id); 619 Dart_CObject* value = GetBackRef(object_id);
533 ASSERT(value == NULL); 620 ASSERT(value == NULL);
534 // Allocate an empty array for the GrowableObjectArray which 621 // Allocate an empty array for the GrowableObjectArray which
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 reinterpret_cast<uint16_t*>(::malloc(len * sizeof(uint16_t))); 1004 reinterpret_cast<uint16_t*>(::malloc(len * sizeof(uint16_t)));
918 bool success = Utf8::DecodeToUTF16(utf8_str, utf8_len, utf16_str, len); 1005 bool success = Utf8::DecodeToUTF16(utf8_str, utf8_len, utf16_str, len);
919 ASSERT(success); 1006 ASSERT(success);
920 for (intptr_t i = 0; i < len; i++) { 1007 for (intptr_t i = 0; i < len; i++) {
921 Write<uint16_t>(utf16_str[i]); 1008 Write<uint16_t>(utf16_str[i]);
922 } 1009 }
923 ::free(utf16_str); 1010 ::free(utf16_str);
924 } 1011 }
925 break; 1012 break;
926 } 1013 }
927 case Dart_CObject::kUint8Array: { 1014 case Dart_CObject::kTypedData: {
928 // Write out the serialization header value for this object. 1015 // Write out the serialization header value for this object.
929 WriteInlinedHeader(object); 1016 WriteInlinedHeader(object);
930 // Write out the class and tags information. 1017 // Write out the class and tags information.
931 WriteIndexedObject(kTypedDataUint8ArrayCid); 1018 intptr_t class_id;
932 WriteIntptrValue(RawObject::ClassIdTag::update( 1019 switch (object->value.as_typed_data.type) {
933 kTypedDataUint8ArrayCid, 0)); 1020 case Dart_CObject::kInt8Array:
934 uint8_t* bytes = object->value.as_byte_array.values; 1021 class_id = kTypedDataInt8ArrayCid;
935 intptr_t len = object->value.as_byte_array.length; 1022 break;
1023 case Dart_CObject::kUint8Array:
1024 class_id = kTypedDataUint8ArrayCid;
1025 break;
1026 default:
1027 UNIMPLEMENTED();
1028 }
1029
1030 WriteIndexedObject(class_id);
1031 WriteIntptrValue(RawObject::ClassIdTag::update(class_id, 0));
1032 uint8_t* bytes = object->value.as_typed_data.values;
1033 intptr_t len = object->value.as_typed_data.length;
936 WriteSmi(len); 1034 WriteSmi(len);
937 for (intptr_t i = 0; i < len; i++) { 1035 for (intptr_t i = 0; i < len; i++) {
938 Write<uint8_t>(bytes[i]); 1036 Write<uint8_t>(bytes[i]);
939 } 1037 }
940 break; 1038 break;
941 } 1039 }
942 case Dart_CObject::kExternalUint8Array: { 1040 case Dart_CObject::kExternalTypedData: {
943 // TODO(ager): we are writing C pointers into the message in 1041 // TODO(ager): we are writing C pointers into the message in
944 // order to post external arrays through ports. We need to make 1042 // order to post external arrays through ports. We need to make
945 // sure that messages containing pointers can never be posted 1043 // sure that messages containing pointers can never be posted
946 // to other processes. 1044 // to other processes.
947 1045
948 // Write out serialization header value for this object. 1046 // Write out serialization header value for this object.
949 WriteInlinedHeader(object); 1047 WriteInlinedHeader(object);
950 // Write out the class and tag information. 1048 // Write out the class and tag information.
951 WriteIndexedObject(kExternalTypedDataUint8ArrayCid); 1049 WriteIndexedObject(kExternalTypedDataUint8ArrayCid);
952 WriteIntptrValue(RawObject::ClassIdTag::update( 1050 WriteIntptrValue(RawObject::ClassIdTag::update(
953 kExternalTypedDataUint8ArrayCid, 0)); 1051 kExternalTypedDataUint8ArrayCid, 0));
954 int length = object->value.as_external_byte_array.length; 1052 int length = object->value.as_external_typed_data.length;
955 uint8_t* data = object->value.as_external_byte_array.data; 1053 uint8_t* data = object->value.as_external_typed_data.data;
956 void* peer = object->value.as_external_byte_array.peer; 1054 void* peer = object->value.as_external_typed_data.peer;
957 Dart_WeakPersistentHandleFinalizer callback = 1055 Dart_WeakPersistentHandleFinalizer callback =
958 object->value.as_external_byte_array.callback; 1056 object->value.as_external_typed_data.callback;
959 WriteSmi(length); 1057 WriteSmi(length);
960 WriteIntptrValue(reinterpret_cast<intptr_t>(data)); 1058 WriteIntptrValue(reinterpret_cast<intptr_t>(data));
961 WriteIntptrValue(reinterpret_cast<intptr_t>(peer)); 1059 WriteIntptrValue(reinterpret_cast<intptr_t>(peer));
962 WriteIntptrValue(reinterpret_cast<intptr_t>(callback)); 1060 WriteIntptrValue(reinterpret_cast<intptr_t>(callback));
963 break; 1061 break;
964 } 1062 }
965 default: 1063 default:
966 UNREACHABLE(); 1064 UNREACHABLE();
967 } 1065 }
968 1066
(...skipping 15 matching lines...) Expand all
984 if (!success) { 1082 if (!success) {
985 UnmarkAllCObjects(object); 1083 UnmarkAllCObjects(object);
986 return false; 1084 return false;
987 } 1085 }
988 } 1086 }
989 UnmarkAllCObjects(object); 1087 UnmarkAllCObjects(object);
990 return true; 1088 return true;
991 } 1089 }
992 1090
993 } // namespace dart 1091 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698