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

Side by Side Diff: src/code-stubs-hydrogen.cc

Issue 12385014: Hydrogen stubs for array constructors (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: More efficient code when number of arguments is known Created 7 years, 8 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 parameters_[i] = param; 125 parameters_[i] = param;
126 } 126 }
127 127
128 HInstruction* stack_parameter_count; 128 HInstruction* stack_parameter_count;
129 if (descriptor_->stack_parameter_count_ != NULL) { 129 if (descriptor_->stack_parameter_count_ != NULL) {
130 ASSERT(descriptor_->environment_length() == (param_count + 1)); 130 ASSERT(descriptor_->environment_length() == (param_count + 1));
131 stack_parameter_count = new(zone) HParameter(param_count, 131 stack_parameter_count = new(zone) HParameter(param_count,
132 HParameter::REGISTER_PARAMETER, 132 HParameter::REGISTER_PARAMETER,
133 Representation::Integer32()); 133 Representation::Integer32());
134 // it's essential to bind this value to the environment in case of deopt 134 // it's essential to bind this value to the environment in case of deopt
135 AddInstruction(stack_parameter_count);
135 start_environment->Bind(param_count, stack_parameter_count); 136 start_environment->Bind(param_count, stack_parameter_count);
136 AddInstruction(stack_parameter_count); 137 arguments_length_ = AddInstruction(new(zone) HChange(
137 arguments_length_ = stack_parameter_count; 138 stack_parameter_count,
139 Representation::Tagged(),
140 true,
141 false));
138 } else { 142 } else {
139 ASSERT(descriptor_->environment_length() == param_count); 143 ASSERT(descriptor_->environment_length() == param_count);
140 stack_parameter_count = graph()->GetConstantMinus1(); 144 stack_parameter_count = graph()->GetConstantMinus1();
141 arguments_length_ = graph()->GetConstant0(); 145 arguments_length_ = graph()->GetConstant0();
142 } 146 }
143 147
144 context_ = new(zone) HContext(); 148 context_ = new(zone) HContext();
145 AddInstruction(context_); 149 AddInstruction(context_);
146 start_environment->BindContext(context_); 150 start_environment->BindContext(context_);
147 151
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 map, true, JSArray::kMapOffset)); 399 map, true, JSArray::kMapOffset));
396 return js_array; 400 return js_array;
397 } 401 }
398 402
399 403
400 Handle<Code> TransitionElementsKindStub::GenerateCode() { 404 Handle<Code> TransitionElementsKindStub::GenerateCode() {
401 return DoGenerateCode(this); 405 return DoGenerateCode(this);
402 } 406 }
403 407
404 408
409 // #define NOARG_DEOPT
410 // #define ONEARG_DEOPT
411 // #define NARG_DEOPT
405 template <> 412 template <>
406 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() { 413 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() {
414 // ----------- S t a t e -------------
415 // -- Parameter 1 : type info cell
416 // -- Parameter 0 : constructor
417 // -----------------------------------
418 #ifdef NOARG_DEOPT
407 HInstruction* deopt = new(zone()) HSoftDeoptimize(); 419 HInstruction* deopt = new(zone()) HSoftDeoptimize();
408 AddInstruction(deopt); 420 AddInstruction(deopt);
409 current_block()->MarkAsDeoptimizing(); 421 current_block()->MarkAsDeoptimizing();
410 return GetParameter(0); 422 return GetParameter(0);
423 #else
424 // Get the right map
425 // Should be a constant
426 JSArrayBuilder array_builder(this,
427 casted_stub()->elements_kind(),
428 GetParameter(ArrayConstructorStubBase::kPropertyCell));
429 HValue* new_object = array_builder.AllocateEmptyArray();
430 return new_object;
431 #endif
411 } 432 }
412 433
413 434
414 Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() { 435 Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() {
415 return DoGenerateCode(this); 436 return DoGenerateCode(this);
416 } 437 }
417 438
418 439
419 template <> 440 template <>
420 HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>:: 441 HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>::
421 BuildCodeStub() { 442 BuildCodeStub() {
443 #ifdef ONEARG_DEOPT
422 HInstruction* deopt = new(zone()) HSoftDeoptimize(); 444 HInstruction* deopt = new(zone()) HSoftDeoptimize();
423 AddInstruction(deopt); 445 AddInstruction(deopt);
424 current_block()->MarkAsDeoptimizing(); 446 current_block()->MarkAsDeoptimizing();
425 return GetParameter(0); 447 return GetParameter(0);
448 #else
449 // Smi check and range check on the input arg.
450 HValue* constant_one = graph()->GetConstant1();
451 HValue* constant_zero = graph()->GetConstant0();
452
453 HInstruction* elements = AddInstruction(
454 new(zone()) HArgumentsElements(false));
455 HInstruction* argument = AddInstruction(
456 new(zone()) HAccessArgumentsAt(elements, constant_one, constant_zero));
457
458 HConstant* max_alloc_length =
459 new(zone()) HConstant(JSObject::kInitialMaxFastElementArray,
460 Representation::Tagged());
461 AddInstruction(max_alloc_length);
462 const int initial_capacity = JSArray::kPreallocatedArrayElements;
463 HConstant* initial_capacity_node =
464 new(zone()) HConstant(initial_capacity, Representation::Tagged());
465 AddInstruction(initial_capacity_node);
466
467 // Since we're forcing Integer32 representation for this HBoundsCheck,
468 // there's no need to Smi-check the index.
469 HBoundsCheck* checked_arg = AddBoundsCheck(argument, max_alloc_length,
470 ALLOW_SMI_KEY,
471 Representation::Tagged());
472 IfBuilder if_builder(this);
473 if_builder.BeginIf(checked_arg, constant_zero, Token::EQ);
474 Push(initial_capacity_node); // capacity
475 Push(constant_zero); // length
476 if_builder.BeginElse();
477 Push(checked_arg); // capacity
478 Push(checked_arg); // length
479 if_builder.End();
480
481 // Figure out total size
482 HValue* length = Pop();
483 HValue* capacity = Pop();
484
485 JSArrayBuilder array_builder(this,
486 casted_stub()->elements_kind(),
487 GetParameter(ArrayConstructorStubBase::kPropertyCell));
488 HValue* size_in_bytes = array_builder.EstablishAllocationSize(capacity);
489 HValue* new_object = array_builder.AllocateArray(size_in_bytes,
490 capacity,
491 length,
492 true);
493 return new_object;
494 #endif
426 } 495 }
427 496
428 497
429 Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() { 498 Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() {
430 return DoGenerateCode(this); 499 return DoGenerateCode(this);
431 } 500 }
432 501
433 502
434 template <> 503 template <>
435 HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() { 504 HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() {
505 #ifdef NARG_DEOPT
436 HInstruction* deopt = new(zone()) HSoftDeoptimize(); 506 HInstruction* deopt = new(zone()) HSoftDeoptimize();
437 AddInstruction(deopt); 507 AddInstruction(deopt);
438 current_block()->MarkAsDeoptimizing(); 508 current_block()->MarkAsDeoptimizing();
439 return GetParameter(0); 509 return GetParameter(0);
510 #else
511 ElementsKind kind = casted_stub()->elements_kind();
512 HValue* length = GetArgumentsLength();
513
514 JSArrayBuilder array_builder(this,
515 kind,
516 GetParameter(ArrayConstructorStubBase::kPropertyCell));
517
518 HValue* total_size = array_builder.EstablishAllocationSize(length);
519 // We need to fill with the hole if it's a smi array in the multi-argument
520 // case because we might have to bail out while copying arguments into
521 // the array because they aren't compatible with a smi array.
522 // If it's a double array, no problem, and if it's fast then no
523 // problem either because doubles are boxed.
524 bool fill_with_hole = IsFastSmiElementsKind(kind);
525 HValue* new_object = array_builder.AllocateArray(total_size,
526 length,
527 length,
528 fill_with_hole);
529 HValue* elements = array_builder.GetElementsLocation();
530 ASSERT(elements != NULL);
531
532 // Now populate the elements correctly.
533 LoopBuilder builder(this,
534 context(),
535 LoopBuilder::kPostIncrement);
536 HValue* start = graph()->GetConstant0();
537 HValue* key = builder.BeginBody(start, length, Token::LT);
538 HInstruction* argument_elements = AddInstruction(
539 new(zone()) HArgumentsElements(false));
540 HInstruction* argument = AddInstruction(new(zone()) HAccessArgumentsAt(
541 argument_elements, length, key));
542
543 // Checks to prevent incompatible stores
544 if (IsFastSmiElementsKind(kind)) {
545 AddInstruction(new(zone()) HCheckSmi(argument));
546 }
547
548 AddInstruction(new(zone()) HStoreKeyed(elements, key, argument, kind));
549 AddSimulate(BailoutId::StubEntry(), REMOVABLE_SIMULATE);
550 builder.EndBody();
551 return new_object;
552 #endif
440 } 553 }
441 554
442 555
443 Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode() { 556 Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode() {
444 return DoGenerateCode(this); 557 return DoGenerateCode(this);
445 } 558 }
446 559
447 } } // namespace v8::internal 560 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/code-stubs.cc ('k') | src/compiler.cc » ('j') | src/hydrogen.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698