| Index: src/code-stubs-hydrogen.cc
|
| diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
|
| index 3c90b5effa7ac16f8723b8732a4cf45c84d9f709..7922d6c3c7ae15ac7313f87ff13571628750aaca 100644
|
| --- a/src/code-stubs-hydrogen.cc
|
| +++ b/src/code-stubs-hydrogen.cc
|
| @@ -188,7 +188,7 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
|
| if (!stack_parameter_count->IsConstant() &&
|
| descriptor_->hint_stack_parameter_count_ < 0) {
|
| HInstruction* constant_one = graph()->GetConstant1();
|
| - stack_pop_count = Add<HAdd>(stack_parameter_count, constant_one);
|
| + stack_pop_count = AddUncasted<HAdd>(stack_parameter_count, constant_one);
|
| stack_pop_count->ClearFlag(HValue::kCanOverflow);
|
| // TODO(mvstanton): verify that stack_parameter_count+1 really fits in a
|
| // smi.
|
| @@ -251,9 +251,6 @@ Handle<Code> HydrogenCodeStub::GenerateLightweightMissCode(Isolate* isolate) {
|
| // Update the static counter each time a new code stub is generated.
|
| isolate->counters()->code_stubs()->Increment();
|
|
|
| - // Nested stubs are not allowed for leaves.
|
| - AllowStubCallsScope allow_scope(&masm, false);
|
| -
|
| // Generate the code for the stub.
|
| masm.set_generating_stub(true);
|
| NoCurrentFrameScope scope(&masm);
|
| @@ -303,7 +300,8 @@ static Handle<Code> DoGenerateCode(Isolate* isolate, Stub* stub) {
|
| Handle<Code> code = chunk->Codegen();
|
| if (FLAG_profile_hydrogen_code_stub_compilation) {
|
| double ms = timer.Elapsed().InMillisecondsF();
|
| - PrintF("[Lazy compilation of %s took %0.3f ms]\n", *stub->GetName(), ms);
|
| + PrintF("[Lazy compilation of %s took %0.3f ms]\n",
|
| + stub->GetName().get(), ms);
|
| }
|
| return code;
|
| }
|
| @@ -472,7 +470,8 @@ HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() {
|
|
|
| ASSERT(FLAG_allocation_site_pretenuring || (size == object_size));
|
| if (FLAG_allocation_site_pretenuring) {
|
| - BuildCreateAllocationMemento(object, object_size, allocation_site);
|
| + BuildCreateAllocationMemento(
|
| + object, Add<HConstant>(object_size), allocation_site);
|
| }
|
|
|
| environment()->Push(object);
|
| @@ -616,6 +615,7 @@ HValue* CodeStubGraphBuilder<KeyedArrayCallStub>::BuildCodeStub() {
|
| info()->set_parameter_count(argc);
|
|
|
| HValue* receiver = Add<HParameter>(1);
|
| + BuildCheckHeapObject(receiver);
|
|
|
| // Load the expected initial array map from the context.
|
| JSArrayBuilder array_builder(this, casted_stub()->elements_kind());
|
| @@ -742,6 +742,15 @@ HValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor(
|
|
|
| HValue* CodeStubGraphBuilderBase::BuildArrayNArgumentsConstructor(
|
| JSArrayBuilder* array_builder, ElementsKind kind) {
|
| + // Insert a bounds check because the number of arguments might exceed
|
| + // the kInitialMaxFastElementArray limit. This cannot happen for code
|
| + // that was parsed, but calling via Array.apply(thisArg, [...]) might
|
| + // trigger it.
|
| + HValue* length = GetArgumentsLength();
|
| + HConstant* max_alloc_length =
|
| + Add<HConstant>(JSObject::kInitialMaxFastElementArray);
|
| + HValue* checked_length = Add<HBoundsCheck>(length, max_alloc_length);
|
| +
|
| // We need to fill with the hole if it's a smi array in the multi-argument
|
| // case because we might have to bail out while copying arguments into
|
| // the array because they aren't compatible with a smi array.
|
| @@ -750,12 +759,11 @@ HValue* CodeStubGraphBuilderBase::BuildArrayNArgumentsConstructor(
|
| //
|
| // TODO(mvstanton): consider an instruction to memset fill the array
|
| // with zero in this case instead.
|
| - HValue* length = GetArgumentsLength();
|
| JSArrayBuilder::FillMode fill_mode = IsFastSmiElementsKind(kind)
|
| ? JSArrayBuilder::FILL_WITH_HOLE
|
| : JSArrayBuilder::DONT_FILL_WITH_HOLE;
|
| - HValue* new_object = array_builder->AllocateArray(length,
|
| - length,
|
| + HValue* new_object = array_builder->AllocateArray(checked_length,
|
| + checked_length,
|
| fill_mode);
|
| HValue* elements = array_builder->GetElementsLocation();
|
| ASSERT(elements != NULL);
|
| @@ -765,10 +773,10 @@ HValue* CodeStubGraphBuilderBase::BuildArrayNArgumentsConstructor(
|
| context(),
|
| LoopBuilder::kPostIncrement);
|
| HValue* start = graph()->GetConstant0();
|
| - HValue* key = builder.BeginBody(start, length, Token::LT);
|
| + HValue* key = builder.BeginBody(start, checked_length, Token::LT);
|
| HInstruction* argument_elements = Add<HArgumentsElements>(false);
|
| HInstruction* argument = Add<HAccessArgumentsAt>(
|
| - argument_elements, length, key);
|
| + argument_elements, checked_length, key);
|
|
|
| Add<HStoreKeyed>(elements, key, argument, kind);
|
| builder.EndBody();
|
| @@ -889,20 +897,21 @@ Handle<Code> CompareNilICStub::GenerateCode(Isolate* isolate) {
|
|
|
|
|
| template <>
|
| -HValue* CodeStubGraphBuilder<BinaryOpStub>::BuildCodeInitializedStub() {
|
| - BinaryOpStub* stub = casted_stub();
|
| - HValue* left = GetParameter(0);
|
| - HValue* right = GetParameter(1);
|
| +HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
|
| + BinaryOpIC::State state = casted_stub()->state();
|
| +
|
| + HValue* left = GetParameter(BinaryOpICStub::kLeft);
|
| + HValue* right = GetParameter(BinaryOpICStub::kRight);
|
|
|
| - Handle<Type> left_type = stub->GetLeftType(isolate());
|
| - Handle<Type> right_type = stub->GetRightType(isolate());
|
| - Handle<Type> result_type = stub->GetResultType(isolate());
|
| + Handle<Type> left_type = state.GetLeftType(isolate());
|
| + Handle<Type> right_type = state.GetRightType(isolate());
|
| + Handle<Type> result_type = state.GetResultType(isolate());
|
|
|
| ASSERT(!left_type->Is(Type::None()) && !right_type->Is(Type::None()) &&
|
| - (stub->HasSideEffects(isolate()) || !result_type->Is(Type::None())));
|
| + (state.HasSideEffects() || !result_type->Is(Type::None())));
|
|
|
| HValue* result = NULL;
|
| - if (stub->operation() == Token::ADD &&
|
| + if (state.op() == Token::ADD &&
|
| (left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) &&
|
| !left_type->Is(Type::String()) && !right_type->Is(Type::String())) {
|
| // For the generic add stub a fast case for string addition is performance
|
| @@ -913,16 +922,16 @@ HValue* CodeStubGraphBuilder<BinaryOpStub>::BuildCodeInitializedStub() {
|
| if_leftisstring.Then();
|
| {
|
| Push(BuildBinaryOperation(
|
| - stub->operation(), left, right,
|
| + state.op(), left, right,
|
| handle(Type::String(), isolate()), right_type,
|
| - result_type, stub->fixed_right_arg()));
|
| + result_type, state.fixed_right_arg()));
|
| }
|
| if_leftisstring.Else();
|
| {
|
| Push(BuildBinaryOperation(
|
| - stub->operation(), left, right,
|
| + state.op(), left, right,
|
| left_type, right_type, result_type,
|
| - stub->fixed_right_arg()));
|
| + state.fixed_right_arg()));
|
| }
|
| if_leftisstring.End();
|
| result = Pop();
|
| @@ -932,32 +941,32 @@ HValue* CodeStubGraphBuilder<BinaryOpStub>::BuildCodeInitializedStub() {
|
| if_rightisstring.Then();
|
| {
|
| Push(BuildBinaryOperation(
|
| - stub->operation(), left, right,
|
| + state.op(), left, right,
|
| left_type, handle(Type::String(), isolate()),
|
| - result_type, stub->fixed_right_arg()));
|
| + result_type, state.fixed_right_arg()));
|
| }
|
| if_rightisstring.Else();
|
| {
|
| Push(BuildBinaryOperation(
|
| - stub->operation(), left, right,
|
| + state.op(), left, right,
|
| left_type, right_type, result_type,
|
| - stub->fixed_right_arg()));
|
| + state.fixed_right_arg()));
|
| }
|
| if_rightisstring.End();
|
| result = Pop();
|
| }
|
| } else {
|
| result = BuildBinaryOperation(
|
| - stub->operation(), left, right,
|
| + state.op(), left, right,
|
| left_type, right_type, result_type,
|
| - stub->fixed_right_arg());
|
| + state.fixed_right_arg());
|
| }
|
|
|
| // If we encounter a generic argument, the number conversion is
|
| // observable, thus we cannot afford to bail out after the fact.
|
| - if (!stub->HasSideEffects(isolate())) {
|
| + if (!state.HasSideEffects()) {
|
| if (result_type->Is(Type::Smi())) {
|
| - if (stub->operation() == Token::SHR) {
|
| + if (state.op() == Token::SHR) {
|
| // TODO(olivf) Replace this by a SmiTagU Instruction.
|
| // 0x40000000: this number would convert to negative when interpreting
|
| // the register as signed value;
|
| @@ -975,8 +984,8 @@ HValue* CodeStubGraphBuilder<BinaryOpStub>::BuildCodeInitializedStub() {
|
|
|
| // Reuse the double box of one of the operands if we are allowed to (i.e.
|
| // chained binops).
|
| - if (stub->CanReuseDoubleBox()) {
|
| - HValue* operand = (stub->mode() == OVERWRITE_LEFT) ? left : right;
|
| + if (state.CanReuseDoubleBox()) {
|
| + HValue* operand = (state.mode() == OVERWRITE_LEFT) ? left : right;
|
| IfBuilder if_heap_number(this);
|
| if_heap_number.IfNot<HIsSmiAndBranch>(operand);
|
| if_heap_number.Then();
|
| @@ -992,7 +1001,7 @@ HValue* CodeStubGraphBuilder<BinaryOpStub>::BuildCodeInitializedStub() {
|
| }
|
|
|
|
|
| -Handle<Code> BinaryOpStub::GenerateCode(Isolate* isolate) {
|
| +Handle<Code> BinaryOpICStub::GenerateCode(Isolate* isolate) {
|
| return DoGenerateCode(isolate, this);
|
| }
|
|
|
|
|