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

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
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 #define EXTERNAL_PEER_HELPER(type, ctype, raw_obj, peer) \
Ivan Posva 2013/08/22 15:44:51 Is this #define really worth the added confusion?
siva 2013/08/22 16:57:08 Removed the macro and inline the code below. On 2
244 type* raw_string = reinterpret_cast<type*>(raw_obj)->ptr(); \
245 ExternalStringData<ctype>* data = raw_string->external_data_; \
246 *peer = data->peer(); \
244 247
245 248 bool Api::StringGetPeerHelper(Dart_NativeArguments args,
246 #define EXTERNAL_PEER_HELPER(cid, raw_obj, peer) \ 249 int arg_index,
247 switch (cid) { \ 250 void** peer) {
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; 251 NoGCScope no_gc_scope;
270 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); 252 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
271 RawObject* raw_obj = arguments->NativeArgAt(arg_index); 253 RawObject* raw_obj = arguments->NativeArgAt(arg_index);
272 intptr_t cid = raw_obj->GetClassId(); 254 intptr_t cid = raw_obj->GetClassId();
273 EXTERNAL_PEER_HELPER(cid, raw_obj, peer); 255 if (cid == kExternalOneByteStringCid) {
274 } 256 EXTERNAL_PEER_HELPER(RawExternalOneByteString, uint8_t, raw_obj, peer);
275 257 return true;
276 258 }
277 bool Api::ExternalStringGetPeerHelper(Dart_Handle object, void** peer) { 259 if (cid == kOneByteStringCid || cid == kTwoByteStringCid) {
278 NoGCScope no_gc_scope; 260 *peer = Isolate::Current()->heap()->GetPeer(raw_obj);
Ivan Posva 2013/08/22 15:44:51 args carries the isolate or pass it in from the ca
siva 2013/08/22 16:57:08 Good point. On 2013/08/22 15:44:51, Ivan Posva wr
279 RawObject* raw_obj = Api::UnwrapHandle(object); 261 return (*peer != 0);
280 EXTERNAL_PEER_HELPER(Api::ClassId(object), raw_obj, peer); 262 }
263 if (cid == kExternalTwoByteStringCid) {
264 EXTERNAL_PEER_HELPER(RawExternalTwoByteString, uint16_t, raw_obj, peer);
265 return true;
266 }
267 return false;
281 } 268 }
282 269
283 270
284 void Api::SetWeakHandleReturnValue(NativeArguments* args, 271 void Api::SetWeakHandleReturnValue(NativeArguments* args,
285 Dart_WeakPersistentHandle retval) { 272 Dart_WeakPersistentHandle retval) {
286 args->SetReturnUnsafe(Api::UnwrapAsWeakPersistentHandle(retval)->raw()); 273 args->SetReturnUnsafe(Api::UnwrapAsWeakPersistentHandle(retval)->raw());
287 } 274 }
288 275
289 276
290 // --- Handles --- 277 // --- Handles ---
(...skipping 1349 matching lines...) Expand 10 before | Expand all | Expand 10 after
1640 DARTSCOPE(isolate); 1627 DARTSCOPE(isolate);
1641 if (utf32_array == NULL && length != 0) { 1628 if (utf32_array == NULL && length != 0) {
1642 RETURN_NULL_ERROR(utf32_array); 1629 RETURN_NULL_ERROR(utf32_array);
1643 } 1630 }
1644 CHECK_LENGTH(length, String::kMaxElements); 1631 CHECK_LENGTH(length, String::kMaxElements);
1645 CHECK_CALLBACK_STATE(isolate); 1632 CHECK_CALLBACK_STATE(isolate);
1646 return Api::NewHandle(isolate, String::FromUTF32(utf32_array, length)); 1633 return Api::NewHandle(isolate, String::FromUTF32(utf32_array, length));
1647 } 1634 }
1648 1635
1649 1636
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( 1637 DART_EXPORT Dart_Handle Dart_NewExternalLatin1String(
1673 const uint8_t* latin1_array, 1638 const uint8_t* latin1_array,
1674 intptr_t length, 1639 intptr_t length,
1675 void* peer, 1640 void* peer,
1676 Dart_PeerFinalizer cback) { 1641 Dart_PeerFinalizer cback) {
1677 Isolate* isolate = Isolate::Current(); 1642 Isolate* isolate = Isolate::Current();
1678 DARTSCOPE(isolate); 1643 DARTSCOPE(isolate);
1679 if (latin1_array == NULL && length != 0) { 1644 if (latin1_array == NULL && length != 0) {
1680 RETURN_NULL_ERROR(latin1_array); 1645 RETURN_NULL_ERROR(latin1_array);
1681 } 1646 }
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1835 intptr_t str_size = (str_obj.Length() * str_obj.CharSize()); 1800 intptr_t str_size = (str_obj.Length() * str_obj.CharSize());
1836 if ((length < str_size) || (length > String::kMaxElements)) { 1801 if ((length < str_size) || (length > String::kMaxElements)) {
1837 return Api::NewError("Dart_MakeExternalString " 1802 return Api::NewError("Dart_MakeExternalString "
1838 "expects argument length to be in the range" 1803 "expects argument length to be in the range"
1839 "[%"Pd"..%"Pd"].", 1804 "[%"Pd"..%"Pd"].",
1840 str_size, String::kMaxElements); 1805 str_size, String::kMaxElements);
1841 } 1806 }
1842 if (str_obj.InVMHeap()) { 1807 if (str_obj.InVMHeap()) {
1843 // Since the string object is read only we do not externalize 1808 // Since the string object is read only we do not externalize
1844 // the string but instead copy the contents of the string into the 1809 // the string but instead copy the contents of the string into the
1845 // specified buffer and return a Null object. 1810 // specified buffer add the specified peer/cback as a Peer object
1846 // This ensures that the embedder does not have to call again 1811 // to this string. The Api::StringGetPeerHelper function picks up
1847 // to get at the contents. 1812 // the peer from the Peer table.
1848 intptr_t copy_len = str_obj.Length(); 1813 intptr_t copy_len = str_obj.Length();
1849 if (str_obj.IsOneByteString()) { 1814 if (str_obj.IsOneByteString()) {
1850 ASSERT(length >= copy_len); 1815 ASSERT(length >= copy_len);
1851 uint8_t* latin1_array = reinterpret_cast<uint8_t*>(array); 1816 uint8_t* latin1_array = reinterpret_cast<uint8_t*>(array);
1852 for (intptr_t i = 0; i < copy_len; i++) { 1817 for (intptr_t i = 0; i < copy_len; i++) {
1853 latin1_array[i] = static_cast<uint8_t>(str_obj.CharAt(i)); 1818 latin1_array[i] = static_cast<uint8_t>(str_obj.CharAt(i));
1854 } 1819 }
1820 OneByteString::SetPeer(str_obj, peer, cback);
1855 } else { 1821 } else {
1856 ASSERT(str_obj.IsTwoByteString()); 1822 ASSERT(str_obj.IsTwoByteString());
1857 ASSERT(length >= (copy_len * str_obj.CharSize())); 1823 ASSERT(length >= (copy_len * str_obj.CharSize()));
1858 uint16_t* utf16_array = reinterpret_cast<uint16_t*>(array); 1824 uint16_t* utf16_array = reinterpret_cast<uint16_t*>(array);
1859 for (intptr_t i = 0; i < copy_len; i++) { 1825 for (intptr_t i = 0; i < copy_len; i++) {
1860 utf16_array[i] = static_cast<uint16_t>(str_obj.CharAt(i)); 1826 utf16_array[i] = static_cast<uint16_t>(str_obj.CharAt(i));
1861 } 1827 }
1828 TwoByteString::SetPeer(str_obj, peer, cback);
1862 } 1829 }
1863 return Api::Null(); 1830 return str;
1864 } 1831 }
1865 return Api::NewHandle(isolate, 1832 return Api::NewHandle(isolate,
1866 str_obj.MakeExternal(array, length, peer, cback)); 1833 str_obj.MakeExternal(array, length, peer, cback));
1867 } 1834 }
1868 1835
1869 1836
1870 DART_EXPORT Dart_Handle Dart_StringGetProperties(Dart_Handle object, 1837 DART_EXPORT Dart_Handle Dart_StringGetProperties(Dart_Handle object,
1871 intptr_t* char_size, 1838 intptr_t* char_size,
1872 intptr_t* str_len, 1839 intptr_t* str_len,
1873 void** peer) { 1840 void** peer) {
1874 Isolate* isolate = Isolate::Current(); 1841 Isolate* isolate = Isolate::Current();
1875 DARTSCOPE(isolate); 1842 DARTSCOPE(isolate);
1876 const String& str = Api::UnwrapStringHandle(isolate, object); 1843 const String& str = Api::UnwrapStringHandle(isolate, object);
1877 if (str.IsNull()) { 1844 if (str.IsNull()) {
1878 RETURN_TYPE_ERROR(isolate, object, String); 1845 RETURN_TYPE_ERROR(isolate, object, String);
1879 } 1846 }
1880 if (str.IsExternal()) { 1847 if (str.IsExternal()) {
1881 *peer = str.GetPeer(); 1848 *peer = str.GetPeer();
1882 ASSERT(*peer != NULL); 1849 ASSERT(*peer != NULL);
1883 } else { 1850 } else {
1884 *peer = NULL; 1851 NoGCScope no_gc_scope;
1852 *peer = isolate->heap()->GetPeer(str.raw());
1885 } 1853 }
1886 *char_size = str.CharSize(); 1854 *char_size = str.CharSize();
1887 *str_len = str.Length(); 1855 *str_len = str.Length();
1888 return Api::Success(); 1856 return Api::Success();
1889 } 1857 }
1890 1858
1891 1859
1892 // --- Lists --- 1860 // --- Lists ---
1893 1861
1894 DART_EXPORT Dart_Handle Dart_NewList(intptr_t length) { 1862 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(); 3665 return Api::Success();
3698 } 3666 }
3699 3667
3700 3668
3701 DART_EXPORT Dart_Handle Dart_GetNativeStringArgument(Dart_NativeArguments args, 3669 DART_EXPORT Dart_Handle Dart_GetNativeStringArgument(Dart_NativeArguments args,
3702 int arg_index, 3670 int arg_index,
3703 void** peer) { 3671 void** peer) {
3704 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); 3672 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
3705 Isolate* isolate = arguments->isolate(); 3673 Isolate* isolate = arguments->isolate();
3706 CHECK_ISOLATE(isolate); 3674 CHECK_ISOLATE(isolate);
3707 if (Api::ExternalStringGetPeerHelper(args, arg_index, peer)) { 3675 if (Api::StringGetPeerHelper(args, arg_index, peer)) {
3708 return Api::Success(); 3676 return Api::Success();
Ivan Posva 2013/08/22 15:44:51 This function does not do what it is documented to
siva 2013/08/22 16:57:08 Updated comment to reflect this. If a peer is pres
3709 } 3677 }
3710 *peer = NULL; 3678 *peer = NULL;
3711 ReusableObjectHandleScope reused_obj_handle(isolate); 3679 ReusableObjectHandleScope reused_obj_handle(isolate);
3712 Object& obj = reused_obj_handle.Handle(); 3680 Object& obj = reused_obj_handle.Handle();
3713 obj = arguments->NativeArgAt(arg_index); 3681 obj = arguments->NativeArgAt(arg_index);
3714 if (RawObject::IsStringClassId(obj.GetClassId())) { 3682 if (RawObject::IsStringClassId(obj.GetClassId())) {
3715 return Api::NewHandle(isolate, obj.raw()); 3683 return Api::NewHandle(isolate, obj.raw());
3716 } 3684 }
3717 return Api::NewError("%s expects argument to be of" 3685 return Api::NewError("%s expects argument to be of"
3718 " type String.", CURRENT_FUNC); 3686 " type String.", CURRENT_FUNC);
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
4249 } 4217 }
4250 { 4218 {
4251 NoGCScope no_gc; 4219 NoGCScope no_gc;
4252 RawObject* raw_obj = obj.raw(); 4220 RawObject* raw_obj = obj.raw();
4253 isolate->heap()->SetPeer(raw_obj, peer); 4221 isolate->heap()->SetPeer(raw_obj, peer);
4254 } 4222 }
4255 return Api::Success(); 4223 return Api::Success();
4256 } 4224 }
4257 4225
4258 } // namespace dart 4226 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698