Chromium Code Reviews| 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 |