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

Side by Side Diff: src/accessors.cc

Issue 1195823002: Add fast path for setting length (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 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
« no previous file with comments | « src/accessors.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/contexts.h" 9 #include "src/contexts.h"
10 #include "src/deoptimizer.h" 10 #include "src/deoptimizer.h"
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 return MakeAccessor(isolate, name, &ArgumentsIteratorGetter, 166 return MakeAccessor(isolate, name, &ArgumentsIteratorGetter,
167 &ArgumentsIteratorSetter, attributes); 167 &ArgumentsIteratorSetter, attributes);
168 } 168 }
169 169
170 170
171 // 171 //
172 // Accessors::ArrayLength 172 // Accessors::ArrayLength
173 // 173 //
174 174
175 175
176 // The helper function will 'flatten' Number objects.
177 Handle<Object> Accessors::FlattenNumber(Isolate* isolate,
178 Handle<Object> value) {
179 if (value->IsNumber() || !value->IsJSValue()) return value;
180 Handle<JSValue> wrapper = Handle<JSValue>::cast(value);
181 DCHECK(wrapper->GetIsolate()->native_context()->number_function()->
182 has_initial_map());
183 if (wrapper->map() == isolate->number_function()->initial_map()) {
184 return handle(wrapper->value(), isolate);
185 }
186
187 return value;
188 }
189
190
191 void Accessors::ArrayLengthGetter( 176 void Accessors::ArrayLengthGetter(
192 v8::Local<v8::Name> name, 177 v8::Local<v8::Name> name,
193 const v8::PropertyCallbackInfo<v8::Value>& info) { 178 const v8::PropertyCallbackInfo<v8::Value>& info) {
194 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 179 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
195 DisallowHeapAllocation no_allocation; 180 DisallowHeapAllocation no_allocation;
196 HandleScope scope(isolate); 181 HandleScope scope(isolate);
197 JSArray* holder = JSArray::cast(*Utils::OpenHandle(*info.Holder())); 182 JSArray* holder = JSArray::cast(*Utils::OpenHandle(*info.Holder()));
198 Object* result = holder->length(); 183 Object* result = holder->length();
199 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate))); 184 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
200 } 185 }
201 186
202 187
188 // Tries to non-observably convert |value| to a valid array length.
189 // Returns false if it fails.
190 static bool FastAsArrayLength(Isolate* isolate, Handle<Object> value,
191 uint32_t* length) {
192 if (value->ToArrayLength(length)) return true;
193 // We don't support AsArrayLength, so use AsArrayIndex for now. This just
194 // misses out on kMaxUInt32.
195 if (value->IsString()) return String::cast(*value)->AsArrayIndex(length);
196 if (!value->IsJSValue()) return false;
197 Handle<JSValue> wrapper = Handle<JSValue>::cast(value);
198 DCHECK(wrapper->GetIsolate()
199 ->native_context()
200 ->number_function()
201 ->has_initial_map());
202 // Only support fast unwrapping for the initial map. Otherwise valueOf might
203 // have been overwritten, in which case unwrapping is invalid.
204 if (wrapper->map() != isolate->number_function()->initial_map()) return false;
205 return wrapper->value()->ToArrayIndex(length);
Toon Verwaest 2015/06/19 20:48:57 I think this is actually wrong... Number.prototyp
Jakob Kummerow 2015/06/20 11:26:38 Good point, in addition to checking the wrapper's
206 }
207
208
203 void Accessors::ArrayLengthSetter( 209 void Accessors::ArrayLengthSetter(
204 v8::Local<v8::Name> name, 210 v8::Local<v8::Name> name,
205 v8::Local<v8::Value> val, 211 v8::Local<v8::Value> val,
206 const v8::PropertyCallbackInfo<void>& info) { 212 const v8::PropertyCallbackInfo<void>& info) {
207 // TODO(verwaest): Speed up.
208 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 213 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
209 HandleScope scope(isolate); 214 HandleScope scope(isolate);
215
210 Handle<JSObject> object = Utils::OpenHandle(*info.This()); 216 Handle<JSObject> object = Utils::OpenHandle(*info.This());
211 Handle<Object> value = Utils::OpenHandle(*val); 217 Handle<JSArray> array = Handle<JSArray>::cast(object);
218 Handle<Object> length_obj = Utils::OpenHandle(*val);
212 219
213 value = FlattenNumber(isolate, value); 220 uint32_t length = 0;
221 if (!FastAsArrayLength(isolate, length_obj, &length)) {
222 Handle<Object> uint32_v;
223 if (!Execution::ToUint32(isolate, length_obj).ToHandle(&uint32_v)) {
224 isolate->OptionalRescheduleException(false);
225 return;
226 }
214 227
215 Handle<JSArray> array_handle = Handle<JSArray>::cast(object); 228 Handle<Object> number_v;
216 MaybeHandle<Object> maybe; 229 if (!Execution::ToNumber(isolate, length_obj).ToHandle(&number_v)) {
217 Handle<Object> uint32_v; 230 isolate->OptionalRescheduleException(false);
218 maybe = Execution::ToUint32(isolate, value); 231 return;
219 if (!maybe.ToHandle(&uint32_v)) { 232 }
220 isolate->OptionalRescheduleException(false); 233
221 return; 234 if (uint32_v->Number() != number_v->Number()) {
222 } 235 Handle<Object> exception = isolate->factory()->NewRangeError(
223 Handle<Object> number_v; 236 MessageTemplate::kInvalidArrayLength);
224 maybe = Execution::ToNumber(isolate, value); 237 return isolate->ScheduleThrow(*exception);
225 if (!maybe.ToHandle(&number_v)) { 238 }
226 isolate->OptionalRescheduleException(false); 239
227 return; 240 CHECK(uint32_v->ToArrayLength(&length));
228 } 241 }
229 242
230 if (uint32_v->Number() == number_v->Number()) { 243 if (JSArray::ObservableSetLength(array, length).is_null()) {
231 uint32_t new_length = 0; 244 isolate->OptionalRescheduleException(false);
232 CHECK(uint32_v->ToArrayLength(&new_length));
233 maybe = JSArray::ObservableSetLength(array_handle, new_length);
234 if (maybe.is_null()) isolate->OptionalRescheduleException(false);
235 return;
236 } 245 }
237
238 Handle<Object> exception =
239 isolate->factory()->NewRangeError(MessageTemplate::kInvalidArrayLength);
240 isolate->ScheduleThrow(*exception);
241 } 246 }
242 247
243 248
244 Handle<AccessorInfo> Accessors::ArrayLengthInfo( 249 Handle<AccessorInfo> Accessors::ArrayLengthInfo(
245 Isolate* isolate, PropertyAttributes attributes) { 250 Isolate* isolate, PropertyAttributes attributes) {
246 return MakeAccessor(isolate, 251 return MakeAccessor(isolate,
247 isolate->factory()->length_string(), 252 isolate->factory()->length_string(),
248 &ArrayLengthGetter, 253 &ArrayLengthGetter,
249 &ArrayLengthSetter, 254 &ArrayLengthSetter,
250 attributes); 255 attributes);
(...skipping 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1494 Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport); 1499 Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport);
1495 Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport); 1500 Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport);
1496 info->set_getter(*getter); 1501 info->set_getter(*getter);
1497 if (!(attributes & ReadOnly)) info->set_setter(*setter); 1502 if (!(attributes & ReadOnly)) info->set_setter(*setter);
1498 return info; 1503 return info;
1499 } 1504 }
1500 1505
1501 1506
1502 } // namespace internal 1507 } // namespace internal
1503 } // namespace v8 1508 } // namespace v8
OLDNEW
« no previous file with comments | « src/accessors.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698