OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |