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

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

Issue 22980022: Setup a peer for read only strings that are not externalized in (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 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
« no previous file with comments | « runtime/vm/dart_api_impl.h ('k') | runtime/vm/dart_api_impl_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 "include/dart_api.h" 5 #include "include/dart_api.h"
6 #include "include/dart_mirrors_api.h" 6 #include "include/dart_mirrors_api.h"
7 #include "include/dart_native_api.h" 7 #include "include/dart_native_api.h"
8 8
9 #include "platform/assert.h" 9 #include "platform/assert.h"
10 #include "vm/bigint_operations.h" 10 #include "vm/bigint_operations.h"
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 true_handle_ = Api::NewHandle(isolate, Bool::True().raw()); 233 true_handle_ = Api::NewHandle(isolate, Bool::True().raw());
234 234
235 ASSERT(false_handle_ == NULL); 235 ASSERT(false_handle_ == NULL);
236 false_handle_ = Api::NewHandle(isolate, Bool::False().raw()); 236 false_handle_ = Api::NewHandle(isolate, Bool::False().raw());
237 237
238 ASSERT(null_handle_ == NULL); 238 ASSERT(null_handle_ == NULL);
239 null_handle_ = Api::NewHandle(isolate, Object::null()); 239 null_handle_ = Api::NewHandle(isolate, Object::null());
240 } 240 }
241 241
242 242
243 #define GET_PEER(type, ctype, raw_obj, peer) \ 243 bool Api::StringGetPeerHelper(Dart_NativeArguments args,
244 244 int arg_index,
245 245 void** peer) {
246 #define EXTERNAL_PEER_HELPER(cid, raw_obj, peer) \
247 switch (cid) { \
248 case kExternalOneByteStringCid: { \
249 RawExternalOneByteString* raw_string = \
250 reinterpret_cast<RawExternalOneByteString*>(raw_obj)->ptr(); \
251 ExternalStringData<uint8_t>* data = raw_string->external_data_; \
252 *peer = data->peer(); \
253 return true; \
254 } \
255 case kExternalTwoByteStringCid: { \
256 RawExternalTwoByteString* raw_string = \
257 reinterpret_cast<RawExternalTwoByteString*>(raw_obj)->ptr(); \
258 ExternalStringData<uint16_t>* data = raw_string->external_data_; \
259 *peer = data->peer(); \
260 return true; \
261 } \
262 } \
263 return false; \
264
265
266 bool Api::ExternalStringGetPeerHelper(Dart_NativeArguments args,
267 int arg_index,
268 void** peer) {
269 NoGCScope no_gc_scope; 246 NoGCScope no_gc_scope;
270 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); 247 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
271 RawObject* raw_obj = arguments->NativeArgAt(arg_index); 248 RawObject* raw_obj = arguments->NativeArgAt(arg_index);
272 intptr_t cid = raw_obj->GetClassId(); 249 intptr_t cid = raw_obj->GetClassId();
273 EXTERNAL_PEER_HELPER(cid, raw_obj, peer); 250 if (cid == kExternalOneByteStringCid) {
274 } 251 RawExternalOneByteString* raw_string =
275 252 reinterpret_cast<RawExternalOneByteString*>(raw_obj)->ptr();
276 253 ExternalStringData<uint8_t>* data = raw_string->external_data_;
277 bool Api::ExternalStringGetPeerHelper(Dart_Handle object, void** peer) { 254 *peer = data->peer();
278 NoGCScope no_gc_scope; 255 return true;
279 RawObject* raw_obj = Api::UnwrapHandle(object); 256 }
280 EXTERNAL_PEER_HELPER(Api::ClassId(object), raw_obj, peer); 257 if (cid == kOneByteStringCid || cid == kTwoByteStringCid) {
258 Isolate* isolate = arguments->isolate();
259 *peer = isolate->heap()->GetPeer(raw_obj);
260 return (*peer != 0);
261 }
262 if (cid == kExternalTwoByteStringCid) {
263 RawExternalTwoByteString* raw_string =
264 reinterpret_cast<RawExternalTwoByteString*>(raw_obj)->ptr();
265 ExternalStringData<uint16_t>* data = raw_string->external_data_;
266 *peer = data->peer();
267 return true;
268 }
269 return false;
281 } 270 }
282 271
283 272
284 void Api::SetWeakHandleReturnValue(NativeArguments* args, 273 void Api::SetWeakHandleReturnValue(NativeArguments* args,
285 Dart_WeakPersistentHandle retval) { 274 Dart_WeakPersistentHandle retval) {
286 args->SetReturnUnsafe(Api::UnwrapAsWeakPersistentHandle(retval)->raw()); 275 args->SetReturnUnsafe(Api::UnwrapAsWeakPersistentHandle(retval)->raw());
287 } 276 }
288 277
289 278
290 // --- Handles --- 279 // --- Handles ---
(...skipping 1349 matching lines...) Expand 10 before | Expand all | Expand 10 after
1640 DARTSCOPE(isolate); 1629 DARTSCOPE(isolate);
1641 if (utf32_array == NULL && length != 0) { 1630 if (utf32_array == NULL && length != 0) {
1642 RETURN_NULL_ERROR(utf32_array); 1631 RETURN_NULL_ERROR(utf32_array);
1643 } 1632 }
1644 CHECK_LENGTH(length, String::kMaxElements); 1633 CHECK_LENGTH(length, String::kMaxElements);
1645 CHECK_CALLBACK_STATE(isolate); 1634 CHECK_CALLBACK_STATE(isolate);
1646 return Api::NewHandle(isolate, String::FromUTF32(utf32_array, length)); 1635 return Api::NewHandle(isolate, String::FromUTF32(utf32_array, length));
1647 } 1636 }
1648 1637
1649 1638
1650 DART_EXPORT Dart_Handle Dart_ExternalStringGetPeer(Dart_Handle object,
1651 void** peer) {
1652 if (peer == NULL) {
1653 RETURN_NULL_ERROR(peer);
1654 }
1655
1656 if (Api::ExternalStringGetPeerHelper(object, peer)) {
1657 return Api::Success();
1658 }
1659
1660 // It's not an external string, return appropriate error.
1661 if (!RawObject::IsStringClassId(Api::ClassId(object))) {
1662 RETURN_TYPE_ERROR(Isolate::Current(), object, String);
1663 } else {
1664 return
1665 Api::NewError(
1666 "%s expects argument 'object' to be an external String.",
1667 CURRENT_FUNC);
1668 }
1669 }
1670
1671
1672 DART_EXPORT Dart_Handle Dart_NewExternalLatin1String( 1639 DART_EXPORT Dart_Handle Dart_NewExternalLatin1String(
1673 const uint8_t* latin1_array, 1640 const uint8_t* latin1_array,
1674 intptr_t length, 1641 intptr_t length,
1675 void* peer, 1642 void* peer,
1676 Dart_PeerFinalizer cback) { 1643 Dart_PeerFinalizer cback) {
1677 Isolate* isolate = Isolate::Current(); 1644 Isolate* isolate = Isolate::Current();
1678 DARTSCOPE(isolate); 1645 DARTSCOPE(isolate);
1679 if (latin1_array == NULL && length != 0) { 1646 if (latin1_array == NULL && length != 0) {
1680 RETURN_NULL_ERROR(latin1_array); 1647 RETURN_NULL_ERROR(latin1_array);
1681 } 1648 }
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1835 intptr_t str_size = (str_obj.Length() * str_obj.CharSize()); 1802 intptr_t str_size = (str_obj.Length() * str_obj.CharSize());
1836 if ((length < str_size) || (length > String::kMaxElements)) { 1803 if ((length < str_size) || (length > String::kMaxElements)) {
1837 return Api::NewError("Dart_MakeExternalString " 1804 return Api::NewError("Dart_MakeExternalString "
1838 "expects argument length to be in the range" 1805 "expects argument length to be in the range"
1839 "[%" Pd "..%" Pd "].", 1806 "[%" Pd "..%" Pd "].",
1840 str_size, String::kMaxElements); 1807 str_size, String::kMaxElements);
1841 } 1808 }
1842 if (str_obj.InVMHeap()) { 1809 if (str_obj.InVMHeap()) {
1843 // Since the string object is read only we do not externalize 1810 // Since the string object is read only we do not externalize
1844 // the string but instead copy the contents of the string into the 1811 // the string but instead copy the contents of the string into the
1845 // specified buffer and return a Null object. 1812 // specified buffer add the specified peer/cback as a Peer object
1846 // This ensures that the embedder does not have to call again 1813 // to this string. The Api::StringGetPeerHelper function picks up
1847 // to get at the contents. 1814 // the peer from the Peer table.
1848 intptr_t copy_len = str_obj.Length(); 1815 intptr_t copy_len = str_obj.Length();
1849 if (str_obj.IsOneByteString()) { 1816 if (str_obj.IsOneByteString()) {
1850 ASSERT(length >= copy_len); 1817 ASSERT(length >= copy_len);
1851 uint8_t* latin1_array = reinterpret_cast<uint8_t*>(array); 1818 uint8_t* latin1_array = reinterpret_cast<uint8_t*>(array);
1852 for (intptr_t i = 0; i < copy_len; i++) { 1819 for (intptr_t i = 0; i < copy_len; i++) {
1853 latin1_array[i] = static_cast<uint8_t>(str_obj.CharAt(i)); 1820 latin1_array[i] = static_cast<uint8_t>(str_obj.CharAt(i));
1854 } 1821 }
1822 OneByteString::SetPeer(str_obj, peer, cback);
1855 } else { 1823 } else {
1856 ASSERT(str_obj.IsTwoByteString()); 1824 ASSERT(str_obj.IsTwoByteString());
1857 ASSERT(length >= (copy_len * str_obj.CharSize())); 1825 ASSERT(length >= (copy_len * str_obj.CharSize()));
1858 uint16_t* utf16_array = reinterpret_cast<uint16_t*>(array); 1826 uint16_t* utf16_array = reinterpret_cast<uint16_t*>(array);
1859 for (intptr_t i = 0; i < copy_len; i++) { 1827 for (intptr_t i = 0; i < copy_len; i++) {
1860 utf16_array[i] = static_cast<uint16_t>(str_obj.CharAt(i)); 1828 utf16_array[i] = static_cast<uint16_t>(str_obj.CharAt(i));
1861 } 1829 }
1830 TwoByteString::SetPeer(str_obj, peer, cback);
1862 } 1831 }
1863 return Api::Null(); 1832 return str;
1864 } 1833 }
1865 return Api::NewHandle(isolate, 1834 return Api::NewHandle(isolate,
1866 str_obj.MakeExternal(array, length, peer, cback)); 1835 str_obj.MakeExternal(array, length, peer, cback));
1867 } 1836 }
1868 1837
1869 1838
1870 DART_EXPORT Dart_Handle Dart_StringGetProperties(Dart_Handle object, 1839 DART_EXPORT Dart_Handle Dart_StringGetProperties(Dart_Handle object,
1871 intptr_t* char_size, 1840 intptr_t* char_size,
1872 intptr_t* str_len, 1841 intptr_t* str_len,
1873 void** peer) { 1842 void** peer) {
1874 Isolate* isolate = Isolate::Current(); 1843 Isolate* isolate = Isolate::Current();
1875 DARTSCOPE(isolate); 1844 DARTSCOPE(isolate);
1876 const String& str = Api::UnwrapStringHandle(isolate, object); 1845 const String& str = Api::UnwrapStringHandle(isolate, object);
1877 if (str.IsNull()) { 1846 if (str.IsNull()) {
1878 RETURN_TYPE_ERROR(isolate, object, String); 1847 RETURN_TYPE_ERROR(isolate, object, String);
1879 } 1848 }
1880 if (str.IsExternal()) { 1849 if (str.IsExternal()) {
1881 *peer = str.GetPeer(); 1850 *peer = str.GetPeer();
1882 ASSERT(*peer != NULL); 1851 ASSERT(*peer != NULL);
1883 } else { 1852 } else {
1884 *peer = NULL; 1853 NoGCScope no_gc_scope;
1854 *peer = isolate->heap()->GetPeer(str.raw());
1885 } 1855 }
1886 *char_size = str.CharSize(); 1856 *char_size = str.CharSize();
1887 *str_len = str.Length(); 1857 *str_len = str.Length();
1888 return Api::Success(); 1858 return Api::Success();
1889 } 1859 }
1890 1860
1891 1861
1892 // --- Lists --- 1862 // --- Lists ---
1893 1863
1894 DART_EXPORT Dart_Handle Dart_NewList(intptr_t length) { 1864 DART_EXPORT Dart_Handle Dart_NewList(intptr_t length) {
(...skipping 1802 matching lines...) Expand 10 before | Expand all | Expand 10 after
3697 return Api::Success(); 3667 return Api::Success();
3698 } 3668 }
3699 3669
3700 3670
3701 DART_EXPORT Dart_Handle Dart_GetNativeStringArgument(Dart_NativeArguments args, 3671 DART_EXPORT Dart_Handle Dart_GetNativeStringArgument(Dart_NativeArguments args,
3702 int arg_index, 3672 int arg_index,
3703 void** peer) { 3673 void** peer) {
3704 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); 3674 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
3705 Isolate* isolate = arguments->isolate(); 3675 Isolate* isolate = arguments->isolate();
3706 CHECK_ISOLATE(isolate); 3676 CHECK_ISOLATE(isolate);
3707 if (Api::ExternalStringGetPeerHelper(args, arg_index, peer)) { 3677 if (Api::StringGetPeerHelper(args, arg_index, peer)) {
3708 return Api::Success(); 3678 return Api::Success();
3709 } 3679 }
3710 *peer = NULL; 3680 *peer = NULL;
3711 ReusableObjectHandleScope reused_obj_handle(isolate); 3681 ReusableObjectHandleScope reused_obj_handle(isolate);
3712 Object& obj = reused_obj_handle.Handle(); 3682 Object& obj = reused_obj_handle.Handle();
3713 obj = arguments->NativeArgAt(arg_index); 3683 obj = arguments->NativeArgAt(arg_index);
3714 if (RawObject::IsStringClassId(obj.GetClassId())) { 3684 if (RawObject::IsStringClassId(obj.GetClassId())) {
3715 return Api::NewHandle(isolate, obj.raw()); 3685 return Api::NewHandle(isolate, obj.raw());
3716 } 3686 }
3717 return Api::NewError("%s expects argument to be of" 3687 return Api::NewError("%s expects argument to be of"
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
4351 } 4321 }
4352 { 4322 {
4353 NoGCScope no_gc; 4323 NoGCScope no_gc;
4354 RawObject* raw_obj = obj.raw(); 4324 RawObject* raw_obj = obj.raw();
4355 isolate->heap()->SetPeer(raw_obj, peer); 4325 isolate->heap()->SetPeer(raw_obj, peer);
4356 } 4326 }
4357 return Api::Success(); 4327 return Api::Success();
4358 } 4328 }
4359 4329
4360 } // namespace dart 4330 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/dart_api_impl.h ('k') | runtime/vm/dart_api_impl_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698