OLD | NEW |
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 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 326 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
327 // The return address is in lr. | 327 // The return address is in lr. |
328 | 328 |
329 __ mr(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); | 329 __ mr(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); |
330 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); | 330 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); |
331 | 331 |
332 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); | 332 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); |
333 } | 333 } |
334 | 334 |
335 | 335 |
336 static MemOperand GenerateMappedArgumentsLookup( | |
337 MacroAssembler* masm, Register object, Register key, Register scratch1, | |
338 Register scratch2, Register scratch3, Label* unmapped_case, | |
339 Label* slow_case) { | |
340 Heap* heap = masm->isolate()->heap(); | |
341 | |
342 // Check that the receiver is a JSObject. Because of the map check | |
343 // later, we do not need to check for interceptors or whether it | |
344 // requires access checks. | |
345 __ JumpIfSmi(object, slow_case); | |
346 // Check that the object is some kind of JSObject. | |
347 __ CompareObjectType(object, scratch1, scratch2, FIRST_JS_RECEIVER_TYPE); | |
348 __ blt(slow_case); | |
349 | |
350 // Check that the key is a positive smi. | |
351 __ mov(scratch1, Operand(0x80000001)); | |
352 __ and_(r0, key, scratch1, SetRC); | |
353 __ bne(slow_case, cr0); | |
354 | |
355 // Load the elements into scratch1 and check its map. | |
356 Handle<Map> arguments_map(heap->sloppy_arguments_elements_map()); | |
357 __ LoadP(scratch1, FieldMemOperand(object, JSObject::kElementsOffset)); | |
358 __ CheckMap(scratch1, scratch2, arguments_map, slow_case, DONT_DO_SMI_CHECK); | |
359 | |
360 // Check if element is in the range of mapped arguments. If not, jump | |
361 // to the unmapped lookup with the parameter map in scratch1. | |
362 __ LoadP(scratch2, FieldMemOperand(scratch1, FixedArray::kLengthOffset)); | |
363 __ SubSmiLiteral(scratch2, scratch2, Smi::FromInt(2), r0); | |
364 __ cmpl(key, scratch2); | |
365 __ bge(unmapped_case); | |
366 | |
367 // Load element index and check whether it is the hole. | |
368 const int kOffset = | |
369 FixedArray::kHeaderSize + 2 * kPointerSize - kHeapObjectTag; | |
370 | |
371 __ SmiToPtrArrayOffset(scratch3, key); | |
372 __ addi(scratch3, scratch3, Operand(kOffset)); | |
373 | |
374 __ LoadPX(scratch2, MemOperand(scratch1, scratch3)); | |
375 __ LoadRoot(scratch3, Heap::kTheHoleValueRootIndex); | |
376 __ cmp(scratch2, scratch3); | |
377 __ beq(unmapped_case); | |
378 | |
379 // Load value from context and return it. We can reuse scratch1 because | |
380 // we do not jump to the unmapped lookup (which requires the parameter | |
381 // map in scratch1). | |
382 __ LoadP(scratch1, FieldMemOperand(scratch1, FixedArray::kHeaderSize)); | |
383 __ SmiToPtrArrayOffset(scratch3, scratch2); | |
384 __ addi(scratch3, scratch3, Operand(Context::kHeaderSize - kHeapObjectTag)); | |
385 return MemOperand(scratch1, scratch3); | |
386 } | |
387 | |
388 | |
389 static MemOperand GenerateUnmappedArgumentsLookup(MacroAssembler* masm, | |
390 Register key, | |
391 Register parameter_map, | |
392 Register scratch, | |
393 Label* slow_case) { | |
394 // Element is in arguments backing store, which is referenced by the | |
395 // second element of the parameter_map. The parameter_map register | |
396 // must be loaded with the parameter map of the arguments object and is | |
397 // overwritten. | |
398 const int kBackingStoreOffset = FixedArray::kHeaderSize + kPointerSize; | |
399 Register backing_store = parameter_map; | |
400 __ LoadP(backing_store, FieldMemOperand(parameter_map, kBackingStoreOffset)); | |
401 Handle<Map> fixed_array_map(masm->isolate()->heap()->fixed_array_map()); | |
402 __ CheckMap(backing_store, scratch, fixed_array_map, slow_case, | |
403 DONT_DO_SMI_CHECK); | |
404 __ LoadP(scratch, FieldMemOperand(backing_store, FixedArray::kLengthOffset)); | |
405 __ cmpl(key, scratch); | |
406 __ bge(slow_case); | |
407 __ SmiToPtrArrayOffset(scratch, key); | |
408 __ addi(scratch, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | |
409 return MemOperand(backing_store, scratch); | |
410 } | |
411 | |
412 | |
413 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { | |
414 Register receiver = StoreDescriptor::ReceiverRegister(); | |
415 Register key = StoreDescriptor::NameRegister(); | |
416 Register value = StoreDescriptor::ValueRegister(); | |
417 DCHECK(receiver.is(r4)); | |
418 DCHECK(key.is(r5)); | |
419 DCHECK(value.is(r3)); | |
420 | |
421 Label slow, notin; | |
422 MemOperand mapped_location = GenerateMappedArgumentsLookup( | |
423 masm, receiver, key, r6, r7, r8, ¬in, &slow); | |
424 Register mapped_base = mapped_location.ra(); | |
425 Register mapped_offset = mapped_location.rb(); | |
426 __ StorePX(value, mapped_location); | |
427 __ add(r9, mapped_base, mapped_offset); | |
428 __ mr(r11, value); | |
429 __ RecordWrite(mapped_base, r9, r11, kLRHasNotBeenSaved, kDontSaveFPRegs); | |
430 __ Ret(); | |
431 __ bind(¬in); | |
432 // The unmapped lookup expects that the parameter map is in r6. | |
433 MemOperand unmapped_location = | |
434 GenerateUnmappedArgumentsLookup(masm, key, r6, r7, &slow); | |
435 Register unmapped_base = unmapped_location.ra(); | |
436 Register unmapped_offset = unmapped_location.rb(); | |
437 __ StorePX(value, unmapped_location); | |
438 __ add(r9, unmapped_base, unmapped_offset); | |
439 __ mr(r11, value); | |
440 __ RecordWrite(unmapped_base, r9, r11, kLRHasNotBeenSaved, kDontSaveFPRegs); | |
441 __ Ret(); | |
442 __ bind(&slow); | |
443 GenerateMiss(masm); | |
444 } | |
445 | |
446 | |
447 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 336 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
448 // The return address is in lr. | 337 // The return address is in lr. |
449 Isolate* isolate = masm->isolate(); | 338 Isolate* isolate = masm->isolate(); |
450 | 339 |
451 DCHECK(!AreAliased(r7, r8, LoadWithVectorDescriptor::SlotRegister(), | 340 DCHECK(!AreAliased(r7, r8, LoadWithVectorDescriptor::SlotRegister(), |
452 LoadWithVectorDescriptor::VectorRegister())); | 341 LoadWithVectorDescriptor::VectorRegister())); |
453 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r7, r8); | 342 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r7, r8); |
454 | 343 |
455 LoadIC_PushArgs(masm); | 344 LoadIC_PushArgs(masm); |
456 | 345 |
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
999 patcher.EmitCondition(ne); | 888 patcher.EmitCondition(ne); |
1000 } else { | 889 } else { |
1001 DCHECK(Assembler::GetCondition(branch_instr) == ne); | 890 DCHECK(Assembler::GetCondition(branch_instr) == ne); |
1002 patcher.EmitCondition(eq); | 891 patcher.EmitCondition(eq); |
1003 } | 892 } |
1004 } | 893 } |
1005 } | 894 } |
1006 } // namespace v8::internal | 895 } // namespace v8::internal |
1007 | 896 |
1008 #endif // V8_TARGET_ARCH_PPC | 897 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |