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

Side by Side Diff: src/ic/ppc/ic-ppc.cc

Issue 1199493002: Revert relanded strong property access CL (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 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
« no previous file with comments | « src/ic/ppc/handler-compiler-ppc.cc ('k') | src/ic/x64/handler-compiler-x64.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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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_PPC 7 #if V8_TARGET_ARCH_PPC
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic/ic.h" 10 #include "src/ic/ic.h"
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 __ lbz(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); 160 __ lbz(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
161 __ cmpi(scratch, Operand(JS_OBJECT_TYPE)); 161 __ cmpi(scratch, Operand(JS_OBJECT_TYPE));
162 __ blt(slow); 162 __ blt(slow);
163 } 163 }
164 164
165 165
166 // Loads an indexed element from a fast case array. 166 // Loads an indexed element from a fast case array.
167 static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver, 167 static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
168 Register key, Register elements, 168 Register key, Register elements,
169 Register scratch1, Register scratch2, 169 Register scratch1, Register scratch2,
170 Register result, Label* slow, 170 Register result, Label* slow) {
171 LanguageMode language_mode) {
172 // Register use: 171 // Register use:
173 // 172 //
174 // receiver - holds the receiver on entry. 173 // receiver - holds the receiver on entry.
175 // Unchanged unless 'result' is the same register. 174 // Unchanged unless 'result' is the same register.
176 // 175 //
177 // key - holds the smi key on entry. 176 // key - holds the smi key on entry.
178 // Unchanged unless 'result' is the same register. 177 // Unchanged unless 'result' is the same register.
179 // 178 //
180 // result - holds the result on exit if the load succeeded. 179 // result - holds the result on exit if the load succeeded.
181 // Allowed to be the the same as 'receiver' or 'key'. 180 // Allowed to be the the same as 'receiver' or 'key'.
182 // Unchanged on bailout so 'receiver' and 'key' can be safely 181 // Unchanged on bailout so 'receiver' and 'key' can be safely
183 // used by further computation. 182 // used by further computation.
184 // 183 //
185 // Scratch registers: 184 // Scratch registers:
186 // 185 //
187 // elements - holds the elements of the receiver and its protoypes. 186 // elements - holds the elements of the receiver and its protoypes.
188 // 187 //
189 // scratch1 - used to hold elements length, bit fields, base addresses. 188 // scratch1 - used to hold elements length, bit fields, base addresses.
190 // 189 //
191 // scratch2 - used to hold maps, prototypes, and the loaded value. 190 // scratch2 - used to hold maps, prototypes, and the loaded value.
192 Label check_prototypes, check_next_prototype; 191 Label check_prototypes, check_next_prototype;
193 Label done, in_bounds, absent; 192 Label done, in_bounds, return_undefined;
194 193
195 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 194 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
196 __ AssertFastElements(elements); 195 __ AssertFastElements(elements);
197 196
198 // Check that the key (index) is within bounds. 197 // Check that the key (index) is within bounds.
199 __ LoadP(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset)); 198 __ LoadP(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset));
200 __ cmpl(key, scratch1); 199 __ cmpl(key, scratch1);
201 __ blt(&in_bounds); 200 __ blt(&in_bounds);
202 // Out-of-bounds. Check the prototype chain to see if we can just return 201 // Out-of-bounds. Check the prototype chain to see if we can just return
203 // 'undefined'. 202 // 'undefined'.
204 __ cmpi(key, Operand::Zero()); 203 __ cmpi(key, Operand::Zero());
205 __ blt(slow); // Negative keys can't take the fast OOB path. 204 __ blt(slow); // Negative keys can't take the fast OOB path.
206 __ bind(&check_prototypes); 205 __ bind(&check_prototypes);
207 __ LoadP(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset)); 206 __ LoadP(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset));
208 __ bind(&check_next_prototype); 207 __ bind(&check_next_prototype);
209 __ LoadP(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset)); 208 __ LoadP(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
210 // scratch2: current prototype 209 // scratch2: current prototype
211 __ CompareRoot(scratch2, Heap::kNullValueRootIndex); 210 __ CompareRoot(scratch2, Heap::kNullValueRootIndex);
212 __ beq(&absent); 211 __ beq(&return_undefined);
213 __ LoadP(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset)); 212 __ LoadP(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
214 __ LoadP(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset)); 213 __ LoadP(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
215 // elements: elements of current prototype 214 // elements: elements of current prototype
216 // scratch2: map of current prototype 215 // scratch2: map of current prototype
217 __ CompareInstanceType(scratch2, scratch1, JS_OBJECT_TYPE); 216 __ CompareInstanceType(scratch2, scratch1, JS_OBJECT_TYPE);
218 __ blt(slow); 217 __ blt(slow);
219 __ lbz(scratch1, FieldMemOperand(scratch2, Map::kBitFieldOffset)); 218 __ lbz(scratch1, FieldMemOperand(scratch2, Map::kBitFieldOffset));
220 __ andi(r0, scratch1, Operand((1 << Map::kIsAccessCheckNeeded) | 219 __ andi(r0, scratch1, Operand((1 << Map::kIsAccessCheckNeeded) |
221 (1 << Map::kHasIndexedInterceptor))); 220 (1 << Map::kHasIndexedInterceptor)));
222 __ bne(slow, cr0); 221 __ bne(slow, cr0);
223 __ CompareRoot(elements, Heap::kEmptyFixedArrayRootIndex); 222 __ CompareRoot(elements, Heap::kEmptyFixedArrayRootIndex);
224 __ bne(slow); 223 __ bne(slow);
225 __ jmp(&check_next_prototype); 224 __ jmp(&check_next_prototype);
226 225
227 __ bind(&absent); 226 __ bind(&return_undefined);
228 if (is_strong(language_mode)) { 227 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
229 // Strong mode accesses must throw in this case, so call the runtime. 228 __ jmp(&done);
230 __ jmp(slow);
231 } else {
232 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
233 __ jmp(&done);
234 }
235 229
236 __ bind(&in_bounds); 230 __ bind(&in_bounds);
237 // Fast case: Do the load. 231 // Fast case: Do the load.
238 __ addi(scratch1, elements, 232 __ addi(scratch1, elements,
239 Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 233 Operand(FixedArray::kHeaderSize - kHeapObjectTag));
240 // The key is a smi. 234 // The key is a smi.
241 __ SmiToPtrArrayOffset(scratch2, key); 235 __ SmiToPtrArrayOffset(scratch2, key);
242 __ LoadPX(scratch2, MemOperand(scratch2, scratch1)); 236 __ LoadPX(scratch2, MemOperand(scratch2, scratch1));
243 __ CompareRoot(scratch2, Heap::kTheHoleValueRootIndex); 237 __ CompareRoot(scratch2, Heap::kTheHoleValueRootIndex);
244 // In case the loaded value is the_hole we have to check the prototype chain. 238 // In case the loaded value is the_hole we have to check the prototype chain.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 Label slow; 281 Label slow;
288 282
289 __ LoadP(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(), 283 __ LoadP(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(),
290 JSObject::kPropertiesOffset)); 284 JSObject::kPropertiesOffset));
291 GenerateDictionaryLoad(masm, &slow, dictionary, 285 GenerateDictionaryLoad(masm, &slow, dictionary,
292 LoadDescriptor::NameRegister(), r3, r6, r7); 286 LoadDescriptor::NameRegister(), r3, r6, r7);
293 __ Ret(); 287 __ Ret();
294 288
295 // Dictionary load failed, go slow (but don't miss). 289 // Dictionary load failed, go slow (but don't miss).
296 __ bind(&slow); 290 __ bind(&slow);
297 GenerateSlow(masm); 291 GenerateRuntimeGetProperty(masm);
298 } 292 }
299 293
300 294
301 // A register that isn't one of the parameters to the load ic. 295 // A register that isn't one of the parameters to the load ic.
302 static const Register LoadIC_TempRegister() { return r6; } 296 static const Register LoadIC_TempRegister() { return r6; }
303 297
304 298
305 static void LoadIC_PushArgs(MacroAssembler* masm) { 299 static void LoadIC_PushArgs(MacroAssembler* masm) {
306 Register receiver = LoadDescriptor::ReceiverRegister(); 300 Register receiver = LoadDescriptor::ReceiverRegister();
307 Register name = LoadDescriptor::NameRegister(); 301 Register name = LoadDescriptor::NameRegister();
(...skipping 14 matching lines...) Expand all
322 316
323 LoadIC_PushArgs(masm); 317 LoadIC_PushArgs(masm);
324 318
325 // Perform tail call to the entry. 319 // Perform tail call to the entry.
326 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate); 320 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
327 int arg_count = 4; 321 int arg_count = 4;
328 __ TailCallExternalReference(ref, arg_count, 1); 322 __ TailCallExternalReference(ref, arg_count, 1);
329 } 323 }
330 324
331 325
332 void LoadIC::GenerateSlow(MacroAssembler* masm) { 326 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
333 // The return address is in lr. 327 // The return address is in lr.
334 328
335 __ mr(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); 329 __ mr(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
336 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); 330 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
337 331
338 ExternalReference ref = 332 __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
339 ExternalReference(IC_Utility(kLoadIC_Slow), masm->isolate());
340 int arg_count = 2;
341 __ TailCallExternalReference(ref, arg_count, 1);
342 } 333 }
343 334
344 335
345 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { 336 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
346 // The return address is in lr. 337 // The return address is in lr.
347 Isolate* isolate = masm->isolate(); 338 Isolate* isolate = masm->isolate();
348 339
349 DCHECK(!AreAliased(r7, r8, LoadWithVectorDescriptor::SlotRegister(), 340 DCHECK(!AreAliased(r7, r8, LoadWithVectorDescriptor::SlotRegister(),
350 LoadWithVectorDescriptor::VectorRegister())); 341 LoadWithVectorDescriptor::VectorRegister()));
351 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r7, r8); 342 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r7, r8);
352 343
353 LoadIC_PushArgs(masm); 344 LoadIC_PushArgs(masm);
354 345
355 // Perform tail call to the entry. 346 // Perform tail call to the entry.
356 ExternalReference ref = 347 ExternalReference ref =
357 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); 348 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
358 int arg_count = 4; 349 int arg_count = 4;
359 __ TailCallExternalReference(ref, arg_count, 1); 350 __ TailCallExternalReference(ref, arg_count, 1);
360 } 351 }
361 352
362 353
363 void KeyedLoadIC::GenerateSlow(MacroAssembler* masm) { 354 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
364 // The return address is in lr. 355 // The return address is in lr.
365 356
366 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); 357 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
367 358
368 ExternalReference ref = 359 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
369 ExternalReference(IC_Utility(kKeyedLoadIC_Slow), masm->isolate());
370 int arg_count = 2;
371 __ TailCallExternalReference(ref, arg_count, 1);
372 } 360 }
373 361
374 362
375 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm, 363 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
376 LanguageMode language_mode) {
377 // The return address is in lr. 364 // The return address is in lr.
378 Label slow, check_name, index_smi, index_name, property_array_property; 365 Label slow, check_name, index_smi, index_name, property_array_property;
379 Label probe_dictionary, check_number_dictionary; 366 Label probe_dictionary, check_number_dictionary;
380 367
381 Register key = LoadDescriptor::NameRegister(); 368 Register key = LoadDescriptor::NameRegister();
382 Register receiver = LoadDescriptor::ReceiverRegister(); 369 Register receiver = LoadDescriptor::ReceiverRegister();
383 DCHECK(key.is(r5)); 370 DCHECK(key.is(r5));
384 DCHECK(receiver.is(r4)); 371 DCHECK(receiver.is(r4));
385 372
386 Isolate* isolate = masm->isolate(); 373 Isolate* isolate = masm->isolate();
387 374
388 // Check that the key is a smi. 375 // Check that the key is a smi.
389 __ JumpIfNotSmi(key, &check_name); 376 __ JumpIfNotSmi(key, &check_name);
390 __ bind(&index_smi); 377 __ bind(&index_smi);
391 // Now the key is known to be a smi. This place is also jumped to from below 378 // Now the key is known to be a smi. This place is also jumped to from below
392 // where a numeric string is converted to a smi. 379 // where a numeric string is converted to a smi.
393 380
394 GenerateKeyedLoadReceiverCheck(masm, receiver, r3, r6, 381 GenerateKeyedLoadReceiverCheck(masm, receiver, r3, r6,
395 Map::kHasIndexedInterceptor, &slow); 382 Map::kHasIndexedInterceptor, &slow);
396 383
397 // Check the receiver's map to see if it has fast elements. 384 // Check the receiver's map to see if it has fast elements.
398 __ CheckFastElements(r3, r6, &check_number_dictionary); 385 __ CheckFastElements(r3, r6, &check_number_dictionary);
399 386
400 GenerateFastArrayLoad(masm, receiver, key, r3, r6, r7, r3, &slow, 387 GenerateFastArrayLoad(masm, receiver, key, r3, r6, r7, r3, &slow);
401 language_mode);
402 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r7, r6); 388 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r7, r6);
403 __ Ret(); 389 __ Ret();
404 390
405 __ bind(&check_number_dictionary); 391 __ bind(&check_number_dictionary);
406 __ LoadP(r7, FieldMemOperand(receiver, JSObject::kElementsOffset)); 392 __ LoadP(r7, FieldMemOperand(receiver, JSObject::kElementsOffset));
407 __ LoadP(r6, FieldMemOperand(r7, JSObject::kMapOffset)); 393 __ LoadP(r6, FieldMemOperand(r7, JSObject::kMapOffset));
408 394
409 // Check whether the elements is a number dictionary. 395 // Check whether the elements is a number dictionary.
410 // r6: elements map 396 // r6: elements map
411 // r7: elements 397 // r7: elements
412 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); 398 __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
413 __ cmp(r6, ip); 399 __ cmp(r6, ip);
414 __ bne(&slow); 400 __ bne(&slow);
415 __ SmiUntag(r3, key); 401 __ SmiUntag(r3, key);
416 __ LoadFromNumberDictionary(&slow, r7, key, r3, r3, r6, r8); 402 __ LoadFromNumberDictionary(&slow, r7, key, r3, r3, r6, r8);
417 __ Ret(); 403 __ Ret();
418 404
419 // Slow case, key and receiver still in r3 and r4. 405 // Slow case, key and receiver still in r3 and r4.
420 __ bind(&slow); 406 __ bind(&slow);
421 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, r7, 407 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, r7,
422 r6); 408 r6);
423 GenerateSlow(masm); 409 GenerateRuntimeGetProperty(masm);
424 410
425 __ bind(&check_name); 411 __ bind(&check_name);
426 GenerateKeyNameCheck(masm, key, r3, r6, &index_name, &slow); 412 GenerateKeyNameCheck(masm, key, r3, r6, &index_name, &slow);
427 413
428 GenerateKeyedLoadReceiverCheck(masm, receiver, r3, r6, 414 GenerateKeyedLoadReceiverCheck(masm, receiver, r3, r6,
429 Map::kHasNamedInterceptor, &slow); 415 Map::kHasNamedInterceptor, &slow);
430 416
431 // If the receiver is a fast-case object, check the stub cache. Otherwise 417 // If the receiver is a fast-case object, check the stub cache. Otherwise
432 // probe the dictionary. 418 // probe the dictionary.
433 __ LoadP(r6, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 419 __ LoadP(r6, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 patcher.EmitCondition(ne); 888 patcher.EmitCondition(ne);
903 } else { 889 } else {
904 DCHECK(Assembler::GetCondition(branch_instr) == ne); 890 DCHECK(Assembler::GetCondition(branch_instr) == ne);
905 patcher.EmitCondition(eq); 891 patcher.EmitCondition(eq);
906 } 892 }
907 } 893 }
908 } // namespace internal 894 } // namespace internal
909 } // namespace v8 895 } // namespace v8
910 896
911 #endif // V8_TARGET_ARCH_PPC 897 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « src/ic/ppc/handler-compiler-ppc.cc ('k') | src/ic/x64/handler-compiler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698