| Index: src/arm/code-stubs-arm.cc
|
| diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
|
| index 3a1d1282a6bc65d5fc0a77d648d9a4be2c2491e4..39b2dc507d5f81c97f0a6bb7825b4b41b7f1eb52 100644
|
| --- a/src/arm/code-stubs-arm.cc
|
| +++ b/src/arm/code-stubs-arm.cc
|
| @@ -2765,9 +2765,10 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
|
|
|
| if (do_gc) {
|
| // Passing r0.
|
| - __ PrepareCallCFunction(1, 0, r1);
|
| + __ PrepareCallCFunction(2, 0, r1);
|
| + __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate())));
|
| __ CallCFunction(ExternalReference::perform_gc_function(isolate),
|
| - 1, 0);
|
| + 2, 0);
|
| }
|
|
|
| ExternalReference scope_depth =
|
| @@ -3375,8 +3376,7 @@ void StringLengthStub::Generate(MacroAssembler* masm) {
|
| receiver = r0;
|
| }
|
|
|
| - StubCompiler::GenerateLoadStringLength(masm, receiver, r3, r4, &miss,
|
| - support_wrapper_);
|
| + StubCompiler::GenerateLoadStringLength(masm, receiver, r3, r4, &miss);
|
|
|
| __ bind(&miss);
|
| StubCompiler::TailCallBuiltin(
|
| @@ -5790,7 +5790,6 @@ void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
|
| __ b(lt, &done);
|
|
|
| // Check the number to string cache.
|
| - Label not_cached;
|
| __ bind(¬_string);
|
| // Puts the cached result into scratch1.
|
| NumberToStringStub::GenerateLookupNumberStringCache(masm,
|
| @@ -5799,26 +5798,9 @@ void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
|
| scratch2,
|
| scratch3,
|
| scratch4,
|
| - ¬_cached);
|
| + slow);
|
| __ mov(arg, scratch1);
|
| __ str(arg, MemOperand(sp, stack_offset));
|
| - __ jmp(&done);
|
| -
|
| - // Check if the argument is a safe string wrapper.
|
| - __ bind(¬_cached);
|
| - __ JumpIfSmi(arg, slow);
|
| - __ CompareObjectType(
|
| - arg, scratch1, scratch2, JS_VALUE_TYPE); // map -> scratch1.
|
| - __ b(ne, slow);
|
| - __ ldrb(scratch2, FieldMemOperand(scratch1, Map::kBitField2Offset));
|
| - __ and_(scratch2,
|
| - scratch2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
|
| - __ cmp(scratch2,
|
| - Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
|
| - __ b(ne, slow);
|
| - __ ldr(arg, FieldMemOperand(arg, JSValue::kValueOffset));
|
| - __ str(arg, MemOperand(sp, stack_offset));
|
| -
|
| __ bind(&done);
|
| }
|
|
|
| @@ -6855,90 +6837,128 @@ void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
|
|
|
|
|
| template<class T>
|
| -static void CreateArrayDispatch(MacroAssembler* masm) {
|
| - int last_index = GetSequenceIndexFromFastElementsKind(
|
| - TERMINAL_FAST_ELEMENTS_KIND);
|
| - for (int i = 0; i <= last_index; ++i) {
|
| - Label next;
|
| - ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
|
| - __ cmp(r3, Operand(kind));
|
| - __ b(ne, &next);
|
| - T stub(kind);
|
| +static void CreateArrayDispatch(MacroAssembler* masm,
|
| + AllocationSiteOverrideMode mode) {
|
| + if (mode == DISABLE_ALLOCATION_SITES) {
|
| + T stub(GetInitialFastElementsKind(),
|
| + CONTEXT_CHECK_REQUIRED,
|
| + mode);
|
| __ TailCallStub(&stub);
|
| - __ bind(&next);
|
| - }
|
| + } else if (mode == DONT_OVERRIDE) {
|
| + int last_index = GetSequenceIndexFromFastElementsKind(
|
| + TERMINAL_FAST_ELEMENTS_KIND);
|
| + for (int i = 0; i <= last_index; ++i) {
|
| + Label next;
|
| + ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
|
| + __ cmp(r3, Operand(kind));
|
| + __ b(ne, &next);
|
| + T stub(kind);
|
| + __ TailCallStub(&stub);
|
| + __ bind(&next);
|
| + }
|
|
|
| - // If we reached this point there is a problem.
|
| - __ Abort(kUnexpectedElementsKindInArrayConstructor);
|
| + // If we reached this point there is a problem.
|
| + __ Abort(kUnexpectedElementsKindInArrayConstructor);
|
| + } else {
|
| + UNREACHABLE();
|
| + }
|
| }
|
|
|
|
|
| -static void CreateArrayDispatchOneArgument(MacroAssembler* masm) {
|
| - // r2 - type info cell
|
| - // r3 - kind
|
| +static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
|
| + AllocationSiteOverrideMode mode) {
|
| + // r2 - type info cell (if mode != DISABLE_ALLOCATION_SITES)
|
| + // r3 - kind (if mode != DISABLE_ALLOCATION_SITES)
|
| // r0 - number of arguments
|
| // r1 - constructor?
|
| // sp[0] - last argument
|
| - ASSERT(FAST_SMI_ELEMENTS == 0);
|
| - ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
|
| - ASSERT(FAST_ELEMENTS == 2);
|
| - ASSERT(FAST_HOLEY_ELEMENTS == 3);
|
| - ASSERT(FAST_DOUBLE_ELEMENTS == 4);
|
| - ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
|
| -
|
| - // is the low bit set? If so, we are holey and that is good.
|
| - __ tst(r3, Operand(1));
|
| Label normal_sequence;
|
| - __ b(ne, &normal_sequence);
|
| + if (mode == DONT_OVERRIDE) {
|
| + ASSERT(FAST_SMI_ELEMENTS == 0);
|
| + ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
|
| + ASSERT(FAST_ELEMENTS == 2);
|
| + ASSERT(FAST_HOLEY_ELEMENTS == 3);
|
| + ASSERT(FAST_DOUBLE_ELEMENTS == 4);
|
| + ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
|
| +
|
| + // is the low bit set? If so, we are holey and that is good.
|
| + __ tst(r3, Operand(1));
|
| + __ b(ne, &normal_sequence);
|
| + }
|
|
|
| // look at the first argument
|
| __ ldr(r5, MemOperand(sp, 0));
|
| __ cmp(r5, Operand::Zero());
|
| __ b(eq, &normal_sequence);
|
|
|
| - // We are going to create a holey array, but our kind is non-holey.
|
| - // Fix kind and retry (only if we have an allocation site in the cell).
|
| - __ add(r3, r3, Operand(1));
|
| - __ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
|
| - __ b(eq, &normal_sequence);
|
| - __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset));
|
| - __ ldr(r5, FieldMemOperand(r5, 0));
|
| - __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex);
|
| - __ b(ne, &normal_sequence);
|
| + if (mode == DISABLE_ALLOCATION_SITES) {
|
| + ElementsKind initial = GetInitialFastElementsKind();
|
| + ElementsKind holey_initial = GetHoleyElementsKind(initial);
|
|
|
| - // Save the resulting elements kind in type info
|
| - __ SmiTag(r3);
|
| - __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset));
|
| - __ str(r3, FieldMemOperand(r5, AllocationSite::kTransitionInfoOffset));
|
| - __ SmiUntag(r3);
|
| + ArraySingleArgumentConstructorStub stub_holey(holey_initial,
|
| + CONTEXT_CHECK_REQUIRED,
|
| + DISABLE_ALLOCATION_SITES);
|
| + __ TailCallStub(&stub_holey);
|
|
|
| - __ bind(&normal_sequence);
|
| - int last_index = GetSequenceIndexFromFastElementsKind(
|
| - TERMINAL_FAST_ELEMENTS_KIND);
|
| - for (int i = 0; i <= last_index; ++i) {
|
| - Label next;
|
| - ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
|
| - __ cmp(r3, Operand(kind));
|
| - __ b(ne, &next);
|
| - ArraySingleArgumentConstructorStub stub(kind);
|
| + __ bind(&normal_sequence);
|
| + ArraySingleArgumentConstructorStub stub(initial,
|
| + CONTEXT_CHECK_REQUIRED,
|
| + DISABLE_ALLOCATION_SITES);
|
| __ TailCallStub(&stub);
|
| - __ bind(&next);
|
| - }
|
| + } else if (mode == DONT_OVERRIDE) {
|
| + // We are going to create a holey array, but our kind is non-holey.
|
| + // Fix kind and retry (only if we have an allocation site in the cell).
|
| + __ add(r3, r3, Operand(1));
|
| + __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset));
|
| +
|
| + if (FLAG_debug_code) {
|
| + __ ldr(r5, FieldMemOperand(r5, 0));
|
| + __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex);
|
| + __ Assert(eq, kExpectedAllocationSiteInCell);
|
| + __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset));
|
| + }
|
| +
|
| + // Save the resulting elements kind in type info
|
| + __ SmiTag(r3);
|
| + __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset));
|
| + __ str(r3, FieldMemOperand(r5, AllocationSite::kTransitionInfoOffset));
|
| + __ SmiUntag(r3);
|
| +
|
| + __ bind(&normal_sequence);
|
| + int last_index = GetSequenceIndexFromFastElementsKind(
|
| + TERMINAL_FAST_ELEMENTS_KIND);
|
| + for (int i = 0; i <= last_index; ++i) {
|
| + Label next;
|
| + ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
|
| + __ cmp(r3, Operand(kind));
|
| + __ b(ne, &next);
|
| + ArraySingleArgumentConstructorStub stub(kind);
|
| + __ TailCallStub(&stub);
|
| + __ bind(&next);
|
| + }
|
|
|
| - // If we reached this point there is a problem.
|
| - __ Abort(kUnexpectedElementsKindInArrayConstructor);
|
| + // If we reached this point there is a problem.
|
| + __ Abort(kUnexpectedElementsKindInArrayConstructor);
|
| + } else {
|
| + UNREACHABLE();
|
| + }
|
| }
|
|
|
|
|
| template<class T>
|
| static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
|
| + ElementsKind initial_kind = GetInitialFastElementsKind();
|
| + ElementsKind initial_holey_kind = GetHoleyElementsKind(initial_kind);
|
| +
|
| int to_index = GetSequenceIndexFromFastElementsKind(
|
| TERMINAL_FAST_ELEMENTS_KIND);
|
| for (int i = 0; i <= to_index; ++i) {
|
| ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
|
| T stub(kind);
|
| stub.GetCode(isolate)->set_is_pregenerated(true);
|
| - if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
|
| + if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE ||
|
| + (!FLAG_track_allocation_sites &&
|
| + (kind == initial_kind || kind == initial_holey_kind))) {
|
| T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES);
|
| stub1.GetCode(isolate)->set_is_pregenerated(true);
|
| }
|
| @@ -6971,6 +6991,34 @@ void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
|
| }
|
|
|
|
|
| +void ArrayConstructorStub::GenerateDispatchToArrayStub(
|
| + MacroAssembler* masm,
|
| + AllocationSiteOverrideMode mode) {
|
| + if (argument_count_ == ANY) {
|
| + Label not_zero_case, not_one_case;
|
| + __ tst(r0, r0);
|
| + __ b(ne, ¬_zero_case);
|
| + CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
|
| +
|
| + __ bind(¬_zero_case);
|
| + __ cmp(r0, Operand(1));
|
| + __ b(gt, ¬_one_case);
|
| + CreateArrayDispatchOneArgument(masm, mode);
|
| +
|
| + __ bind(¬_one_case);
|
| + CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
|
| + } else if (argument_count_ == NONE) {
|
| + CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
|
| + } else if (argument_count_ == ONE) {
|
| + CreateArrayDispatchOneArgument(masm, mode);
|
| + } else if (argument_count_ == MORE_THAN_ONE) {
|
| + CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
|
| + } else {
|
| + UNREACHABLE();
|
| + }
|
| +}
|
| +
|
| +
|
| void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
| // ----------- S t a t e -------------
|
| // -- r0 : argc (only if argument_count_ == ANY)
|
| @@ -7002,50 +7050,24 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
| __ bind(&okay_here);
|
| }
|
|
|
| - Label no_info, switch_ready;
|
| + Label no_info;
|
| // Get the elements kind and case on that.
|
| __ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
|
| __ b(eq, &no_info);
|
| __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset));
|
|
|
| - // The type cell may have undefined in its value.
|
| - __ CompareRoot(r3, Heap::kUndefinedValueRootIndex);
|
| - __ b(eq, &no_info);
|
| -
|
| - // The type cell has either an AllocationSite or a JSFunction
|
| + // If the type cell is undefined, or contains anything other than an
|
| + // AllocationSite, call an array constructor that doesn't use AllocationSites.
|
| __ ldr(r4, FieldMemOperand(r3, 0));
|
| __ CompareRoot(r4, Heap::kAllocationSiteMapRootIndex);
|
| __ b(ne, &no_info);
|
|
|
| __ ldr(r3, FieldMemOperand(r3, AllocationSite::kTransitionInfoOffset));
|
| __ SmiUntag(r3);
|
| - __ jmp(&switch_ready);
|
| - __ bind(&no_info);
|
| - __ mov(r3, Operand(GetInitialFastElementsKind()));
|
| - __ bind(&switch_ready);
|
| -
|
| - if (argument_count_ == ANY) {
|
| - Label not_zero_case, not_one_case;
|
| - __ tst(r0, r0);
|
| - __ b(ne, ¬_zero_case);
|
| - CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
|
| -
|
| - __ bind(¬_zero_case);
|
| - __ cmp(r0, Operand(1));
|
| - __ b(gt, ¬_one_case);
|
| - CreateArrayDispatchOneArgument(masm);
|
| + GenerateDispatchToArrayStub(masm, DONT_OVERRIDE);
|
|
|
| - __ bind(¬_one_case);
|
| - CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
|
| - } else if (argument_count_ == NONE) {
|
| - CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
|
| - } else if (argument_count_ == ONE) {
|
| - CreateArrayDispatchOneArgument(masm);
|
| - } else if (argument_count_ == MORE_THAN_ONE) {
|
| - CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
|
| - } else {
|
| - UNREACHABLE();
|
| - }
|
| + __ bind(&no_info);
|
| + GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES);
|
| }
|
|
|
|
|
|
|