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

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: addressed comments 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') | 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 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 NoGCScope no_gc;
2146 memmove(native_array,
2147 reinterpret_cast<uint8_t*>(array.DataAddr(offset)),
2148 length);
2149 return Api::Success();
2150 }
2151
2152
2139 DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list, 2153 DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list,
2140 intptr_t offset, 2154 intptr_t offset,
2141 uint8_t* native_array, 2155 uint8_t* native_array,
2142 intptr_t length) { 2156 intptr_t length) {
2143 Isolate* isolate = Isolate::Current(); 2157 Isolate* isolate = Isolate::Current();
2144 DARTSCOPE(isolate); 2158 DARTSCOPE(isolate);
2145 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(list)); 2159 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(list));
2146 if (obj.IsTypedData()) { 2160 if (obj.IsTypedData()) {
2147 const TypedData& array = TypedData::Cast(obj); 2161 const TypedData& array = TypedData::Cast(obj);
2148 if (array.ElementSizeInBytes() == 1) { 2162 if (array.ElementSizeInBytes() == 1) {
2149 if (Utils::RangeCheck(offset, length, array.Length())) { 2163 if (!Utils::RangeCheck(offset, length, array.Length())) {
2150 NoGCScope no_gc; 2164 return Api::NewError(
2151 memmove(native_array, 2165 "Invalid length passed in to access list elements");
2152 reinterpret_cast<uint8_t*>(array.DataAddr(offset)),
2153 length);
2154 return Api::Success();
2155 } 2166 }
2156 return Api::NewError("Invalid length passed in to access list elements"); 2167 return CopyBytes(array, offset, native_array, length);
2168 }
2169 }
2170 if (RawObject::IsTypedDataViewClassId(obj.GetClassId())) {
2171 const Instance& view = Instance::Cast(obj);
2172 if (TypedDataView::ElementSizeInBytes(view) == 1) {
2173 intptr_t view_length = Smi::Value(TypedDataView::Length(view));
2174 if (!Utils::RangeCheck(offset, length, view_length)) {
2175 return Api::NewError(
2176 "Invalid length passed in to access list elements");
2177 }
2178 const Instance& data = Instance::Handle(TypedDataView::Data(view));
2179 if (data.IsTypedData()) {
Ivan Posva 2013/08/05 03:45:00 How can this ever not be a typed data? I would exp
Florian Schneider 2013/08/05 08:38:09 Not sure: the view constructor takes just a ByteBu
2180 const TypedData& array = TypedData::Cast(data);
2181 if (array.ElementSizeInBytes() == 1) {
2182 intptr_t data_offset =
2183 Smi::Value(TypedDataView::OffsetInBytes(view)) + offset;
2184 // Range check already performed on the view object.
2185 ASSERT(Utils::RangeCheck(data_offset, length, array.Length()));
2186 return CopyBytes(array, data_offset, native_array, length);
2187 }
2188 }
2157 } 2189 }
2158 } 2190 }
2159 if (obj.IsArray()) { 2191 if (obj.IsArray()) {
2160 GET_LIST_ELEMENT_AS_BYTES(isolate, 2192 GET_LIST_ELEMENT_AS_BYTES(isolate,
2161 Array, 2193 Array,
2162 obj, 2194 obj,
2163 native_array, 2195 native_array,
2164 offset, 2196 offset,
2165 length); 2197 length);
2166 } 2198 }
(...skipping 19 matching lines...) Expand all
2186 Array::Handle(ArgumentsDescriptor::New(kNumArgs))); 2218 Array::Handle(ArgumentsDescriptor::New(kNumArgs)));
2187 const Function& function = Function::Handle( 2219 const Function& function = Function::Handle(
2188 isolate, 2220 isolate,
2189 Resolver::ResolveDynamic(instance, Symbols::IndexToken(), args_desc)); 2221 Resolver::ResolveDynamic(instance, Symbols::IndexToken(), args_desc));
2190 if (!function.IsNull()) { 2222 if (!function.IsNull()) {
2191 Object& result = Object::Handle(isolate); 2223 Object& result = Object::Handle(isolate);
2192 Integer& intobj = Integer::Handle(isolate); 2224 Integer& intobj = Integer::Handle(isolate);
2193 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); 2225 const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
2194 args.SetAt(0, instance); // Set up the receiver as the first argument. 2226 args.SetAt(0, instance); // Set up the receiver as the first argument.
2195 for (int i = 0; i < length; i++) { 2227 for (int i = 0; i < length; i++) {
2228 HANDLESCOPE(isolate);
2196 intobj = Integer::New(offset + i); 2229 intobj = Integer::New(offset + i);
2197 args.SetAt(1, intobj); 2230 args.SetAt(1, intobj);
2198 result = DartEntry::InvokeFunction(function, args); 2231 result = DartEntry::InvokeFunction(function, args);
2199 if (result.IsError()) { 2232 if (result.IsError()) {
2200 return Api::NewHandle(isolate, result.raw()); 2233 return Api::NewHandle(isolate, result.raw());
2201 } 2234 }
2202 if (!result.IsInteger()) { 2235 if (!result.IsInteger()) {
2203 return Api::NewError("%s expects the argument 'list' to be " 2236 return Api::NewError("%s expects the argument 'list' to be "
2204 "a List of int", CURRENT_FUNC); 2237 "a List of int", CURRENT_FUNC);
2205 } 2238 }
(...skipping 1903 matching lines...) Expand 10 before | Expand all | Expand 10 after
4109 } 4142 }
4110 { 4143 {
4111 NoGCScope no_gc; 4144 NoGCScope no_gc;
4112 RawObject* raw_obj = obj.raw(); 4145 RawObject* raw_obj = obj.raw();
4113 isolate->heap()->SetPeer(raw_obj, peer); 4146 isolate->heap()->SetPeer(raw_obj, peer);
4114 } 4147 }
4115 return Api::Success(); 4148 return Api::Success();
4116 } 4149 }
4117 4150
4118 } // namespace dart 4151 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/dart_api_impl_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698