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

Side by Side Diff: src/runtime/runtime-scopes.cc

Issue 1340313003: [turbofan] Make arguments object materialization inlinable. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@local_turbofan-arguments-2
Patch Set: Rebased Created 5 years, 3 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/runtime/runtime.h ('k') | test/cctest/compiler/test-run-inlining.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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/runtime/runtime-utils.h" 5 #include "src/runtime/runtime-utils.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/arguments.h" 8 #include "src/arguments.h"
9 #include "src/frames-inl.h" 9 #include "src/frames-inl.h"
10 #include "src/isolate-inl.h" 10 #include "src/isolate-inl.h"
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 } 397 }
398 398
399 RETURN_FAILURE_ON_EXCEPTION( 399 RETURN_FAILURE_ON_EXCEPTION(
400 isolate, JSObject::SetOwnPropertyIgnoreAttributes( 400 isolate, JSObject::SetOwnPropertyIgnoreAttributes(
401 Handle<JSObject>::cast(holder), name, value, attr)); 401 Handle<JSObject>::cast(holder), name, value, attr));
402 402
403 return *value; 403 return *value;
404 } 404 }
405 405
406 406
407 static Handle<JSObject> NewSloppyArguments(Isolate* isolate, 407 namespace {
408 Handle<JSFunction> callee, 408
409 Object** parameters, 409 template <typename T>
410 int argument_count) { 410 Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee,
411 T parameters, int argument_count) {
411 CHECK(!IsSubclassConstructor(callee->shared()->kind())); 412 CHECK(!IsSubclassConstructor(callee->shared()->kind()));
412 DCHECK(callee->has_simple_parameters()); 413 DCHECK(callee->has_simple_parameters());
413 Handle<JSObject> result = 414 Handle<JSObject> result =
414 isolate->factory()->NewArgumentsObject(callee, argument_count); 415 isolate->factory()->NewArgumentsObject(callee, argument_count);
415 416
416 // Allocate the elements if needed. 417 // Allocate the elements if needed.
417 int parameter_count = callee->shared()->internal_formal_parameter_count(); 418 int parameter_count = callee->shared()->internal_formal_parameter_count();
418 if (argument_count > 0) { 419 if (argument_count > 0) {
419 if (parameter_count > 0) { 420 if (parameter_count > 0) {
420 int mapped_count = Min(argument_count, parameter_count); 421 int mapped_count = Min(argument_count, parameter_count);
421 Handle<FixedArray> parameter_map = 422 Handle<FixedArray> parameter_map =
422 isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED); 423 isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
423 parameter_map->set_map(isolate->heap()->sloppy_arguments_elements_map()); 424 parameter_map->set_map(isolate->heap()->sloppy_arguments_elements_map());
424 result->set_map(isolate->native_context()->fast_aliased_arguments_map()); 425 result->set_map(isolate->native_context()->fast_aliased_arguments_map());
425 result->set_elements(*parameter_map); 426 result->set_elements(*parameter_map);
426 427
427 // Store the context and the arguments array at the beginning of the 428 // Store the context and the arguments array at the beginning of the
428 // parameter map. 429 // parameter map.
429 Handle<Context> context(isolate->context()); 430 Handle<Context> context(isolate->context());
430 Handle<FixedArray> arguments = 431 Handle<FixedArray> arguments =
431 isolate->factory()->NewFixedArray(argument_count, NOT_TENURED); 432 isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
432 parameter_map->set(0, *context); 433 parameter_map->set(0, *context);
433 parameter_map->set(1, *arguments); 434 parameter_map->set(1, *arguments);
434 435
435 // Loop over the actual parameters backwards. 436 // Loop over the actual parameters backwards.
436 int index = argument_count - 1; 437 int index = argument_count - 1;
437 while (index >= mapped_count) { 438 while (index >= mapped_count) {
438 // These go directly in the arguments array and have no 439 // These go directly in the arguments array and have no
439 // corresponding slot in the parameter map. 440 // corresponding slot in the parameter map.
440 arguments->set(index, *(parameters - index - 1)); 441 arguments->set(index, parameters[index]);
441 --index; 442 --index;
442 } 443 }
443 444
444 Handle<ScopeInfo> scope_info(callee->shared()->scope_info()); 445 Handle<ScopeInfo> scope_info(callee->shared()->scope_info());
445 while (index >= 0) { 446 while (index >= 0) {
446 // Detect duplicate names to the right in the parameter list. 447 // Detect duplicate names to the right in the parameter list.
447 Handle<String> name(scope_info->ParameterName(index)); 448 Handle<String> name(scope_info->ParameterName(index));
448 int context_local_count = scope_info->ContextLocalCount(); 449 int context_local_count = scope_info->ContextLocalCount();
449 bool duplicate = false; 450 bool duplicate = false;
450 for (int j = index + 1; j < parameter_count; ++j) { 451 for (int j = index + 1; j < parameter_count; ++j) {
451 if (scope_info->ParameterName(j) == *name) { 452 if (scope_info->ParameterName(j) == *name) {
452 duplicate = true; 453 duplicate = true;
453 break; 454 break;
454 } 455 }
455 } 456 }
456 457
457 if (duplicate) { 458 if (duplicate) {
458 // This goes directly in the arguments array with a hole in the 459 // This goes directly in the arguments array with a hole in the
459 // parameter map. 460 // parameter map.
460 arguments->set(index, *(parameters - index - 1)); 461 arguments->set(index, parameters[index]);
461 parameter_map->set_the_hole(index + 2); 462 parameter_map->set_the_hole(index + 2);
462 } else { 463 } else {
463 // The context index goes in the parameter map with a hole in the 464 // The context index goes in the parameter map with a hole in the
464 // arguments array. 465 // arguments array.
465 int context_index = -1; 466 int context_index = -1;
466 for (int j = 0; j < context_local_count; ++j) { 467 for (int j = 0; j < context_local_count; ++j) {
467 if (scope_info->ContextLocalName(j) == *name) { 468 if (scope_info->ContextLocalName(j) == *name) {
468 context_index = j; 469 context_index = j;
469 break; 470 break;
470 } 471 }
471 } 472 }
472 473
473 DCHECK(context_index >= 0); 474 DCHECK(context_index >= 0);
474 arguments->set_the_hole(index); 475 arguments->set_the_hole(index);
475 parameter_map->set( 476 parameter_map->set(
476 index + 2, 477 index + 2,
477 Smi::FromInt(Context::MIN_CONTEXT_SLOTS + context_index)); 478 Smi::FromInt(Context::MIN_CONTEXT_SLOTS + context_index));
478 } 479 }
479 480
480 --index; 481 --index;
481 } 482 }
482 } else { 483 } else {
483 // If there is no aliasing, the arguments object elements are not 484 // If there is no aliasing, the arguments object elements are not
484 // special in any way. 485 // special in any way.
485 Handle<FixedArray> elements = 486 Handle<FixedArray> elements =
486 isolate->factory()->NewFixedArray(argument_count, NOT_TENURED); 487 isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
487 result->set_elements(*elements); 488 result->set_elements(*elements);
488 for (int i = 0; i < argument_count; ++i) { 489 for (int i = 0; i < argument_count; ++i) {
489 elements->set(i, *(parameters - i - 1)); 490 elements->set(i, parameters[i]);
490 } 491 }
491 } 492 }
492 } 493 }
493 return result; 494 return result;
494 } 495 }
495 496
496 497
497 static Handle<JSObject> NewStrictArguments(Isolate* isolate, 498 template <typename T>
498 Handle<JSFunction> callee, 499 Handle<JSObject> NewStrictArguments(Isolate* isolate, Handle<JSFunction> callee,
499 Object** parameters, 500 T parameters, int argument_count) {
500 int argument_count) {
501 Handle<JSObject> result = 501 Handle<JSObject> result =
502 isolate->factory()->NewArgumentsObject(callee, argument_count); 502 isolate->factory()->NewArgumentsObject(callee, argument_count);
503 503
504 if (argument_count > 0) { 504 if (argument_count > 0) {
505 Handle<FixedArray> array = 505 Handle<FixedArray> array =
506 isolate->factory()->NewUninitializedFixedArray(argument_count); 506 isolate->factory()->NewUninitializedFixedArray(argument_count);
507 DisallowHeapAllocation no_gc; 507 DisallowHeapAllocation no_gc;
508 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); 508 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
509 for (int i = 0; i < argument_count; i++) { 509 for (int i = 0; i < argument_count; i++) {
510 array->set(i, *--parameters, mode); 510 array->set(i, parameters[i], mode);
511 } 511 }
512 result->set_elements(*array); 512 result->set_elements(*array);
513 } 513 }
514 return result; 514 return result;
515 } 515 }
516 516
517 517
518 RUNTIME_FUNCTION(Runtime_NewArguments) { 518 class HandleArguments BASE_EMBEDDED {
519 public:
520 explicit HandleArguments(Handle<Object>* array) : array_(array) {}
521 Object* operator[](int index) { return *array_[index]; }
522
523 private:
524 Handle<Object>* array_;
525 };
526
527
528 class ParameterArguments BASE_EMBEDDED {
529 public:
530 explicit ParameterArguments(Object** parameters) : parameters_(parameters) {}
531 Object*& operator[](int index) { return *(parameters_ - index - 1); }
532
533 private:
534 Object** parameters_;
535 };
536
537 } // namespace
538
539
540 RUNTIME_FUNCTION(Runtime_NewSloppyArguments_Generic) {
519 HandleScope scope(isolate); 541 HandleScope scope(isolate);
520 DCHECK(args.length() == 1); 542 DCHECK(args.length() == 1);
521 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); 543 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
522 JavaScriptFrameIterator it(isolate); 544 // This generic runtime function can also be used when the caller has been
523 545 // inlined, we use the slow but accurate {Runtime::GetCallerArguments}.
524 // Find the frame that holds the actual arguments passed to the function. 546 int argument_count = 0;
525 it.AdvanceToArgumentsFrame(); 547 base::SmartArrayPointer<Handle<Object>> arguments =
526 JavaScriptFrame* frame = it.frame(); 548 Runtime::GetCallerArguments(isolate, 0, &argument_count);
527 549 HandleArguments argument_getter(arguments.get());
528 // Determine parameter location on the stack and dispatch on language mode. 550 return *NewSloppyArguments(isolate, callee, argument_getter, argument_count);
529 int argument_count = frame->GetArgumentsLength();
530 Object** parameters = reinterpret_cast<Object**>(frame->GetParameterSlot(-1));
531
532 return (is_strict(callee->shared()->language_mode()) ||
533 !callee->has_simple_parameters())
534 ? *NewStrictArguments(isolate, callee, parameters, argument_count)
535 : *NewSloppyArguments(isolate, callee, parameters, argument_count);
536 } 551 }
537 552
538 553
554 RUNTIME_FUNCTION(Runtime_NewStrictArguments_Generic) {
555 HandleScope scope(isolate);
556 DCHECK(args.length() == 1);
557 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
558 // This generic runtime function can also be used when the caller has been
559 // inlined, we use the slow but accurate {Runtime::GetCallerArguments}.
560 int argument_count = 0;
561 base::SmartArrayPointer<Handle<Object>> arguments =
562 Runtime::GetCallerArguments(isolate, 0, &argument_count);
563 HandleArguments argument_getter(arguments.get());
564 return *NewStrictArguments(isolate, callee, argument_getter, argument_count);
565 }
566
567
539 RUNTIME_FUNCTION(Runtime_NewSloppyArguments) { 568 RUNTIME_FUNCTION(Runtime_NewSloppyArguments) {
540 HandleScope scope(isolate); 569 HandleScope scope(isolate);
541 DCHECK(args.length() == 3); 570 DCHECK(args.length() == 3);
542 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); 571 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
543 Object** parameters = reinterpret_cast<Object**>(args[1]); 572 Object** parameters = reinterpret_cast<Object**>(args[1]);
544 CONVERT_SMI_ARG_CHECKED(argument_count, 2); 573 CONVERT_SMI_ARG_CHECKED(argument_count, 2);
545 #ifdef DEBUG 574 #ifdef DEBUG
546 // This runtime function does not materialize the correct arguments when the 575 // This runtime function does not materialize the correct arguments when the
547 // caller has been inlined, better make sure we are not hitting that case. 576 // caller has been inlined, better make sure we are not hitting that case.
548 JavaScriptFrameIterator it(isolate); 577 JavaScriptFrameIterator it(isolate);
549 DCHECK(!it.frame()->HasInlinedFrames()); 578 DCHECK(!it.frame()->HasInlinedFrames());
550 #endif // DEBUG 579 #endif // DEBUG
551 return *NewSloppyArguments(isolate, callee, parameters, argument_count); 580 ParameterArguments argument_getter(parameters);
581 return *NewSloppyArguments(isolate, callee, argument_getter, argument_count);
552 } 582 }
553 583
554 584
555 RUNTIME_FUNCTION(Runtime_NewStrictArguments) { 585 RUNTIME_FUNCTION(Runtime_NewStrictArguments) {
556 HandleScope scope(isolate); 586 HandleScope scope(isolate);
557 DCHECK(args.length() == 3); 587 DCHECK(args.length() == 3);
558 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0) 588 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0)
559 Object** parameters = reinterpret_cast<Object**>(args[1]); 589 Object** parameters = reinterpret_cast<Object**>(args[1]);
560 CONVERT_SMI_ARG_CHECKED(argument_count, 2); 590 CONVERT_SMI_ARG_CHECKED(argument_count, 2);
561 #ifdef DEBUG 591 #ifdef DEBUG
562 // This runtime function does not materialize the correct arguments when the 592 // This runtime function does not materialize the correct arguments when the
563 // caller has been inlined, better make sure we are not hitting that case. 593 // caller has been inlined, better make sure we are not hitting that case.
564 JavaScriptFrameIterator it(isolate); 594 JavaScriptFrameIterator it(isolate);
565 DCHECK(!it.frame()->HasInlinedFrames()); 595 DCHECK(!it.frame()->HasInlinedFrames());
566 #endif // DEBUG 596 #endif // DEBUG
567 return *NewStrictArguments(isolate, callee, parameters, argument_count); 597 ParameterArguments argument_getter(parameters);
598 return *NewStrictArguments(isolate, callee, argument_getter, argument_count);
568 } 599 }
569 600
570 601
571 RUNTIME_FUNCTION(Runtime_NewClosure) { 602 RUNTIME_FUNCTION(Runtime_NewClosure) {
572 HandleScope scope(isolate); 603 HandleScope scope(isolate);
573 DCHECK_EQ(1, args.length()); 604 DCHECK_EQ(1, args.length());
574 CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0); 605 CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
575 Handle<Context> context(isolate->context(), isolate); 606 Handle<Context> context(isolate->context(), isolate);
576 return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, 607 return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
577 NOT_TENURED); 608 NOT_TENURED);
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 1161
1131 // Lookup in the initial Object.prototype object. 1162 // Lookup in the initial Object.prototype object.
1132 Handle<Object> result; 1163 Handle<Object> result;
1133 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 1164 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1134 isolate, result, 1165 isolate, result,
1135 Object::GetProperty(isolate->initial_object_prototype(), key)); 1166 Object::GetProperty(isolate->initial_object_prototype(), key));
1136 return *result; 1167 return *result;
1137 } 1168 }
1138 } // namespace internal 1169 } // namespace internal
1139 } // namespace v8 1170 } // namespace v8
OLDNEW
« no previous file with comments | « src/runtime/runtime.h ('k') | test/cctest/compiler/test-run-inlining.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698