OLD | NEW |
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 | 5 |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #if V8_TARGET_ARCH_MIPS64 | 9 #if V8_TARGET_ARCH_MIPS64 |
10 | 10 |
(...skipping 18 matching lines...) Expand all Loading... |
29 Register type, | 29 Register type, |
30 Label* global_object) { | 30 Label* global_object) { |
31 // Register usage: | 31 // Register usage: |
32 // type: holds the receiver instance type on entry. | 32 // type: holds the receiver instance type on entry. |
33 __ Branch(global_object, eq, type, Operand(JS_GLOBAL_OBJECT_TYPE)); | 33 __ Branch(global_object, eq, type, Operand(JS_GLOBAL_OBJECT_TYPE)); |
34 __ Branch(global_object, eq, type, Operand(JS_BUILTINS_OBJECT_TYPE)); | 34 __ Branch(global_object, eq, type, Operand(JS_BUILTINS_OBJECT_TYPE)); |
35 __ Branch(global_object, eq, type, Operand(JS_GLOBAL_PROXY_TYPE)); | 35 __ Branch(global_object, eq, type, Operand(JS_GLOBAL_PROXY_TYPE)); |
36 } | 36 } |
37 | 37 |
38 | 38 |
39 // Generated code falls through if the receiver is a regular non-global | |
40 // JS object with slow properties and no interceptors. | |
41 static void GenerateNameDictionaryReceiverCheck(MacroAssembler* masm, | |
42 Register receiver, | |
43 Register elements, | |
44 Register scratch0, | |
45 Register scratch1, | |
46 Label* miss) { | |
47 // Register usage: | |
48 // receiver: holds the receiver on entry and is unchanged. | |
49 // elements: holds the property dictionary on fall through. | |
50 // Scratch registers: | |
51 // scratch0: used to holds the receiver map. | |
52 // scratch1: used to holds the receiver instance type, receiver bit mask | |
53 // and elements map. | |
54 | |
55 // Check that the receiver isn't a smi. | |
56 __ JumpIfSmi(receiver, miss); | |
57 | |
58 // Check that the receiver is a valid JS object. | |
59 __ GetObjectType(receiver, scratch0, scratch1); | |
60 __ Branch(miss, lt, scratch1, Operand(FIRST_SPEC_OBJECT_TYPE)); | |
61 | |
62 // If this assert fails, we have to check upper bound too. | |
63 STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE); | |
64 | |
65 GenerateGlobalInstanceTypeCheck(masm, scratch1, miss); | |
66 | |
67 // Check that the global object does not require access checks. | |
68 __ lbu(scratch1, FieldMemOperand(scratch0, Map::kBitFieldOffset)); | |
69 __ And(scratch1, scratch1, Operand((1 << Map::kIsAccessCheckNeeded) | | |
70 (1 << Map::kHasNamedInterceptor))); | |
71 __ Branch(miss, ne, scratch1, Operand(zero_reg)); | |
72 | |
73 __ ld(elements, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | |
74 __ ld(scratch1, FieldMemOperand(elements, HeapObject::kMapOffset)); | |
75 __ LoadRoot(scratch0, Heap::kHashTableMapRootIndex); | |
76 __ Branch(miss, ne, scratch1, Operand(scratch0)); | |
77 } | |
78 | |
79 | |
80 // Helper function used from LoadIC GenerateNormal. | 39 // Helper function used from LoadIC GenerateNormal. |
81 // | 40 // |
82 // elements: Property dictionary. It is not clobbered if a jump to the miss | 41 // elements: Property dictionary. It is not clobbered if a jump to the miss |
83 // label is done. | 42 // label is done. |
84 // name: Property name. It is not clobbered if a jump to the miss label is | 43 // name: Property name. It is not clobbered if a jump to the miss label is |
85 // done | 44 // done |
86 // result: Register for the result. It is only updated if a jump to the miss | 45 // result: Register for the result. It is only updated if a jump to the miss |
87 // label is not done. Can be the same as elements or name clobbering | 46 // label is not done. Can be the same as elements or name clobbering |
88 // one of these in the case of not jumping to the miss label. | 47 // one of these in the case of not jumping to the miss label. |
89 // The two scratch registers need to be different from elements, name and | 48 // The two scratch registers need to be different from elements, name and |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); | 286 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); |
328 masm->isolate()->stub_cache()->GenerateProbe( | 287 masm->isolate()->stub_cache()->GenerateProbe( |
329 masm, flags, receiver, name, a3, a4, a5, a6); | 288 masm, flags, receiver, name, a3, a4, a5, a6); |
330 | 289 |
331 // Cache miss: Jump to runtime. | 290 // Cache miss: Jump to runtime. |
332 GenerateMiss(masm); | 291 GenerateMiss(masm); |
333 } | 292 } |
334 | 293 |
335 | 294 |
336 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 295 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
337 // ----------- S t a t e ------------- | 296 Register dictionary = a0; |
338 // -- a2 : name | 297 ASSERT(!dictionary.is(ReceiverRegister())); |
339 // -- lr : return address | 298 ASSERT(!dictionary.is(NameRegister())); |
340 // -- a1 : receiver | 299 Label slow; |
341 // ----------------------------------- | |
342 ASSERT(a1.is(ReceiverRegister())); | |
343 ASSERT(a2.is(NameRegister())); | |
344 | 300 |
345 Label miss, slow; | 301 __ ld(dictionary, |
346 | 302 FieldMemOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); |
347 GenerateNameDictionaryReceiverCheck(masm, a1, a0, a3, a4, &miss); | 303 GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), v0, a3, a4); |
348 | |
349 // a0: elements | |
350 GenerateDictionaryLoad(masm, &slow, a0, a2, v0, a3, a4); | |
351 __ Ret(); | 304 __ Ret(); |
352 | 305 |
353 // Dictionary load failed, go slow (but don't miss). | 306 // Dictionary load failed, go slow (but don't miss). |
354 __ bind(&slow); | 307 __ bind(&slow); |
355 GenerateRuntimeGetProperty(masm); | 308 GenerateRuntimeGetProperty(masm); |
356 | |
357 // Cache miss: Jump to runtime. | |
358 __ bind(&miss); | |
359 GenerateMiss(masm); | |
360 } | 309 } |
361 | 310 |
362 | 311 |
363 // A register that isn't one of the parameters to the load ic. | 312 // A register that isn't one of the parameters to the load ic. |
364 static const Register LoadIC_TempRegister() { return a3; } | 313 static const Register LoadIC_TempRegister() { return a3; } |
365 | 314 |
366 | 315 |
367 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 316 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
368 // The return address is on the stack. | 317 // The return address is on the stack. |
369 Isolate* isolate = masm->isolate(); | 318 Isolate* isolate = masm->isolate(); |
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1181 masm->isolate()); | 1130 masm->isolate()); |
1182 __ TailCallExternalReference(ref, 3, 1); | 1131 __ TailCallExternalReference(ref, 3, 1); |
1183 } | 1132 } |
1184 | 1133 |
1185 | 1134 |
1186 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 1135 void StoreIC::GenerateNormal(MacroAssembler* masm) { |
1187 Label miss; | 1136 Label miss; |
1188 Register receiver = ReceiverRegister(); | 1137 Register receiver = ReceiverRegister(); |
1189 Register name = NameRegister(); | 1138 Register name = NameRegister(); |
1190 Register value = ValueRegister(); | 1139 Register value = ValueRegister(); |
1191 ASSERT(receiver.is(a1)); | 1140 Register dictionary = a3; |
1192 ASSERT(name.is(a2)); | 1141 ASSERT(!AreAliased(value, receiver, name, dictionary, a4, a5)); |
1193 ASSERT(value.is(a0)); | |
1194 | 1142 |
1195 GenerateNameDictionaryReceiverCheck(masm, receiver, a3, a4, a5, &miss); | 1143 __ ld(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
1196 | 1144 |
1197 GenerateDictionaryStore(masm, &miss, a3, name, value, a4, a5); | 1145 GenerateDictionaryStore(masm, &miss, a3, name, value, a4, a5); |
1198 Counters* counters = masm->isolate()->counters(); | 1146 Counters* counters = masm->isolate()->counters(); |
1199 __ IncrementCounter(counters->store_normal_hit(), 1, a4, a5); | 1147 __ IncrementCounter(counters->store_normal_hit(), 1, a4, a5); |
1200 __ Ret(); | 1148 __ Ret(); |
1201 | 1149 |
1202 __ bind(&miss); | 1150 __ bind(&miss); |
1203 __ IncrementCounter(counters->store_normal_miss(), 1, a4, a5); | 1151 __ IncrementCounter(counters->store_normal_miss(), 1, a4, a5); |
1204 GenerateMiss(masm); | 1152 GenerateMiss(masm); |
1205 } | 1153 } |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1310 } else { | 1258 } else { |
1311 ASSERT(Assembler::IsBne(branch_instr)); | 1259 ASSERT(Assembler::IsBne(branch_instr)); |
1312 patcher.ChangeBranchCondition(eq); | 1260 patcher.ChangeBranchCondition(eq); |
1313 } | 1261 } |
1314 } | 1262 } |
1315 | 1263 |
1316 | 1264 |
1317 } } // namespace v8::internal | 1265 } } // namespace v8::internal |
1318 | 1266 |
1319 #endif // V8_TARGET_ARCH_MIPS64 | 1267 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |