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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 |
OLD | NEW |