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

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: With all ports done 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
148 AddSimulate(BailoutId::StubEntry()); 152 AddSimulate(BailoutId::StubEntry());
149 153
150 NoObservableSideEffectsScope no_effects(this); 154 NoObservableSideEffectsScope no_effects(this);
151 155
152 HValue* return_value = BuildCodeStub(); 156 HValue* return_value = BuildCodeStub();
153 157
154 // We might have extra expressions to pop from the stack in addition to the 158 // We might have extra expressions to pop from the stack in addition to the
155 // arguments above 159 // arguments above
156 HInstruction* stack_pop_count = stack_parameter_count; 160 HInstruction* stack_pop_count = stack_parameter_count;
157 if (descriptor_->function_mode_ == JS_FUNCTION_STUB_MODE) { 161 if (descriptor_->function_mode_ == JS_FUNCTION_STUB_MODE) {
158 HInstruction* amount = graph()->GetConstant1(); 162 if (stack_parameter_count->IsParameter() &&
159 stack_pop_count = AddInstruction( 163 descriptor_->hint_stack_parameter_count_ < 0) {
160 HAdd::New(zone, context_, stack_parameter_count, amount)); 164 HInstruction* amount = graph()->GetConstant1();
161 stack_pop_count->ChangeRepresentation(Representation::Integer32()); 165 stack_pop_count = AddInstruction(
162 stack_pop_count->ClearFlag(HValue::kCanOverflow); 166 HAdd::New(zone, context_, stack_parameter_count, amount));
167 stack_pop_count->ChangeRepresentation(Representation::Integer32());
168 stack_pop_count->ClearFlag(HValue::kCanOverflow);
169 } else {
170 int count = descriptor_->hint_stack_parameter_count_;
171 if (count == 0) {
172 stack_pop_count = graph()->GetConstant0();
173 } else if (count == 1) {
174 stack_pop_count = graph()->GetConstant1();
175 } else {
176 stack_pop_count = AddInstruction(new(zone)
177 HConstant(count, Representation::Integer32()));
178 }
179 }
163 } 180 }
164 181
165 HReturn* hreturn_instruction = new(zone) HReturn(return_value, 182 HReturn* hreturn_instruction = new(zone) HReturn(return_value,
166 context_, 183 context_,
167 stack_pop_count); 184 stack_pop_count);
168 current_block()->Finish(hreturn_instruction); 185 current_block()->Finish(hreturn_instruction);
169 return true; 186 return true;
170 } 187 }
171 188
172 189
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 } 410 }
394 411
395 412
396 Handle<Code> TransitionElementsKindStub::GenerateCode() { 413 Handle<Code> TransitionElementsKindStub::GenerateCode() {
397 return DoGenerateCode(this); 414 return DoGenerateCode(this);
398 } 415 }
399 416
400 417
401 template <> 418 template <>
402 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() { 419 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() {
403 HInstruction* deopt = new(zone()) HSoftDeoptimize(); 420 // ----------- S t a t e -------------
404 AddInstruction(deopt); 421 // -- Parameter 1 : type info cell
405 current_block()->MarkAsDeoptimizing(); 422 // -- Parameter 0 : constructor
406 return GetParameter(0); 423 // -----------------------------------
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 casted_stub()->mode());
430 return array_builder.AllocateEmptyArray();
407 } 431 }
408 432
409 433
410 Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() { 434 Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() {
411 return DoGenerateCode(this); 435 return DoGenerateCode(this);
412 } 436 }
413 437
414 438
415 template <> 439 template <>
416 HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>:: 440 HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>::
417 BuildCodeStub() { 441 BuildCodeStub() {
418 HInstruction* deopt = new(zone()) HSoftDeoptimize(); 442 info()->MarkAsStubThatUsesArguments();
419 AddInstruction(deopt); 443
420 current_block()->MarkAsDeoptimizing(); 444 // Smi check and range check on the input arg.
421 return GetParameter(0); 445 HValue* constant_one = graph()->GetConstant1();
446 HValue* constant_zero = graph()->GetConstant0();
447
448 HInstruction* elements = AddInstruction(
449 new(zone()) HArgumentsElements(false));
450 HInstruction* argument = AddInstruction(
451 new(zone()) HAccessArgumentsAt(elements, constant_one, constant_zero));
452
453 // AddInstruction(new(zone()) HCheckSmi(argument));
Hannes Payer (out of office) 2013/04/18 11:14:39 I think you can remove that line.
mvstanton 2013/04/18 13:39:26 thx!, done
454
455 HConstant* max_alloc_length =
456 new(zone()) HConstant(JSObject::kInitialMaxFastElementArray,
457 Representation::Tagged());
458 AddInstruction(max_alloc_length);
459 const int initial_capacity = JSArray::kPreallocatedArrayElements;
460 HConstant* initial_capacity_node =
461 new(zone()) HConstant(initial_capacity, Representation::Tagged());
462 AddInstruction(initial_capacity_node);
463
464 // Since we're forcing Integer32 representation for this HBoundsCheck,
465 // there's no need to Smi-check the index.
466 HBoundsCheck* checked_arg = AddBoundsCheck(argument, max_alloc_length,
467 ALLOW_SMI_KEY,
468 Representation::Tagged());
469 IfBuilder if_builder(this);
470 if_builder.BeginIf(checked_arg, constant_zero, Token::EQ);
471 Push(initial_capacity_node); // capacity
472 Push(constant_zero); // length
473 if_builder.BeginElse();
474 Push(checked_arg); // capacity
475 Push(checked_arg); // length
476 if_builder.End();
477
478 // Figure out total size
479 HValue* length = Pop();
480 HValue* capacity = Pop();
481
482 // length->ChangeRepresentation(Representation::Integer32());
483 // capacity->ChangeRepresentation(Representation::Integer32());
484
485 JSArrayBuilder array_builder(this,
486 casted_stub()->elements_kind(),
487 GetParameter(ArrayConstructorStubBase::kPropertyCell),
488 casted_stub()->mode());
489 return array_builder.AllocateArray(capacity, length, true);
422 } 490 }
423 491
424 492
425 Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() { 493 Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() {
426 return DoGenerateCode(this); 494 return DoGenerateCode(this);
427 } 495 }
428 496
429 497
430 template <> 498 template <>
431 HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() { 499 HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() {
432 HInstruction* deopt = new(zone()) HSoftDeoptimize(); 500 info()->MarkAsStubThatUsesArguments();
433 AddInstruction(deopt); 501 ElementsKind kind = casted_stub()->elements_kind();
434 current_block()->MarkAsDeoptimizing(); 502 HValue* length = GetArgumentsLength();
435 return GetParameter(0); 503
504 JSArrayBuilder array_builder(this,
505 kind,
506 GetParameter(ArrayConstructorStubBase::kPropertyCell),
507 casted_stub()->mode());
508
509 // We need to fill with the hole if it's a smi array in the multi-argument
510 // case because we might have to bail out while copying arguments into
511 // the array because they aren't compatible with a smi array.
512 // If it's a double array, no problem, and if it's fast then no
513 // problem either because doubles are boxed.
514 bool fill_with_hole = IsFastSmiElementsKind(kind);
515 HValue* new_object = array_builder.AllocateArray(length,
516 length,
517 fill_with_hole);
518 HValue* elements = array_builder.GetElementsLocation();
519 ASSERT(elements != NULL);
520
521 // Now populate the elements correctly.
522 LoopBuilder builder(this,
523 context(),
524 LoopBuilder::kPostIncrement);
525 HValue* start = graph()->GetConstant0();
526 HValue* key = builder.BeginBody(start, length, Token::LT);
527 HInstruction* argument_elements = AddInstruction(
528 new(zone()) HArgumentsElements(false));
529 HInstruction* argument = AddInstruction(new(zone()) HAccessArgumentsAt(
530 argument_elements, length, key));
531
532 // Checks to prevent incompatible stores
533 if (IsFastSmiElementsKind(kind)) {
534 AddInstruction(new(zone()) HCheckSmi(argument));
535 }
536
537 AddInstruction(new(zone()) HStoreKeyed(elements, key, argument, kind));
538 builder.EndBody();
539 return new_object;
436 } 540 }
437 541
438 542
439 Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode() { 543 Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode() {
440 return DoGenerateCode(this); 544 return DoGenerateCode(this);
441 } 545 }
442 546
443 } } // namespace v8::internal 547 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698