Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/mips/code-stubs-mips.cc

Issue 13905009: MIPS: Constructed arrays can be created with Hydrogen code stubs. The feature is still off by defau… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mips/code-stubs-mips.h ('k') | src/mips/lithium-codegen-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 static Register registers[] = { a0 }; 103 static Register registers[] = { a0 };
104 descriptor->register_param_count_ = 1; 104 descriptor->register_param_count_ = 1;
105 descriptor->register_params_ = registers; 105 descriptor->register_params_ = registers;
106 descriptor->deoptimization_handler_ = 106 descriptor->deoptimization_handler_ =
107 FUNCTION_ADDR(CompareNilIC_Miss); 107 FUNCTION_ADDR(CompareNilIC_Miss);
108 descriptor->miss_handler_ = 108 descriptor->miss_handler_ =
109 ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate); 109 ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate);
110 } 110 }
111 111
112 112
113 static void InitializeArrayConstructorDescriptor(Isolate* isolate, 113 static void InitializeArrayConstructorDescriptor(
114 CodeStubInterfaceDescriptor* descriptor) { 114 Isolate* isolate,
115 CodeStubInterfaceDescriptor* descriptor,
116 int constant_stack_parameter_count) {
115 // register state 117 // register state
116 // a1 -- constructor function 118 // a0 -- number of arguments
117 // a2 -- type info cell with elements kind 119 // a2 -- type info cell with elements kind
118 // a0 -- number of arguments to the constructor function 120 static Register registers[] = { a2 };
119 static Register registers[] = { a1, a2 }; 121 descriptor->register_param_count_ = 1;
120 descriptor->register_param_count_ = 2; 122 if (constant_stack_parameter_count != 0) {
121 // stack param count needs (constructor pointer, and single argument) 123 // stack param count needs (constructor pointer, and single argument)
122 descriptor->stack_parameter_count_ = &a0; 124 descriptor->stack_parameter_count_ = &a0;
125 }
126 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
123 descriptor->register_params_ = registers; 127 descriptor->register_params_ = registers;
124 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; 128 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
125 descriptor->deoptimization_handler_ = 129 descriptor->deoptimization_handler_ =
126 FUNCTION_ADDR(ArrayConstructor_StubFailure); 130 FUNCTION_ADDR(ArrayConstructor_StubFailure);
127 } 131 }
128 132
129 133
130 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( 134 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
131 Isolate* isolate, 135 Isolate* isolate,
132 CodeStubInterfaceDescriptor* descriptor) { 136 CodeStubInterfaceDescriptor* descriptor) {
133 InitializeArrayConstructorDescriptor(isolate, descriptor); 137 InitializeArrayConstructorDescriptor(isolate, descriptor, 0);
134 } 138 }
135 139
136 140
137 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( 141 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
138 Isolate* isolate, 142 Isolate* isolate,
139 CodeStubInterfaceDescriptor* descriptor) { 143 CodeStubInterfaceDescriptor* descriptor) {
140 InitializeArrayConstructorDescriptor(isolate, descriptor); 144 InitializeArrayConstructorDescriptor(isolate, descriptor, 1);
141 } 145 }
142 146
143 147
144 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( 148 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
145 Isolate* isolate, 149 Isolate* isolate,
146 CodeStubInterfaceDescriptor* descriptor) { 150 CodeStubInterfaceDescriptor* descriptor) {
147 InitializeArrayConstructorDescriptor(isolate, descriptor); 151 InitializeArrayConstructorDescriptor(isolate, descriptor, -1);
148 } 152 }
149 153
150 154
151 #define __ ACCESS_MASM(masm) 155 #define __ ACCESS_MASM(masm)
152 156
153 static void EmitIdenticalObjectComparison(MacroAssembler* masm, 157 static void EmitIdenticalObjectComparison(MacroAssembler* masm,
154 Label* slow, 158 Label* slow,
155 Condition cc); 159 Condition cc);
156 static void EmitSmiNonsmiComparison(MacroAssembler* masm, 160 static void EmitSmiNonsmiComparison(MacroAssembler* masm,
157 Register lhs, 161 Register lhs,
(...skipping 3177 matching lines...) Expand 10 before | Expand all | Expand 10 after
3335 result_size_ == 1; 3339 result_size_ == 1;
3336 } 3340 }
3337 3341
3338 3342
3339 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { 3343 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
3340 CEntryStub::GenerateAheadOfTime(isolate); 3344 CEntryStub::GenerateAheadOfTime(isolate);
3341 WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(isolate); 3345 WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(isolate);
3342 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); 3346 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
3343 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); 3347 StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
3344 RecordWriteStub::GenerateFixedRegStubsAheadOfTime(isolate); 3348 RecordWriteStub::GenerateFixedRegStubsAheadOfTime(isolate);
3349 if (FLAG_optimize_constructed_arrays) {
3350 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
3351 }
3345 } 3352 }
3346 3353
3347 3354
3348 void CodeStub::GenerateFPStubs(Isolate* isolate) { 3355 void CodeStub::GenerateFPStubs(Isolate* isolate) {
3349 SaveFPRegsMode mode = kSaveFPRegs; 3356 SaveFPRegsMode mode = kSaveFPRegs;
3350 CEntryStub save_doubles(1, mode); 3357 CEntryStub save_doubles(1, mode);
3351 StoreBufferOverflowStub stub(mode); 3358 StoreBufferOverflowStub stub(mode);
3352 // These stubs might already be in the snapshot, detect that and don't 3359 // These stubs might already be in the snapshot, detect that and don't
3353 // regenerate, which would lead to code stub initialization state being messed 3360 // regenerate, which would lead to code stub initialization state being messed
3354 // up. 3361 // up.
(...skipping 1734 matching lines...) Expand 10 before | Expand all | Expand 10 after
5089 __ Branch(&done, eq, a3, Operand(a1)); 5096 __ Branch(&done, eq, a3, Operand(a1));
5090 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 5097 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
5091 __ Branch(&done, eq, a3, Operand(at)); 5098 __ Branch(&done, eq, a3, Operand(at));
5092 5099
5093 // Special handling of the Array() function, which caches not only the 5100 // Special handling of the Array() function, which caches not only the
5094 // monomorphic Array function but the initial ElementsKind with special 5101 // monomorphic Array function but the initial ElementsKind with special
5095 // sentinels 5102 // sentinels
5096 Handle<Object> terminal_kind_sentinel = 5103 Handle<Object> terminal_kind_sentinel =
5097 TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(), 5104 TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(),
5098 LAST_FAST_ELEMENTS_KIND); 5105 LAST_FAST_ELEMENTS_KIND);
5099 __ Branch(&miss, ne, a3, Operand(terminal_kind_sentinel)); 5106 __ Branch(&miss, gt, a3, Operand(terminal_kind_sentinel));
5100 // Make sure the function is the Array() function 5107 // Make sure the function is the Array() function
5101 __ LoadArrayFunction(a3); 5108 __ LoadArrayFunction(a3);
5102 __ Branch(&megamorphic, ne, a1, Operand(a3)); 5109 __ Branch(&megamorphic, ne, a1, Operand(a3));
5103 __ jmp(&done); 5110 __ jmp(&done);
5104 5111
5105 __ bind(&miss); 5112 __ bind(&miss);
5106 5113
5107 // A monomorphic miss (i.e, here the cache is not uninitialized) goes 5114 // A monomorphic miss (i.e, here the cache is not uninitialized) goes
5108 // megamorphic. 5115 // megamorphic.
5109 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 5116 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
(...skipping 2445 matching lines...) Expand 10 before | Expand all | Expand 10 after
7555 // Restore the stack pointer if needed. 7562 // Restore the stack pointer if needed.
7556 if (frame_alignment > kPointerSize) { 7563 if (frame_alignment > kPointerSize) {
7557 __ mov(sp, t1); 7564 __ mov(sp, t1);
7558 } 7565 }
7559 7566
7560 __ Pop(ra, t1, a1); 7567 __ Pop(ra, t1, a1);
7561 __ Ret(); 7568 __ Ret();
7562 } 7569 }
7563 7570
7564 7571
7572 template<class T>
7573 static void CreateArrayDispatch(MacroAssembler* masm) {
7574 int last_index = GetSequenceIndexFromFastElementsKind(
7575 TERMINAL_FAST_ELEMENTS_KIND);
7576 for (int i = 0; i <= last_index; ++i) {
7577 Label next;
7578 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
7579 __ Branch(&next, ne, a3, Operand(kind));
7580 T stub(kind);
7581 __ TailCallStub(&stub);
7582 __ bind(&next);
7583 }
7584
7585 // If we reached this point there is a problem.
7586 __ Abort("Unexpected ElementsKind in array constructor");
7587 }
7588
7589
7590 static void CreateArrayDispatchOneArgument(MacroAssembler* masm) {
7591 // a2 - type info cell
7592 // a3 - kind
7593 // a0 - number of arguments
7594 // a1 - constructor?
7595 // sp[0] - last argument
7596 ASSERT(FAST_SMI_ELEMENTS == 0);
7597 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
7598 ASSERT(FAST_ELEMENTS == 2);
7599 ASSERT(FAST_HOLEY_ELEMENTS == 3);
7600 ASSERT(FAST_DOUBLE_ELEMENTS == 4);
7601 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
7602
7603 Handle<Object> undefined_sentinel(
7604 masm->isolate()->heap()->undefined_value(),
7605 masm->isolate());
7606
7607 // is the low bit set? If so, we are holey and that is good.
7608 Label normal_sequence;
7609 __ And(at, a3, Operand(1));
7610 __ Branch(&normal_sequence, ne, at, Operand(zero_reg));
7611
7612 // look at the first argument
7613 __ lw(t1, MemOperand(sp, 0));
7614 __ Branch(&normal_sequence, eq, t1, Operand(zero_reg));
7615
7616 // We are going to create a holey array, but our kind is non-holey.
7617 // Fix kind and retry
7618 __ Addu(a3, a3, Operand(1));
7619 __ Branch(&normal_sequence, eq, a2, Operand(undefined_sentinel));
7620
7621 // Save the resulting elements kind in type info
7622 __ SmiTag(a3);
7623 __ sw(a3, FieldMemOperand(a2, kPointerSize));
7624 __ SmiUntag(a3);
7625
7626 __ bind(&normal_sequence);
7627 int last_index = GetSequenceIndexFromFastElementsKind(
7628 TERMINAL_FAST_ELEMENTS_KIND);
7629 for (int i = 0; i <= last_index; ++i) {
7630 Label next;
7631 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
7632 __ Branch(&next, ne, a3, Operand(kind));
7633 ArraySingleArgumentConstructorStub stub(kind);
7634 __ TailCallStub(&stub);
7635 __ bind(&next);
7636 }
7637
7638 // If we reached this point there is a problem.
7639 __ Abort("Unexpected ElementsKind in array constructor");
7640 }
7641
7642
7643 template<class T>
7644 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
7645 int to_index = GetSequenceIndexFromFastElementsKind(
7646 TERMINAL_FAST_ELEMENTS_KIND);
7647 for (int i = 0; i <= to_index; ++i) {
7648 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
7649 T stub(kind);
7650 stub.GetCode(isolate)->set_is_pregenerated(true);
7651 }
7652 }
7653
7654
7655 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
7656 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
7657 isolate);
7658 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>(
7659 isolate);
7660 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>(
7661 isolate);
7662 }
7663
7664
7665 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
7666 // ----------- S t a t e -------------
7667 // -- a0 : argc (only if argument_count_ == ANY)
7668 // -- a1 : constructor
7669 // -- a2 : type info cell
7670 // -- sp[0] : return address
7671 // -- sp[4] : last argument
7672 // -----------------------------------
7673 Handle<Object> undefined_sentinel(
7674 masm->isolate()->heap()->undefined_value(),
7675 masm->isolate());
7676
7677 if (FLAG_debug_code) {
7678 // The array construct code is only set for the global and natives
7679 // builtin Array functions which always have maps.
7680
7681 // Initial map for the builtin Array function should be a map.
7682 __ lw(a3, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
7683 // Will both indicate a NULL and a Smi.
7684 __ And(at, a3, Operand(kSmiTagMask));
7685 __ Assert(ne, "Unexpected initial map for Array function",
7686 at, Operand(zero_reg));
7687 __ GetObjectType(a3, a3, t0);
7688 __ Assert(eq, "Unexpected initial map for Array function",
7689 t0, Operand(MAP_TYPE));
7690
7691 // We should either have undefined in ebx or a valid jsglobalpropertycell
7692 Label okay_here;
7693 Handle<Map> global_property_cell_map(
7694 masm->isolate()->heap()->global_property_cell_map());
7695 __ Branch(&okay_here, eq, a2, Operand(undefined_sentinel));
7696 __ lw(a3, FieldMemOperand(a2, 0));
7697 __ Assert(eq, "Expected property cell in register ebx",
7698 a3, Operand(global_property_cell_map));
7699 __ bind(&okay_here);
7700 }
7701
7702 if (FLAG_optimize_constructed_arrays) {
7703 Label no_info, switch_ready;
7704 // Get the elements kind and case on that.
7705 __ Branch(&no_info, eq, a2, Operand(undefined_sentinel));
7706 __ lw(a3, FieldMemOperand(a2, kPointerSize));
7707
7708 // There is no info if the call site went megamorphic either
7709 // TODO(mvstanton): Really? I thought if it was the array function that
7710 // the cell wouldn't get stamped as megamorphic.
7711 __ Branch(&no_info, eq, a3,
7712 Operand(TypeFeedbackCells::MegamorphicSentinel(masm->isolate())));
7713 __ SmiUntag(a3);
7714 __ jmp(&switch_ready);
7715 __ bind(&no_info);
7716 __ li(a3, Operand(GetInitialFastElementsKind()));
7717 __ bind(&switch_ready);
7718
7719 if (argument_count_ == ANY) {
7720 Label not_zero_case, not_one_case;
7721 __ And(at, a0, a0);
7722 __ Branch(&not_zero_case, ne, at, Operand(zero_reg));
7723 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
7724
7725 __ bind(&not_zero_case);
7726 __ Branch(&not_one_case, gt, a0, Operand(1));
7727 CreateArrayDispatchOneArgument(masm);
7728
7729 __ bind(&not_one_case);
7730 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
7731 } else if (argument_count_ == NONE) {
7732 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
7733 } else if (argument_count_ == ONE) {
7734 CreateArrayDispatchOneArgument(masm);
7735 } else if (argument_count_ == MORE_THAN_ONE) {
7736 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
7737 } else {
7738 UNREACHABLE();
7739 }
7740 } else {
7741 Label generic_constructor;
7742 // Run the native code for the Array function called as a constructor.
7743 ArrayNativeCode(masm, &generic_constructor);
7744
7745 // Jump to the generic construct code in case the specialized code cannot
7746 // handle the construction.
7747 __ bind(&generic_constructor);
7748 Handle<Code> generic_construct_stub =
7749 masm->isolate()->builtins()->JSConstructStubGeneric();
7750 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
7751 }
7752 }
7753
7754
7565 #undef __ 7755 #undef __
7566 7756
7567 } } // namespace v8::internal 7757 } } // namespace v8::internal
7568 7758
7569 #endif // V8_TARGET_ARCH_MIPS 7759 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/code-stubs-mips.h ('k') | src/mips/lithium-codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698