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

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: REBASE 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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 parameters_[i] = param; 124 parameters_[i] = param;
125 } 125 }
126 126
127 HInstruction* stack_parameter_count; 127 HInstruction* stack_parameter_count;
128 if (descriptor_->stack_parameter_count_ != NULL) { 128 if (descriptor_->stack_parameter_count_ != NULL) {
129 ASSERT(descriptor_->environment_length() == (param_count + 1)); 129 ASSERT(descriptor_->environment_length() == (param_count + 1));
130 stack_parameter_count = new(zone) HParameter(param_count, 130 stack_parameter_count = new(zone) HParameter(param_count,
131 HParameter::REGISTER_PARAMETER, 131 HParameter::REGISTER_PARAMETER,
132 Representation::Integer32()); 132 Representation::Integer32());
133 // it's essential to bind this value to the environment in case of deopt 133 // it's essential to bind this value to the environment in case of deopt
134 AddInstruction(stack_parameter_count);
134 start_environment->Bind(param_count, stack_parameter_count); 135 start_environment->Bind(param_count, stack_parameter_count);
135 AddInstruction(stack_parameter_count); 136 arguments_length_ = AddInstruction(new(zone) HChange(
136 arguments_length_ = stack_parameter_count; 137 stack_parameter_count,
mvstanton 2013/04/18 14:43:01 try not to use HChange explicitly, can you avoid?
mvstanton 2013/04/23 14:19:57 I was able to avoid it by setting the type of stac
138 Representation::Tagged(),
139 true,
140 false));
137 } else { 141 } else {
138 ASSERT(descriptor_->environment_length() == param_count); 142 ASSERT(descriptor_->environment_length() == param_count);
139 stack_parameter_count = graph()->GetConstantMinus1(); 143 stack_parameter_count = graph()->GetConstantMinus1();
140 arguments_length_ = graph()->GetConstant0(); 144 arguments_length_ = graph()->GetConstant0();
141 } 145 }
142 146
143 context_ = new(zone) HContext(); 147 context_ = new(zone) HContext();
144 AddInstruction(context_); 148 AddInstruction(context_);
145 start_environment->BindContext(context_); 149 start_environment->BindContext(context_);
146 150
147 AddSimulate(BailoutId::StubEntry()); 151 AddSimulate(BailoutId::StubEntry());
148 152
149 NoObservableSideEffectsScope no_effects(this); 153 NoObservableSideEffectsScope no_effects(this);
150 154
151 HValue* return_value = BuildCodeStub(); 155 HValue* return_value = BuildCodeStub();
152 156
153 // We might have extra expressions to pop from the stack in addition to the 157 // We might have extra expressions to pop from the stack in addition to the
154 // arguments above 158 // arguments above
155 HInstruction* stack_pop_count = stack_parameter_count; 159 HInstruction* stack_pop_count = stack_parameter_count;
156 if (descriptor_->function_mode_ == JS_FUNCTION_STUB_MODE) { 160 if (descriptor_->function_mode_ == JS_FUNCTION_STUB_MODE) {
157 HInstruction* amount = graph()->GetConstant1(); 161 if (stack_parameter_count->IsParameter() &&
mvstanton 2013/04/18 14:43:01 change to !stack_parameter_count->IsConstant()
mvstanton 2013/04/23 14:19:57 Done.
158 stack_pop_count = AddInstruction( 162 descriptor_->hint_stack_parameter_count_ < 0) {
159 HAdd::New(zone, context_, stack_parameter_count, amount)); 163 HInstruction* amount = graph()->GetConstant1();
160 stack_pop_count->ChangeRepresentation(Representation::Integer32()); 164 stack_pop_count = AddInstruction(
161 stack_pop_count->ClearFlag(HValue::kCanOverflow); 165 HAdd::New(zone, context_, stack_parameter_count, amount));
166 stack_pop_count->ChangeRepresentation(Representation::Integer32());
167 stack_pop_count->ClearFlag(HValue::kCanOverflow);
168 } else {
169 int count = descriptor_->hint_stack_parameter_count_;
170 stack_pop_count = AddInstruction(new(zone)
171 HConstant(count, Representation::Integer32()));
172 }
162 } 173 }
163 174
164 HReturn* hreturn_instruction = new(zone) HReturn(return_value, 175 HReturn* hreturn_instruction = new(zone) HReturn(return_value,
165 context_, 176 context_,
166 stack_pop_count); 177 stack_pop_count);
167 current_block()->Finish(hreturn_instruction); 178 current_block()->Finish(hreturn_instruction);
168 return true; 179 return true;
169 } 180 }
170 181
171 182
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 } 405 }
395 406
396 407
397 Handle<Code> TransitionElementsKindStub::GenerateCode() { 408 Handle<Code> TransitionElementsKindStub::GenerateCode() {
398 return DoGenerateCode(this); 409 return DoGenerateCode(this);
399 } 410 }
400 411
401 412
402 template <> 413 template <>
403 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() { 414 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() {
404 HInstruction* deopt = new(zone()) HSoftDeoptimize(); 415 // ----------- S t a t e -------------
405 AddInstruction(deopt); 416 // -- Parameter 1 : type info cell
406 current_block()->MarkAsDeoptimizing(); 417 // -- Parameter 0 : constructor
407 return GetParameter(0); 418 // -----------------------------------
419 // Get the right map
420 // Should be a constant
421 JSArrayBuilder array_builder(this,
422 casted_stub()->elements_kind(),
423 GetParameter(ArrayConstructorStubBase::kPropertyCell),
424 casted_stub()->mode());
425 return array_builder.AllocateEmptyArray();
408 } 426 }
409 427
410 428
411 Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() { 429 Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() {
412 return DoGenerateCode(this); 430 return DoGenerateCode(this);
413 } 431 }
414 432
415 433
416 template <> 434 template <>
417 HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>:: 435 HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>::
418 BuildCodeStub() { 436 BuildCodeStub() {
419 HInstruction* deopt = new(zone()) HSoftDeoptimize(); 437 // Smi check and range check on the input arg.
420 AddInstruction(deopt); 438 HValue* constant_one = graph()->GetConstant1();
421 current_block()->MarkAsDeoptimizing(); 439 HValue* constant_zero = graph()->GetConstant0();
422 return GetParameter(0); 440
441 HInstruction* elements = AddInstruction(
442 new(zone()) HArgumentsElements(false));
443 HInstruction* argument = AddInstruction(
444 new(zone()) HAccessArgumentsAt(elements, constant_one, constant_zero));
445
446 HConstant* max_alloc_length =
447 new(zone()) HConstant(JSObject::kInitialMaxFastElementArray,
448 Representation::Tagged());
449 AddInstruction(max_alloc_length);
450 const int initial_capacity = JSArray::kPreallocatedArrayElements;
451 HConstant* initial_capacity_node =
452 new(zone()) HConstant(initial_capacity, Representation::Tagged());
453 AddInstruction(initial_capacity_node);
454
455 // Since we're forcing Integer32 representation for this HBoundsCheck,
456 // there's no need to Smi-check the index.
457 HBoundsCheck* checked_arg = AddBoundsCheck(argument, max_alloc_length,
458 ALLOW_SMI_KEY,
459 Representation::Tagged());
460 IfBuilder if_builder(this);
461 if_builder.IfCompare(checked_arg, constant_zero, Token::EQ);
462 if_builder.Then();
463 Push(initial_capacity_node); // capacity
464 Push(constant_zero); // length
465 if_builder.Else();
466 Push(checked_arg); // capacity
467 Push(checked_arg); // length
468 if_builder.End();
469
470 // Figure out total size
471 HValue* length = Pop();
472 HValue* capacity = Pop();
473
474 JSArrayBuilder array_builder(this,
475 casted_stub()->elements_kind(),
476 GetParameter(ArrayConstructorStubBase::kPropertyCell),
477 casted_stub()->mode());
478 return array_builder.AllocateArray(capacity, length, true);
423 } 479 }
424 480
425 481
426 Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() { 482 Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() {
427 return DoGenerateCode(this); 483 return DoGenerateCode(this);
428 } 484 }
429 485
430 486
431 template <> 487 template <>
432 HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() { 488 HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() {
433 HInstruction* deopt = new(zone()) HSoftDeoptimize(); 489 ElementsKind kind = casted_stub()->elements_kind();
434 AddInstruction(deopt); 490 HValue* length = GetArgumentsLength();
435 current_block()->MarkAsDeoptimizing(); 491
436 return GetParameter(0); 492 JSArrayBuilder array_builder(this,
mvstanton 2013/04/18 14:43:01 nit: this should be on next line.
mvstanton 2013/04/23 14:19:57 done, also in another place in this file.
493 kind,
494 GetParameter(ArrayConstructorStubBase::kPropertyCell),
495 casted_stub()->mode());
496
497 // We need to fill with the hole if it's a smi array in the multi-argument
498 // case because we might have to bail out while copying arguments into
499 // the array because they aren't compatible with a smi array.
500 // If it's a double array, no problem, and if it's fast then no
501 // problem either because doubles are boxed.
502 bool fill_with_hole = IsFastSmiElementsKind(kind);
503 HValue* new_object = array_builder.AllocateArray(length,
504 length,
505 fill_with_hole);
506 HValue* elements = array_builder.GetElementsLocation();
507 ASSERT(elements != NULL);
508
509 // Now populate the elements correctly.
510 LoopBuilder builder(this,
511 context(),
512 LoopBuilder::kPostIncrement);
513 HValue* start = graph()->GetConstant0();
514 HValue* key = builder.BeginBody(start, length, Token::LT);
515 HInstruction* argument_elements = AddInstruction(
516 new(zone()) HArgumentsElements(false));
517 HInstruction* argument = AddInstruction(new(zone()) HAccessArgumentsAt(
518 argument_elements, length, key));
519
520 // Checks to prevent incompatible stores
521 if (IsFastSmiElementsKind(kind)) {
522 AddInstruction(new(zone()) HCheckSmi(argument));
523 }
524
525 AddInstruction(new(zone()) HStoreKeyed(elements, key, argument, kind));
526 builder.EndBody();
527 return new_object;
437 } 528 }
438 529
439 530
440 Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode() { 531 Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode() {
441 return DoGenerateCode(this); 532 return DoGenerateCode(this);
442 } 533 }
443 534
444 } } // namespace v8::internal 535 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698