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

Side by Side Diff: src/builtins.cc

Issue 1716833002: [runtime] Speed up C++ version of ArrayPush (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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 | « no previous file | src/debug/liveedit.cc » ('j') | src/objects.cc » ('J')
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/builtins.h" 5 #include "src/builtins.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/api-natives.h" 8 #include "src/api-natives.h"
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/base/once.h" 10 #include "src/base/once.h"
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 isolate->is_initial_array_prototype(JSArray::cast(prototype)) && 238 isolate->is_initial_array_prototype(JSArray::cast(prototype)) &&
239 isolate->IsFastArrayConstructorPrototypeChainIntact()) { 239 isolate->IsFastArrayConstructorPrototypeChainIntact()) {
240 return true; 240 return true;
241 } 241 }
242 242
243 // Slow case. 243 // Slow case.
244 PrototypeIterator iter(isolate, receiver); 244 PrototypeIterator iter(isolate, receiver);
245 return PrototypeHasNoElements(&iter); 245 return PrototypeHasNoElements(&iter);
246 } 246 }
247 247
248 248 // Returns |false| if not applicable.
249 // Returns empty handle if not applicable.
250 MUST_USE_RESULT 249 MUST_USE_RESULT
251 inline MaybeHandle<FixedArrayBase> EnsureJSArrayWithWritableFastElements( 250 inline bool EnsureJSArrayWithWritableFastElements(Isolate* isolate,
252 Isolate* isolate, Handle<Object> receiver, Arguments* args, 251 Handle<Object> receiver,
253 int first_added_arg) { 252 Arguments* args,
254 // We explicitly add a HandleScope to avoid creating several copies of the 253 int first_added_arg) {
255 // same handle which would otherwise cause issue when left-trimming later-on. 254 if (!receiver->IsJSArray()) return false;
256 HandleScope scope(isolate);
257 if (!receiver->IsJSArray()) return MaybeHandle<FixedArrayBase>();
258 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 255 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
259 // If there may be elements accessors in the prototype chain, the fast path 256 // If there may be elements accessors in the prototype chain, the fast path
260 // cannot be used if there arguments to add to the array. 257 // cannot be used if there arguments to add to the array.
261 Heap* heap = isolate->heap(); 258 Heap* heap = isolate->heap();
262 if (args != NULL && !IsJSArrayFastElementMovingAllowed(isolate, *array)) { 259 if (args != NULL && !IsJSArrayFastElementMovingAllowed(isolate, *array)) {
263 return MaybeHandle<FixedArrayBase>(); 260 return false;
264 } 261 }
265 if (array->map()->is_observed()) return MaybeHandle<FixedArrayBase>(); 262 if (array->map()->is_observed()) return false;
266 if (!array->map()->is_extensible()) return MaybeHandle<FixedArrayBase>(); 263 if (!array->map()->is_extensible()) return false;
267 Handle<FixedArrayBase> elms(array->elements(), isolate); 264 Map* map = array->elements()->map();
268 Map* map = elms->map();
269 if (map == heap->fixed_array_map()) { 265 if (map == heap->fixed_array_map()) {
270 if (args == NULL || array->HasFastObjectElements()) { 266 if (args == NULL || array->HasFastObjectElements()) {
271 return scope.CloseAndEscape(elms); 267 return true;
272 } 268 }
273 } else if (map == heap->fixed_cow_array_map()) { 269 } else if (map == heap->fixed_cow_array_map()) {
274 elms = JSObject::EnsureWritableFastElements(array); 270 // Use a short-lived HandleScope to avoid creating several copies of the
Toon Verwaest 2016/02/24 10:31:05 Push shouldn't need to EnsureWritableFastElements
271 // elements handle which would cause issues when left-trimming later-on.
272 HandleScope scope(isolate);
273 JSObject::EnsureWritableFastElements(array);
275 if (args == NULL || array->HasFastObjectElements()) { 274 if (args == NULL || array->HasFastObjectElements()) {
276 return scope.CloseAndEscape(elms); 275 return true;
277 } 276 }
278 } else if (map == heap->fixed_double_array_map()) { 277 } else if (map == heap->fixed_double_array_map()) {
279 if (args == NULL) { 278 if (args == NULL) {
280 return scope.CloseAndEscape(elms); 279 return true;
281 } 280 }
282 } else { 281 } else {
283 return MaybeHandle<FixedArrayBase>(); 282 return false;
284 } 283 }
285 284
286 // Adding elements to the array prototype would break code that makes sure 285 // Adding elements to the array prototype would break code that makes sure
287 // it has no elements. Handle that elsewhere. 286 // it has no elements. Handle that elsewhere.
288 if (isolate->IsAnyInitialArrayPrototype(array)) { 287 if (isolate->IsAnyInitialArrayPrototype(array)) {
289 return MaybeHandle<FixedArrayBase>(); 288 return false;
290 } 289 }
291 290
292 // Need to ensure that the arguments passed in args can be contained in 291 // Need to ensure that the arguments passed in args can be contained in
293 // the array. 292 // the array.
294 int args_length = args->length(); 293 int args_length = args->length();
295 if (first_added_arg >= args_length) { 294 if (first_added_arg >= args_length) {
296 return scope.CloseAndEscape(elms); 295 return true;
297 } 296 }
298 297
299 ElementsKind origin_kind = array->map()->elements_kind(); 298 ElementsKind origin_kind = array->map()->elements_kind();
300 DCHECK(!IsFastObjectElementsKind(origin_kind)); 299 DCHECK(!IsFastObjectElementsKind(origin_kind));
301 ElementsKind target_kind = origin_kind; 300 ElementsKind target_kind = origin_kind;
302 { 301 {
303 DisallowHeapAllocation no_gc; 302 DisallowHeapAllocation no_gc;
304 int arg_count = args_length - first_added_arg; 303 int arg_count = args_length - first_added_arg;
305 Object** arguments = args->arguments() - first_added_arg - (arg_count - 1); 304 Object** arguments = args->arguments() - first_added_arg - (arg_count - 1);
306 for (int i = 0; i < arg_count; i++) { 305 for (int i = 0; i < arg_count; i++) {
307 Object* arg = arguments[i]; 306 Object* arg = arguments[i];
308 if (arg->IsHeapObject()) { 307 if (arg->IsHeapObject()) {
309 if (arg->IsHeapNumber()) { 308 if (arg->IsHeapNumber()) {
310 target_kind = FAST_DOUBLE_ELEMENTS; 309 target_kind = FAST_DOUBLE_ELEMENTS;
311 } else { 310 } else {
312 target_kind = FAST_ELEMENTS; 311 target_kind = FAST_ELEMENTS;
313 break; 312 break;
314 } 313 }
315 } 314 }
316 } 315 }
317 } 316 }
318 if (target_kind != origin_kind) { 317 if (target_kind != origin_kind) {
318 // Use a short-lived HandleScope to avoid creating several copies of the
319 // elements handle which would cause issues when left-trimming later-on.
320 HandleScope scope(isolate);
319 JSObject::TransitionElementsKind(array, target_kind); 321 JSObject::TransitionElementsKind(array, target_kind);
320 elms = handle(array->elements(), isolate);
321 } 322 }
322 return scope.CloseAndEscape(elms); 323 return true;
323 } 324 }
324 325
325 326
326 MUST_USE_RESULT static Object* CallJsIntrinsic( 327 MUST_USE_RESULT static Object* CallJsIntrinsic(
327 Isolate* isolate, Handle<JSFunction> function, 328 Isolate* isolate, Handle<JSFunction> function,
328 BuiltinArguments<BuiltinExtraArguments::kNone> args) { 329 BuiltinArguments<BuiltinExtraArguments::kNone> args) {
329 HandleScope handleScope(isolate); 330 HandleScope handleScope(isolate);
330 int argc = args.length() - 1; 331 int argc = args.length() - 1;
331 ScopedVector<Handle<Object> > argv(argc); 332 ScopedVector<Handle<Object> > argv(argc);
332 for (int i = 0; i < argc; ++i) { 333 for (int i = 0; i < argc; ++i) {
(...skipping 19 matching lines...) Expand all
352 return isolate->heap()->undefined_value(); // Make compiler happy. 353 return isolate->heap()->undefined_value(); // Make compiler happy.
353 } 354 }
354 355
355 356
356 BUILTIN(EmptyFunction) { return isolate->heap()->undefined_value(); } 357 BUILTIN(EmptyFunction) { return isolate->heap()->undefined_value(); }
357 358
358 359
359 BUILTIN(ArrayPush) { 360 BUILTIN(ArrayPush) {
360 HandleScope scope(isolate); 361 HandleScope scope(isolate);
361 Handle<Object> receiver = args.receiver(); 362 Handle<Object> receiver = args.receiver();
362 MaybeHandle<FixedArrayBase> maybe_elms_obj = 363 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1)) {
363 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
364 Handle<FixedArrayBase> elms_obj;
365 if (!maybe_elms_obj.ToHandle(&elms_obj)) {
366 return CallJsIntrinsic(isolate, isolate->array_push(), args); 364 return CallJsIntrinsic(isolate, isolate->array_push(), args);
367 } 365 }
368 // Fast Elements Path 366 // Fast Elements Path
369 int push_size = args.length() - 1; 367 int push_size = args.length() - 1;
370 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 368 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
371 int len = Smi::cast(array->length())->value(); 369 int len = Smi::cast(array->length())->value();
372 if (push_size == 0) { 370 if (push_size == 0) {
373 return Smi::FromInt(len); 371 return Smi::FromInt(len);
374 } 372 }
375 if (push_size > 0 && 373 DCHECK(push_size > 0);
376 JSArray::WouldChangeReadOnlyLength(array, len + push_size)) { 374 if (JSArray::HasReadOnlyLength(array)) {
377 return CallJsIntrinsic(isolate, isolate->array_push(), args); 375 return CallJsIntrinsic(isolate, isolate->array_push(), args);
378 } 376 }
379 DCHECK(!array->map()->is_observed()); 377 DCHECK(!array->map()->is_observed());
380 ElementsAccessor* accessor = array->GetElementsAccessor(); 378 ElementsAccessor* accessor = array->GetElementsAccessor();
381 int new_length = accessor->Push(array, elms_obj, &args, push_size); 379 int new_length = accessor->Push(array, handle(array->elements(), isolate),
380 &args, push_size);
382 return Smi::FromInt(new_length); 381 return Smi::FromInt(new_length);
383 } 382 }
384 383
385 384
386 BUILTIN(ArrayPop) { 385 BUILTIN(ArrayPop) {
387 HandleScope scope(isolate); 386 HandleScope scope(isolate);
388 Handle<Object> receiver = args.receiver(); 387 Handle<Object> receiver = args.receiver();
389 MaybeHandle<FixedArrayBase> maybe_elms_obj = 388 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0)) {
390 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
391 Handle<FixedArrayBase> elms_obj;
392 if (!maybe_elms_obj.ToHandle(&elms_obj)) {
393 return CallJsIntrinsic(isolate, isolate->array_pop(), args); 389 return CallJsIntrinsic(isolate, isolate->array_pop(), args);
394 } 390 }
395 391
396 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 392 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
397 DCHECK(!array->map()->is_observed()); 393 DCHECK(!array->map()->is_observed());
398 394
399 uint32_t len = static_cast<uint32_t>(Smi::cast(array->length())->value()); 395 uint32_t len = static_cast<uint32_t>(Smi::cast(array->length())->value());
400 if (len == 0) return isolate->heap()->undefined_value(); 396 if (len == 0) return isolate->heap()->undefined_value();
401 397
402 if (JSArray::HasReadOnlyLength(array)) { 398 if (JSArray::HasReadOnlyLength(array)) {
403 return CallJsIntrinsic(isolate, isolate->array_pop(), args); 399 return CallJsIntrinsic(isolate, isolate->array_pop(), args);
404 } 400 }
405 401
406 Handle<Object> result; 402 Handle<Object> result;
407 if (IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) { 403 if (IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) {
408 // Fast Elements Path 404 // Fast Elements Path
409 result = array->GetElementsAccessor()->Pop(array, elms_obj); 405 result = array->GetElementsAccessor()->Pop(
406 array, handle(array->elements(), isolate));
410 } else { 407 } else {
411 // Use Slow Lookup otherwise 408 // Use Slow Lookup otherwise
412 uint32_t new_length = len - 1; 409 uint32_t new_length = len - 1;
413 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 410 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
414 isolate, result, Object::GetElement(isolate, array, new_length)); 411 isolate, result, Object::GetElement(isolate, array, new_length));
415 JSArray::SetLength(array, new_length); 412 JSArray::SetLength(array, new_length);
416 } 413 }
417 return *result; 414 return *result;
418 } 415 }
419 416
420 417
421 BUILTIN(ArrayShift) { 418 BUILTIN(ArrayShift) {
422 HandleScope scope(isolate); 419 HandleScope scope(isolate);
423 Heap* heap = isolate->heap(); 420 Heap* heap = isolate->heap();
424 Handle<Object> receiver = args.receiver(); 421 Handle<Object> receiver = args.receiver();
425 MaybeHandle<FixedArrayBase> maybe_elms_obj = 422 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0) ||
426 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
427 Handle<FixedArrayBase> elms_obj;
428 if (!maybe_elms_obj.ToHandle(&elms_obj) ||
429 !IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) { 423 !IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) {
430 return CallJsIntrinsic(isolate, isolate->array_shift(), args); 424 return CallJsIntrinsic(isolate, isolate->array_shift(), args);
431 } 425 }
432 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 426 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
433 DCHECK(!array->map()->is_observed()); 427 DCHECK(!array->map()->is_observed());
434 428
435 int len = Smi::cast(array->length())->value(); 429 int len = Smi::cast(array->length())->value();
436 if (len == 0) return heap->undefined_value(); 430 if (len == 0) return heap->undefined_value();
437 431
438 if (JSArray::HasReadOnlyLength(array)) { 432 if (JSArray::HasReadOnlyLength(array)) {
439 return CallJsIntrinsic(isolate, isolate->array_shift(), args); 433 return CallJsIntrinsic(isolate, isolate->array_shift(), args);
440 } 434 }
441 435
442 Handle<Object> first = array->GetElementsAccessor()->Shift(array, elms_obj); 436 Handle<Object> first = array->GetElementsAccessor()->Shift(
437 array, handle(array->elements(), isolate));
443 return *first; 438 return *first;
444 } 439 }
445 440
446 441
447 BUILTIN(ArrayUnshift) { 442 BUILTIN(ArrayUnshift) {
448 HandleScope scope(isolate); 443 HandleScope scope(isolate);
449 Handle<Object> receiver = args.receiver(); 444 Handle<Object> receiver = args.receiver();
450 MaybeHandle<FixedArrayBase> maybe_elms_obj = 445 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1)) {
451 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
452 Handle<FixedArrayBase> elms_obj;
453 if (!maybe_elms_obj.ToHandle(&elms_obj)) {
454 return CallJsIntrinsic(isolate, isolate->array_unshift(), args); 446 return CallJsIntrinsic(isolate, isolate->array_unshift(), args);
455 } 447 }
456 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 448 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
457 DCHECK(!array->map()->is_observed()); 449 DCHECK(!array->map()->is_observed());
458 int to_add = args.length() - 1; 450 int to_add = args.length() - 1;
459 if (to_add == 0) { 451 if (to_add == 0) {
460 return array->length(); 452 return array->length();
461 } 453 }
462 // Currently fixed arrays cannot grow too big, so 454 // Currently fixed arrays cannot grow too big, so
463 // we should never hit this case. 455 // we should never hit this case.
464 DCHECK(to_add <= (Smi::kMaxValue - Smi::cast(array->length())->value())); 456 DCHECK(to_add <= (Smi::kMaxValue - Smi::cast(array->length())->value()));
465 457
466 if (to_add > 0 && JSArray::HasReadOnlyLength(array)) { 458 if (to_add > 0 && JSArray::HasReadOnlyLength(array)) {
467 return CallJsIntrinsic(isolate, isolate->array_unshift(), args); 459 return CallJsIntrinsic(isolate, isolate->array_unshift(), args);
468 } 460 }
469 461
470 ElementsAccessor* accessor = array->GetElementsAccessor(); 462 ElementsAccessor* accessor = array->GetElementsAccessor();
471 int new_length = accessor->Unshift(array, elms_obj, &args, to_add); 463 int new_length = accessor->Unshift(array, handle(array->elements(), isolate),
464 &args, to_add);
472 return Smi::FromInt(new_length); 465 return Smi::FromInt(new_length);
473 } 466 }
474 467
475 468
476 BUILTIN(ArraySlice) { 469 BUILTIN(ArraySlice) {
477 HandleScope scope(isolate); 470 HandleScope scope(isolate);
478 Handle<Object> receiver = args.receiver(); 471 Handle<Object> receiver = args.receiver();
479 Handle<JSObject> object; 472 Handle<JSObject> object;
480 Handle<FixedArrayBase> elms_obj; 473 Handle<FixedArrayBase> elms_obj;
481 int len = -1; 474 int len = -1;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 } 556 }
564 Handle<JSArray> result_array = 557 Handle<JSArray> result_array =
565 accessor->Slice(object, elms_obj, actual_start, actual_end); 558 accessor->Slice(object, elms_obj, actual_start, actual_end);
566 return *result_array; 559 return *result_array;
567 } 560 }
568 561
569 562
570 BUILTIN(ArraySplice) { 563 BUILTIN(ArraySplice) {
571 HandleScope scope(isolate); 564 HandleScope scope(isolate);
572 Handle<Object> receiver = args.receiver(); 565 Handle<Object> receiver = args.receiver();
573 MaybeHandle<FixedArrayBase> maybe_elms_obj = 566 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3)) {
574 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3);
575 Handle<FixedArrayBase> elms_obj;
576 if (!maybe_elms_obj.ToHandle(&elms_obj)) {
577 return CallJsIntrinsic(isolate, isolate->array_splice(), args); 567 return CallJsIntrinsic(isolate, isolate->array_splice(), args);
578 } 568 }
579 // TODO(littledan): Look up @@species only once, not once here and 569 // TODO(littledan): Look up @@species only once, not once here and
580 // again in the JS builtin. Pass the species out? 570 // again in the JS builtin. Pass the species out?
581 Handle<Object> species; 571 Handle<Object> species;
582 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 572 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
583 isolate, species, Object::ArraySpeciesConstructor(isolate, receiver)); 573 isolate, species, Object::ArraySpeciesConstructor(isolate, receiver));
584 if (*species != isolate->context()->native_context()->array_function()) { 574 if (*species != isolate->context()->native_context()->array_function()) {
585 return CallJsIntrinsic(isolate, isolate->array_splice(), args); 575 return CallJsIntrinsic(isolate, isolate->array_splice(), args);
586 } 576 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 } 612 }
623 613
624 int add_count = (argument_count > 1) ? (argument_count - 2) : 0; 614 int add_count = (argument_count > 1) ? (argument_count - 2) : 0;
625 int new_length = len - actual_delete_count + add_count; 615 int new_length = len - actual_delete_count + add_count;
626 616
627 if (new_length != len && JSArray::HasReadOnlyLength(array)) { 617 if (new_length != len && JSArray::HasReadOnlyLength(array)) {
628 AllowHeapAllocation allow_allocation; 618 AllowHeapAllocation allow_allocation;
629 return CallJsIntrinsic(isolate, isolate->array_splice(), args); 619 return CallJsIntrinsic(isolate, isolate->array_splice(), args);
630 } 620 }
631 ElementsAccessor* accessor = array->GetElementsAccessor(); 621 ElementsAccessor* accessor = array->GetElementsAccessor();
632 Handle<JSArray> result_array = accessor->Splice( 622 Handle<JSArray> result_array =
633 array, elms_obj, actual_start, actual_delete_count, &args, add_count); 623 accessor->Splice(array, handle(array->elements(), isolate), actual_start,
624 actual_delete_count, &args, add_count);
634 return *result_array; 625 return *result_array;
635 } 626 }
636 627
637 628
638 // Array Concat ------------------------------------------------------------- 629 // Array Concat -------------------------------------------------------------
639 630
640 namespace { 631 namespace {
641 632
642 /** 633 /**
643 * A simple visitor visits every element of Array's. 634 * A simple visitor visits every element of Array's.
(...skipping 3803 matching lines...) Expand 10 before | Expand all | Expand 10 after
4447 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) 4438 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
4448 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) 4439 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
4449 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 4440 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
4450 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 4441 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
4451 #undef DEFINE_BUILTIN_ACCESSOR_C 4442 #undef DEFINE_BUILTIN_ACCESSOR_C
4452 #undef DEFINE_BUILTIN_ACCESSOR_A 4443 #undef DEFINE_BUILTIN_ACCESSOR_A
4453 4444
4454 4445
4455 } // namespace internal 4446 } // namespace internal
4456 } // namespace v8 4447 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/debug/liveedit.cc » ('j') | src/objects.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698