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

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

Issue 426233002: Land the Fan (disabled) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback, rebase and "git cl format" Created 6 years, 4 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/arm/assembler-arm.cc ('k') | src/arm/deoptimizer-arm.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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_ARM 7 #if V8_TARGET_ARCH_ARM
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
11 #include "src/regexp-macro-assembler.h" 11 #include "src/regexp-macro-assembler.h"
12 #include "src/stub-cache.h" 12 #include "src/stub-cache.h"
13 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 16
17 17
18 void FastNewClosureStub::InitializeInterfaceDescriptor( 18 void FastNewClosureStub::InitializeInterfaceDescriptor(
19 CodeStubInterfaceDescriptor* descriptor) { 19 CodeStubInterfaceDescriptor* descriptor) {
20 Register registers[] = { cp, r2 }; 20 Register registers[] = { cp, r2 };
21 descriptor->Initialize( 21 descriptor->Initialize(
22 ARRAY_SIZE(registers), registers, 22 MajorKey(), ARRAY_SIZE(registers), registers,
23 Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry); 23 Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry);
24 } 24 }
25 25
26 26
27 void FastNewContextStub::InitializeInterfaceDescriptor( 27 void FastNewContextStub::InitializeInterfaceDescriptor(
28 CodeStubInterfaceDescriptor* descriptor) { 28 CodeStubInterfaceDescriptor* descriptor) {
29 Register registers[] = { cp, r1 }; 29 Register registers[] = { cp, r1 };
30 descriptor->Initialize(ARRAY_SIZE(registers), registers); 30 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers);
31 } 31 }
32 32
33 33
34 void ToNumberStub::InitializeInterfaceDescriptor( 34 void ToNumberStub::InitializeInterfaceDescriptor(
35 CodeStubInterfaceDescriptor* descriptor) { 35 CodeStubInterfaceDescriptor* descriptor) {
36 Register registers[] = { cp, r0 }; 36 Register registers[] = { cp, r0 };
37 descriptor->Initialize(ARRAY_SIZE(registers), registers); 37 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers);
38 } 38 }
39 39
40 40
41 void NumberToStringStub::InitializeInterfaceDescriptor( 41 void NumberToStringStub::InitializeInterfaceDescriptor(
42 CodeStubInterfaceDescriptor* descriptor) { 42 CodeStubInterfaceDescriptor* descriptor) {
43 Register registers[] = { cp, r0 }; 43 Register registers[] = { cp, r0 };
44 descriptor->Initialize( 44 descriptor->Initialize(
45 ARRAY_SIZE(registers), registers, 45 MajorKey(), ARRAY_SIZE(registers), registers,
46 Runtime::FunctionForId(Runtime::kNumberToStringRT)->entry); 46 Runtime::FunctionForId(Runtime::kNumberToStringRT)->entry);
47 } 47 }
48 48
49 49
50 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( 50 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
51 CodeStubInterfaceDescriptor* descriptor) { 51 CodeStubInterfaceDescriptor* descriptor) {
52 Register registers[] = { cp, r3, r2, r1 }; 52 Register registers[] = { cp, r3, r2, r1 };
53 Representation representations[] = { 53 Representation representations[] = {
54 Representation::Tagged(), 54 Representation::Tagged(),
55 Representation::Tagged(), 55 Representation::Tagged(),
56 Representation::Smi(), 56 Representation::Smi(),
57 Representation::Tagged() }; 57 Representation::Tagged() };
58 descriptor->Initialize( 58 descriptor->Initialize(
59 ARRAY_SIZE(registers), registers, 59 MajorKey(), ARRAY_SIZE(registers), registers,
60 Runtime::FunctionForId( 60 Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry,
61 Runtime::kCreateArrayLiteralStubBailout)->entry,
62 representations); 61 representations);
63 } 62 }
64 63
65 64
66 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( 65 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
67 CodeStubInterfaceDescriptor* descriptor) { 66 CodeStubInterfaceDescriptor* descriptor) {
68 Register registers[] = { cp, r3, r2, r1, r0 }; 67 Register registers[] = { cp, r3, r2, r1, r0 };
69 descriptor->Initialize( 68 descriptor->Initialize(
70 ARRAY_SIZE(registers), registers, 69 MajorKey(), ARRAY_SIZE(registers), registers,
71 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry); 70 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry);
72 } 71 }
73 72
74 73
75 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( 74 void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
76 CodeStubInterfaceDescriptor* descriptor) { 75 CodeStubInterfaceDescriptor* descriptor) {
77 Register registers[] = { cp, r2, r3 }; 76 Register registers[] = { cp, r2, r3 };
78 descriptor->Initialize(ARRAY_SIZE(registers), registers); 77 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers);
79 } 78 }
80 79
81 80
81 void InstanceofStub::InitializeInterfaceDescriptor(
82 Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) {
83 Register registers[] = {cp, left(), right()};
84 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers);
85 }
86
87
88 void CallFunctionStub::InitializeInterfaceDescriptor(
89 Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) {
90 // r1 function the function to call
91 Register registers[] = {cp, r1};
92 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers);
93 }
94
95
96 void CallConstructStub::InitializeInterfaceDescriptor(
97 Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) {
98 // r0 : number of arguments
99 // r1 : the function to call
100 // r2 : feedback vector
101 // r3 : (only if r2 is not the megamorphic symbol) slot in feedback
102 // vector (Smi)
103 // TODO(turbofan): So far we don't gather type feedback and hence skip the
104 // slot parameter, but ArrayConstructStub needs the vector to be undefined.
105 Register registers[] = {cp, r0, r1, r2};
106 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers);
107 }
108
109
82 void RegExpConstructResultStub::InitializeInterfaceDescriptor( 110 void RegExpConstructResultStub::InitializeInterfaceDescriptor(
83 CodeStubInterfaceDescriptor* descriptor) { 111 CodeStubInterfaceDescriptor* descriptor) {
84 Register registers[] = { cp, r2, r1, r0 }; 112 Register registers[] = { cp, r2, r1, r0 };
85 descriptor->Initialize( 113 descriptor->Initialize(
86 ARRAY_SIZE(registers), registers, 114 MajorKey(), ARRAY_SIZE(registers), registers,
87 Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry); 115 Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry);
88 } 116 }
89 117
90 118
91 void TransitionElementsKindStub::InitializeInterfaceDescriptor( 119 void TransitionElementsKindStub::InitializeInterfaceDescriptor(
92 CodeStubInterfaceDescriptor* descriptor) { 120 CodeStubInterfaceDescriptor* descriptor) {
93 Register registers[] = { cp, r0, r1 }; 121 Register registers[] = { cp, r0, r1 };
94 Address entry = 122 Address entry =
95 Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry; 123 Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry;
96 descriptor->Initialize(ARRAY_SIZE(registers), registers, 124 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
97 FUNCTION_ADDR(entry)); 125 FUNCTION_ADDR(entry));
98 } 126 }
99 127
100 128
101 void CompareNilICStub::InitializeInterfaceDescriptor( 129 void CompareNilICStub::InitializeInterfaceDescriptor(
102 CodeStubInterfaceDescriptor* descriptor) { 130 CodeStubInterfaceDescriptor* descriptor) {
103 Register registers[] = { cp, r0 }; 131 Register registers[] = { cp, r0 };
104 descriptor->Initialize(ARRAY_SIZE(registers), registers, 132 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
105 FUNCTION_ADDR(CompareNilIC_Miss)); 133 FUNCTION_ADDR(CompareNilIC_Miss));
106 descriptor->SetMissHandler( 134 descriptor->SetMissHandler(
107 ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate())); 135 ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate()));
108 } 136 }
109 137
110 138
111 const Register InterfaceDescriptor::ContextRegister() { return cp; } 139 const Register InterfaceDescriptor::ContextRegister() { return cp; }
112 140
113 141
114 static void InitializeArrayConstructorDescriptor( 142 static void InitializeArrayConstructorDescriptor(
115 CodeStubInterfaceDescriptor* descriptor, 143 CodeStub::Major major, CodeStubInterfaceDescriptor* descriptor,
116 int constant_stack_parameter_count) { 144 int constant_stack_parameter_count) {
117 // register state 145 // register state
118 // cp -- context 146 // cp -- context
119 // r0 -- number of arguments 147 // r0 -- number of arguments
120 // r1 -- function 148 // r1 -- function
121 // r2 -- allocation site with elements kind 149 // r2 -- allocation site with elements kind
122 Address deopt_handler = Runtime::FunctionForId( 150 Address deopt_handler = Runtime::FunctionForId(
123 Runtime::kArrayConstructor)->entry; 151 Runtime::kArrayConstructor)->entry;
124 152
125 if (constant_stack_parameter_count == 0) { 153 if (constant_stack_parameter_count == 0) {
126 Register registers[] = { cp, r1, r2 }; 154 Register registers[] = { cp, r1, r2 };
127 descriptor->Initialize(ARRAY_SIZE(registers), registers, 155 descriptor->Initialize(major, ARRAY_SIZE(registers), registers,
128 deopt_handler, 156 deopt_handler, NULL, constant_stack_parameter_count,
129 NULL,
130 constant_stack_parameter_count,
131 JS_FUNCTION_STUB_MODE); 157 JS_FUNCTION_STUB_MODE);
132 } else { 158 } else {
133 // stack param count needs (constructor pointer, and single argument) 159 // stack param count needs (constructor pointer, and single argument)
134 Register registers[] = { cp, r1, r2, r0 }; 160 Register registers[] = { cp, r1, r2, r0 };
135 Representation representations[] = { 161 Representation representations[] = {
136 Representation::Tagged(), 162 Representation::Tagged(),
137 Representation::Tagged(), 163 Representation::Tagged(),
138 Representation::Tagged(), 164 Representation::Tagged(),
139 Representation::Integer32() }; 165 Representation::Integer32() };
140 descriptor->Initialize(ARRAY_SIZE(registers), registers, 166 descriptor->Initialize(major, ARRAY_SIZE(registers), registers, r0,
141 r0, 167 deopt_handler, representations,
142 deopt_handler,
143 representations,
144 constant_stack_parameter_count, 168 constant_stack_parameter_count,
145 JS_FUNCTION_STUB_MODE, 169 JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS);
146 PASS_ARGUMENTS);
147 } 170 }
148 } 171 }
149 172
150 173
151 static void InitializeInternalArrayConstructorDescriptor( 174 static void InitializeInternalArrayConstructorDescriptor(
152 CodeStubInterfaceDescriptor* descriptor, 175 CodeStub::Major major, CodeStubInterfaceDescriptor* descriptor,
153 int constant_stack_parameter_count) { 176 int constant_stack_parameter_count) {
154 // register state 177 // register state
155 // cp -- context 178 // cp -- context
156 // r0 -- number of arguments 179 // r0 -- number of arguments
157 // r1 -- constructor function 180 // r1 -- constructor function
158 Address deopt_handler = Runtime::FunctionForId( 181 Address deopt_handler = Runtime::FunctionForId(
159 Runtime::kInternalArrayConstructor)->entry; 182 Runtime::kInternalArrayConstructor)->entry;
160 183
161 if (constant_stack_parameter_count == 0) { 184 if (constant_stack_parameter_count == 0) {
162 Register registers[] = { cp, r1 }; 185 Register registers[] = { cp, r1 };
163 descriptor->Initialize(ARRAY_SIZE(registers), registers, 186 descriptor->Initialize(major, ARRAY_SIZE(registers), registers,
164 deopt_handler, 187 deopt_handler, NULL, constant_stack_parameter_count,
165 NULL,
166 constant_stack_parameter_count,
167 JS_FUNCTION_STUB_MODE); 188 JS_FUNCTION_STUB_MODE);
168 } else { 189 } else {
169 // stack param count needs (constructor pointer, and single argument) 190 // stack param count needs (constructor pointer, and single argument)
170 Register registers[] = { cp, r1, r0 }; 191 Register registers[] = { cp, r1, r0 };
171 Representation representations[] = { 192 Representation representations[] = {
172 Representation::Tagged(), 193 Representation::Tagged(),
173 Representation::Tagged(), 194 Representation::Tagged(),
174 Representation::Integer32() }; 195 Representation::Integer32() };
175 descriptor->Initialize(ARRAY_SIZE(registers), registers, 196 descriptor->Initialize(major, ARRAY_SIZE(registers), registers, r0,
176 r0, 197 deopt_handler, representations,
177 deopt_handler,
178 representations,
179 constant_stack_parameter_count, 198 constant_stack_parameter_count,
180 JS_FUNCTION_STUB_MODE, 199 JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS);
181 PASS_ARGUMENTS);
182 } 200 }
183 } 201 }
184 202
185 203
186 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( 204 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
187 CodeStubInterfaceDescriptor* descriptor) { 205 CodeStubInterfaceDescriptor* descriptor) {
188 InitializeArrayConstructorDescriptor(descriptor, 0); 206 InitializeArrayConstructorDescriptor(MajorKey(), descriptor, 0);
189 } 207 }
190 208
191 209
192 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( 210 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
193 CodeStubInterfaceDescriptor* descriptor) { 211 CodeStubInterfaceDescriptor* descriptor) {
194 InitializeArrayConstructorDescriptor(descriptor, 1); 212 InitializeArrayConstructorDescriptor(MajorKey(), descriptor, 1);
195 } 213 }
196 214
197 215
198 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( 216 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
199 CodeStubInterfaceDescriptor* descriptor) { 217 CodeStubInterfaceDescriptor* descriptor) {
200 InitializeArrayConstructorDescriptor(descriptor, -1); 218 InitializeArrayConstructorDescriptor(MajorKey(), descriptor, -1);
201 } 219 }
202 220
203 221
204 void ToBooleanStub::InitializeInterfaceDescriptor( 222 void ToBooleanStub::InitializeInterfaceDescriptor(
205 CodeStubInterfaceDescriptor* descriptor) { 223 CodeStubInterfaceDescriptor* descriptor) {
206 Register registers[] = { cp, r0 }; 224 Register registers[] = { cp, r0 };
207 descriptor->Initialize(ARRAY_SIZE(registers), registers, 225 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
208 FUNCTION_ADDR(ToBooleanIC_Miss)); 226 FUNCTION_ADDR(ToBooleanIC_Miss));
209 descriptor->SetMissHandler( 227 descriptor->SetMissHandler(
210 ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate())); 228 ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate()));
211 } 229 }
212 230
213 231
214 void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( 232 void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
215 CodeStubInterfaceDescriptor* descriptor) { 233 CodeStubInterfaceDescriptor* descriptor) {
216 InitializeInternalArrayConstructorDescriptor(descriptor, 0); 234 InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, 0);
217 } 235 }
218 236
219 237
220 void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( 238 void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
221 CodeStubInterfaceDescriptor* descriptor) { 239 CodeStubInterfaceDescriptor* descriptor) {
222 InitializeInternalArrayConstructorDescriptor(descriptor, 1); 240 InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, 1);
223 } 241 }
224 242
225 243
226 void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( 244 void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
227 CodeStubInterfaceDescriptor* descriptor) { 245 CodeStubInterfaceDescriptor* descriptor) {
228 InitializeInternalArrayConstructorDescriptor(descriptor, -1); 246 InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, -1);
229 } 247 }
230 248
231 249
232 void BinaryOpICStub::InitializeInterfaceDescriptor( 250 void BinaryOpICStub::InitializeInterfaceDescriptor(
233 CodeStubInterfaceDescriptor* descriptor) { 251 CodeStubInterfaceDescriptor* descriptor) {
234 Register registers[] = { cp, r1, r0 }; 252 Register registers[] = { cp, r1, r0 };
235 descriptor->Initialize(ARRAY_SIZE(registers), registers, 253 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
236 FUNCTION_ADDR(BinaryOpIC_Miss)); 254 FUNCTION_ADDR(BinaryOpIC_Miss));
237 descriptor->SetMissHandler( 255 descriptor->SetMissHandler(
238 ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate())); 256 ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate()));
239 } 257 }
240 258
241 259
242 void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor( 260 void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
243 CodeStubInterfaceDescriptor* descriptor) { 261 CodeStubInterfaceDescriptor* descriptor) {
244 Register registers[] = { cp, r2, r1, r0 }; 262 Register registers[] = { cp, r2, r1, r0 };
245 descriptor->Initialize(ARRAY_SIZE(registers), registers, 263 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
246 FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite)); 264 FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite));
247 } 265 }
248 266
249 267
250 void StringAddStub::InitializeInterfaceDescriptor( 268 void StringAddStub::InitializeInterfaceDescriptor(
251 CodeStubInterfaceDescriptor* descriptor) { 269 CodeStubInterfaceDescriptor* descriptor) {
252 Register registers[] = { cp, r1, r0 }; 270 Register registers[] = { cp, r1, r0 };
253 descriptor->Initialize( 271 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
254 ARRAY_SIZE(registers), registers, 272 Runtime::FunctionForId(Runtime::kStringAdd)->entry);
255 Runtime::FunctionForId(Runtime::kStringAdd)->entry);
256 } 273 }
257 274
258 275
259 void CallDescriptors::InitializeForIsolate(Isolate* isolate) { 276 void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
260 static PlatformInterfaceDescriptor default_descriptor = 277 static PlatformInterfaceDescriptor default_descriptor =
261 PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS); 278 PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
262 279
263 static PlatformInterfaceDescriptor noInlineDescriptor = 280 static PlatformInterfaceDescriptor noInlineDescriptor =
264 PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS); 281 PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
265 282
(...skipping 1399 matching lines...) Expand 10 before | Expand all | Expand 10 after
1665 // Expected input (depending on whether args are in registers or on the stack): 1682 // Expected input (depending on whether args are in registers or on the stack):
1666 // * object: r0 or at sp + 1 * kPointerSize. 1683 // * object: r0 or at sp + 1 * kPointerSize.
1667 // * function: r1 or at sp. 1684 // * function: r1 or at sp.
1668 // 1685 //
1669 // An inlined call site may have been generated before calling this stub. 1686 // An inlined call site may have been generated before calling this stub.
1670 // In this case the offset to the inline sites to patch are passed in r5 and r6. 1687 // In this case the offset to the inline sites to patch are passed in r5 and r6.
1671 // (See LCodeGen::DoInstanceOfKnownGlobal) 1688 // (See LCodeGen::DoInstanceOfKnownGlobal)
1672 void InstanceofStub::Generate(MacroAssembler* masm) { 1689 void InstanceofStub::Generate(MacroAssembler* masm) {
1673 // Call site inlining and patching implies arguments in registers. 1690 // Call site inlining and patching implies arguments in registers.
1674 ASSERT(HasArgsInRegisters() || !HasCallSiteInlineCheck()); 1691 ASSERT(HasArgsInRegisters() || !HasCallSiteInlineCheck());
1675 // ReturnTrueFalse is only implemented for inlined call sites.
1676 ASSERT(!ReturnTrueFalseObject() || HasCallSiteInlineCheck());
1677 1692
1678 // Fixed register usage throughout the stub: 1693 // Fixed register usage throughout the stub:
1679 const Register object = r0; // Object (lhs). 1694 const Register object = r0; // Object (lhs).
1680 Register map = r3; // Map of the object. 1695 Register map = r3; // Map of the object.
1681 const Register function = r1; // Function (rhs). 1696 const Register function = r1; // Function (rhs).
1682 const Register prototype = r4; // Prototype of the function. 1697 const Register prototype = r4; // Prototype of the function.
1683 const Register scratch = r2; 1698 const Register scratch = r2;
1684 1699
1685 Label slow, loop, is_instance, is_not_instance, not_js_object; 1700 Label slow, loop, is_instance, is_not_instance, not_js_object;
1686 1701
1687 if (!HasArgsInRegisters()) { 1702 if (!HasArgsInRegisters()) {
1688 __ ldr(object, MemOperand(sp, 1 * kPointerSize)); 1703 __ ldr(object, MemOperand(sp, 1 * kPointerSize));
1689 __ ldr(function, MemOperand(sp, 0)); 1704 __ ldr(function, MemOperand(sp, 0));
1690 } 1705 }
1691 1706
1692 // Check that the left hand is a JS object and load map. 1707 // Check that the left hand is a JS object and load map.
1693 __ JumpIfSmi(object, &not_js_object); 1708 __ JumpIfSmi(object, &not_js_object);
1694 __ IsObjectJSObjectType(object, map, scratch, &not_js_object); 1709 __ IsObjectJSObjectType(object, map, scratch, &not_js_object);
1695 1710
1696 // If there is a call site cache don't look in the global cache, but do the 1711 // If there is a call site cache don't look in the global cache, but do the
1697 // real lookup and update the call site cache. 1712 // real lookup and update the call site cache.
1698 if (!HasCallSiteInlineCheck()) { 1713 if (!HasCallSiteInlineCheck() && !ReturnTrueFalseObject()) {
1699 Label miss; 1714 Label miss;
1700 __ CompareRoot(function, Heap::kInstanceofCacheFunctionRootIndex); 1715 __ CompareRoot(function, Heap::kInstanceofCacheFunctionRootIndex);
1701 __ b(ne, &miss); 1716 __ b(ne, &miss);
1702 __ CompareRoot(map, Heap::kInstanceofCacheMapRootIndex); 1717 __ CompareRoot(map, Heap::kInstanceofCacheMapRootIndex);
1703 __ b(ne, &miss); 1718 __ b(ne, &miss);
1704 __ LoadRoot(r0, Heap::kInstanceofCacheAnswerRootIndex); 1719 __ LoadRoot(r0, Heap::kInstanceofCacheAnswerRootIndex);
1705 __ Ret(HasArgsInRegisters() ? 0 : 2); 1720 __ Ret(HasArgsInRegisters() ? 0 : 2);
1706 1721
1707 __ bind(&miss); 1722 __ bind(&miss);
1708 } 1723 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1744 // Loop through the prototype chain looking for the function prototype. 1759 // Loop through the prototype chain looking for the function prototype.
1745 __ LoadRoot(scratch2, Heap::kNullValueRootIndex); 1760 __ LoadRoot(scratch2, Heap::kNullValueRootIndex);
1746 __ bind(&loop); 1761 __ bind(&loop);
1747 __ cmp(scratch, Operand(prototype)); 1762 __ cmp(scratch, Operand(prototype));
1748 __ b(eq, &is_instance); 1763 __ b(eq, &is_instance);
1749 __ cmp(scratch, scratch2); 1764 __ cmp(scratch, scratch2);
1750 __ b(eq, &is_not_instance); 1765 __ b(eq, &is_not_instance);
1751 __ ldr(scratch, FieldMemOperand(scratch, HeapObject::kMapOffset)); 1766 __ ldr(scratch, FieldMemOperand(scratch, HeapObject::kMapOffset));
1752 __ ldr(scratch, FieldMemOperand(scratch, Map::kPrototypeOffset)); 1767 __ ldr(scratch, FieldMemOperand(scratch, Map::kPrototypeOffset));
1753 __ jmp(&loop); 1768 __ jmp(&loop);
1769 Factory* factory = isolate()->factory();
1754 1770
1755 __ bind(&is_instance); 1771 __ bind(&is_instance);
1756 if (!HasCallSiteInlineCheck()) { 1772 if (!HasCallSiteInlineCheck()) {
1757 __ mov(r0, Operand(Smi::FromInt(0))); 1773 __ mov(r0, Operand(Smi::FromInt(0)));
1758 __ StoreRoot(r0, Heap::kInstanceofCacheAnswerRootIndex); 1774 __ StoreRoot(r0, Heap::kInstanceofCacheAnswerRootIndex);
1775 if (ReturnTrueFalseObject()) {
1776 __ Move(r0, factory->true_value());
1777 }
1759 } else { 1778 } else {
1760 // Patch the call site to return true. 1779 // Patch the call site to return true.
1761 __ LoadRoot(r0, Heap::kTrueValueRootIndex); 1780 __ LoadRoot(r0, Heap::kTrueValueRootIndex);
1762 // The bool_load_offset was stored in r6 1781 // The bool_load_offset was stored in r6
1763 // (See LCodeGen::DoDeferredLInstanceOfKnownGlobal). 1782 // (See LCodeGen::DoDeferredLInstanceOfKnownGlobal).
1764 const Register bool_load_offset = r6; 1783 const Register bool_load_offset = r6;
1765 __ sub(r9, lr, bool_load_offset); 1784 __ sub(r9, lr, bool_load_offset);
1766 // Get the boolean result location in scratch and patch it. 1785 // Get the boolean result location in scratch and patch it.
1767 __ GetRelocatedValueLocation(r9, scratch, scratch2); 1786 __ GetRelocatedValueLocation(r9, scratch, scratch2);
1768 __ str(r0, MemOperand(scratch)); 1787 __ str(r0, MemOperand(scratch));
1769 1788
1770 if (!ReturnTrueFalseObject()) { 1789 if (!ReturnTrueFalseObject()) {
1771 __ mov(r0, Operand(Smi::FromInt(0))); 1790 __ mov(r0, Operand(Smi::FromInt(0)));
1772 } 1791 }
1773 } 1792 }
1774 __ Ret(HasArgsInRegisters() ? 0 : 2); 1793 __ Ret(HasArgsInRegisters() ? 0 : 2);
1775 1794
1776 __ bind(&is_not_instance); 1795 __ bind(&is_not_instance);
1777 if (!HasCallSiteInlineCheck()) { 1796 if (!HasCallSiteInlineCheck()) {
1778 __ mov(r0, Operand(Smi::FromInt(1))); 1797 __ mov(r0, Operand(Smi::FromInt(1)));
1779 __ StoreRoot(r0, Heap::kInstanceofCacheAnswerRootIndex); 1798 __ StoreRoot(r0, Heap::kInstanceofCacheAnswerRootIndex);
1799 if (ReturnTrueFalseObject()) {
1800 __ Move(r0, factory->false_value());
1801 }
1780 } else { 1802 } else {
1781 // Patch the call site to return false. 1803 // Patch the call site to return false.
1782 __ LoadRoot(r0, Heap::kFalseValueRootIndex); 1804 __ LoadRoot(r0, Heap::kFalseValueRootIndex);
1783 // The bool_load_offset was stored in r6 1805 // The bool_load_offset was stored in r6
1784 // (See LCodeGen::DoDeferredLInstanceOfKnownGlobal). 1806 // (See LCodeGen::DoDeferredLInstanceOfKnownGlobal).
1785 const Register bool_load_offset = r6; 1807 const Register bool_load_offset = r6;
1786 __ sub(r9, lr, bool_load_offset); 1808 __ sub(r9, lr, bool_load_offset);
1787 ; 1809 ;
1788 // Get the boolean result location in scratch and patch it. 1810 // Get the boolean result location in scratch and patch it.
1789 __ GetRelocatedValueLocation(r9, scratch, scratch2); 1811 __ GetRelocatedValueLocation(r9, scratch, scratch2);
1790 __ str(r0, MemOperand(scratch)); 1812 __ str(r0, MemOperand(scratch));
1791 1813
1792 if (!ReturnTrueFalseObject()) { 1814 if (!ReturnTrueFalseObject()) {
1793 __ mov(r0, Operand(Smi::FromInt(1))); 1815 __ mov(r0, Operand(Smi::FromInt(1)));
1794 } 1816 }
1795 } 1817 }
1796 __ Ret(HasArgsInRegisters() ? 0 : 2); 1818 __ Ret(HasArgsInRegisters() ? 0 : 2);
1797 1819
1798 Label object_not_null, object_not_null_or_smi; 1820 Label object_not_null, object_not_null_or_smi;
1799 __ bind(&not_js_object); 1821 __ bind(&not_js_object);
1800 // Before null, smi and string value checks, check that the rhs is a function 1822 // Before null, smi and string value checks, check that the rhs is a function
1801 // as for a non-function rhs an exception needs to be thrown. 1823 // as for a non-function rhs an exception needs to be thrown.
1802 __ JumpIfSmi(function, &slow); 1824 __ JumpIfSmi(function, &slow);
1803 __ CompareObjectType(function, scratch2, scratch, JS_FUNCTION_TYPE); 1825 __ CompareObjectType(function, scratch2, scratch, JS_FUNCTION_TYPE);
1804 __ b(ne, &slow); 1826 __ b(ne, &slow);
1805 1827
1806 // Null is not instance of anything. 1828 // Null is not instance of anything.
1807 __ cmp(scratch, Operand(isolate()->factory()->null_value())); 1829 __ cmp(scratch, Operand(isolate()->factory()->null_value()));
1808 __ b(ne, &object_not_null); 1830 __ b(ne, &object_not_null);
1809 __ mov(r0, Operand(Smi::FromInt(1))); 1831 if (ReturnTrueFalseObject()) {
1832 __ Move(r0, factory->false_value());
1833 } else {
1834 __ mov(r0, Operand(Smi::FromInt(1)));
1835 }
1810 __ Ret(HasArgsInRegisters() ? 0 : 2); 1836 __ Ret(HasArgsInRegisters() ? 0 : 2);
1811 1837
1812 __ bind(&object_not_null); 1838 __ bind(&object_not_null);
1813 // Smi values are not instances of anything. 1839 // Smi values are not instances of anything.
1814 __ JumpIfNotSmi(object, &object_not_null_or_smi); 1840 __ JumpIfNotSmi(object, &object_not_null_or_smi);
1815 __ mov(r0, Operand(Smi::FromInt(1))); 1841 if (ReturnTrueFalseObject()) {
1842 __ Move(r0, factory->false_value());
1843 } else {
1844 __ mov(r0, Operand(Smi::FromInt(1)));
1845 }
1816 __ Ret(HasArgsInRegisters() ? 0 : 2); 1846 __ Ret(HasArgsInRegisters() ? 0 : 2);
1817 1847
1818 __ bind(&object_not_null_or_smi); 1848 __ bind(&object_not_null_or_smi);
1819 // String values are not instances of anything. 1849 // String values are not instances of anything.
1820 __ IsObjectJSStringType(object, scratch, &slow); 1850 __ IsObjectJSStringType(object, scratch, &slow);
1821 __ mov(r0, Operand(Smi::FromInt(1))); 1851 if (ReturnTrueFalseObject()) {
1852 __ Move(r0, factory->false_value());
1853 } else {
1854 __ mov(r0, Operand(Smi::FromInt(1)));
1855 }
1822 __ Ret(HasArgsInRegisters() ? 0 : 2); 1856 __ Ret(HasArgsInRegisters() ? 0 : 2);
1823 1857
1824 // Slow-case. Tail call builtin. 1858 // Slow-case. Tail call builtin.
1825 __ bind(&slow); 1859 __ bind(&slow);
1826 if (!ReturnTrueFalseObject()) { 1860 if (!ReturnTrueFalseObject()) {
1827 if (HasArgsInRegisters()) { 1861 if (HasArgsInRegisters()) {
1828 __ Push(r0, r1); 1862 __ Push(r0, r1);
1829 } 1863 }
1830 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 1864 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
1831 } else { 1865 } else {
(...skipping 3233 matching lines...) Expand 10 before | Expand all | Expand 10 after
5065 MemOperand(fp, 6 * kPointerSize), 5099 MemOperand(fp, 6 * kPointerSize),
5066 NULL); 5100 NULL);
5067 } 5101 }
5068 5102
5069 5103
5070 #undef __ 5104 #undef __
5071 5105
5072 } } // namespace v8::internal 5106 } } // namespace v8::internal
5073 5107
5074 #endif // V8_TARGET_ARCH_ARM 5108 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.cc ('k') | src/arm/deoptimizer-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698