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

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

Issue 21562002: Improve performance of Dart_ListGetAsBytes. (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 | « no previous file | runtime/vm/dart_api_impl_test.cc » ('j') | runtime/vm/dart_api_impl_test.cc » ('J')
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 2118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2129 } \ 2129 } \
2130 const Integer& integer = Integer::Cast(element); \ 2130 const Integer& integer = Integer::Cast(element); \
2131 native_array[i] = static_cast<uint8_t>(integer.AsInt64Value() & 0xff); \ 2131 native_array[i] = static_cast<uint8_t>(integer.AsInt64Value() & 0xff); \
2132 ASSERT(integer.AsInt64Value() <= 0xff); \ 2132 ASSERT(integer.AsInt64Value() <= 0xff); \
2133 } \ 2133 } \
2134 return Api::Success(); \ 2134 return Api::Success(); \
2135 } \ 2135 } \
2136 return Api::NewError("Invalid length passed in to access array elements"); \ 2136 return Api::NewError("Invalid length passed in to access array elements"); \
2137 2137
2138 2138
2139 static Dart_Handle CopyBytes(const TypedData& array,
2140 intptr_t offset,
2141 uint8_t* native_array,
2142 intptr_t length) {
2143 ASSERT(array.IsTypedData());
2144 ASSERT(array.ElementSizeInBytes() == 1);
2145 if (!Utils::RangeCheck(offset, length, array.Length())) {
2146 return Api::NewError("Invalid length passed in to access list elements");
2147 }
2148 NoGCScope no_gc;
2149 memmove(native_array,
2150 reinterpret_cast<uint8_t*>(array.DataAddr(offset)),
2151 length);
2152 return Api::Success();
2153 }
2154
2155
2139 DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list, 2156 DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list,
2140 intptr_t offset, 2157 intptr_t offset,
2141 uint8_t* native_array, 2158 uint8_t* native_array,
2142 intptr_t length) { 2159 intptr_t length) {
2143 Isolate* isolate = Isolate::Current(); 2160 Isolate* isolate = Isolate::Current();
2144 DARTSCOPE(isolate); 2161 DARTSCOPE(isolate);
2145 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(list)); 2162 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(list));
2146 if (obj.IsTypedData()) { 2163 if (obj.IsTypedData()) {
2147 const TypedData& array = TypedData::Cast(obj); 2164 const TypedData& array = TypedData::Cast(obj);
2148 if (array.ElementSizeInBytes() == 1) { 2165 if (array.ElementSizeInBytes() == 1) {
2149 if (Utils::RangeCheck(offset, length, array.Length())) { 2166 return CopyBytes(array, offset, native_array, length);
2150 NoGCScope no_gc; 2167 }
2151 memmove(native_array, 2168 }
2152 reinterpret_cast<uint8_t*>(array.DataAddr(offset)), 2169 if (RawObject::IsTypedDataViewClassId(obj.GetClassId())) {
2153 length); 2170 const Instance& view = Instance::Cast(obj);
2154 return Api::Success(); 2171 if (TypedDataView::ElementSizeInBytes(view) == 1) {
2172 intptr_t view_length = Smi::Value(TypedDataView::Length(view));
2173 if (!Utils::RangeCheck(offset, length, view_length)) {
2174 return Api::NewError(
2175 "Invalid length passed in to access list elements");
2155 } 2176 }
2156 return Api::NewError("Invalid length passed in to access list elements"); 2177 const Instance& data = Instance::Handle(TypedDataView::Data(view));
2178 intptr_t data_offset =
2179 Smi::Value(TypedDataView::OffsetInBytes(view)) + offset;
siva 2013/08/01 16:29:31 This data_offset computation can be moved inside t
Florian Schneider 2013/08/02 11:07:33 Done.
2180 if (data.IsTypedData()) {
2181 const TypedData& array = TypedData::Cast(data);
2182 if (array.ElementSizeInBytes() == 1) {
2183 return CopyBytes(array, data_offset, native_array, length);
siva 2013/08/01 16:29:31 We end up doing the range check twice in this case
Florian Schneider 2013/08/02 11:07:33 Agree. The second range check is redundant becaus
2184 }
2185 }
2157 } 2186 }
2158 } 2187 }
2159 if (obj.IsArray()) { 2188 if (obj.IsArray()) {
2160 GET_LIST_ELEMENT_AS_BYTES(isolate, 2189 GET_LIST_ELEMENT_AS_BYTES(isolate,
2161 Array, 2190 Array,
2162 obj, 2191 obj,
2163 native_array, 2192 native_array,
2164 offset, 2193 offset,
2165 length); 2194 length);
2166 } 2195 }
(...skipping 19 matching lines...) Expand all
2186 Array::Handle(ArgumentsDescriptor::New(kNumArgs))); 2215 Array::Handle(ArgumentsDescriptor::New(kNumArgs)));
2187 const Function& function = Function::Handle( 2216 const Function& function = Function::Handle(
2188 isolate, 2217 isolate,
2189 Resolver::ResolveDynamic(instance, Symbols::IndexToken(), args_desc)); 2218 Resolver::ResolveDynamic(instance, Symbols::IndexToken(), args_desc));
2190 if (!function.IsNull()) { 2219 if (!function.IsNull()) {
2191 Object& result = Object::Handle(isolate); 2220 Object& result = Object::Handle(isolate);
2192 Integer& intobj = Integer::Handle(isolate); 2221 Integer& intobj = Integer::Handle(isolate);
2193 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); 2222 const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
2194 args.SetAt(0, instance); // Set up the receiver as the first argument. 2223 args.SetAt(0, instance); // Set up the receiver as the first argument.
2195 for (int i = 0; i < length; i++) { 2224 for (int i = 0; i < length; i++) {
2225 HandleScope handle_scope(isolate);
siva 2013/08/01 16:29:31 Could you use HANDLESCOPE(isolate); here to be con
Florian Schneider 2013/08/02 11:07:33 Done.
2196 intobj = Integer::New(offset + i); 2226 intobj = Integer::New(offset + i);
2197 args.SetAt(1, intobj); 2227 args.SetAt(1, intobj);
2198 result = DartEntry::InvokeFunction(function, args); 2228 result = DartEntry::InvokeFunction(function, args);
2199 if (result.IsError()) { 2229 if (result.IsError()) {
2200 return Api::NewHandle(isolate, result.raw()); 2230 return Api::NewHandle(isolate, result.raw());
2201 } 2231 }
2202 if (!result.IsInteger()) { 2232 if (!result.IsInteger()) {
2203 return Api::NewError("%s expects the argument 'list' to be " 2233 return Api::NewError("%s expects the argument 'list' to be "
2204 "a List of int", CURRENT_FUNC); 2234 "a List of int", CURRENT_FUNC);
2205 } 2235 }
(...skipping 1903 matching lines...) Expand 10 before | Expand all | Expand 10 after
4109 } 4139 }
4110 { 4140 {
4111 NoGCScope no_gc; 4141 NoGCScope no_gc;
4112 RawObject* raw_obj = obj.raw(); 4142 RawObject* raw_obj = obj.raw();
4113 isolate->heap()->SetPeer(raw_obj, peer); 4143 isolate->heap()->SetPeer(raw_obj, peer);
4114 } 4144 }
4115 return Api::Success(); 4145 return Api::Success();
4116 } 4146 }
4117 4147
4118 } // namespace dart 4148 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/dart_api_impl_test.cc » ('j') | runtime/vm/dart_api_impl_test.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698