| 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 #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/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 1082 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1093 // the context will be set to (cp == 0) for non-JS frames. | 1093 // the context will be set to (cp == 0) for non-JS frames. |
| 1094 __ cmp(cp, Operand(0)); | 1094 __ cmp(cp, Operand(0)); |
| 1095 __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne); | 1095 __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne); |
| 1096 | 1096 |
| 1097 // Compute the handler entry address and jump to it. | 1097 // Compute the handler entry address and jump to it. |
| 1098 ConstantPoolUnavailableScope constant_pool_unavailable(masm); | 1098 ConstantPoolUnavailableScope constant_pool_unavailable(masm); |
| 1099 __ mov(r1, Operand(pending_handler_code_address)); | 1099 __ mov(r1, Operand(pending_handler_code_address)); |
| 1100 __ ldr(r1, MemOperand(r1)); | 1100 __ ldr(r1, MemOperand(r1)); |
| 1101 __ mov(r2, Operand(pending_handler_offset_address)); | 1101 __ mov(r2, Operand(pending_handler_offset_address)); |
| 1102 __ ldr(r2, MemOperand(r2)); | 1102 __ ldr(r2, MemOperand(r2)); |
| 1103 __ add(r1, r1, Operand(Code::kHeaderSize - kHeapObjectTag)); // Code start |
| 1103 if (FLAG_enable_embedded_constant_pool) { | 1104 if (FLAG_enable_embedded_constant_pool) { |
| 1104 __ LoadConstantPoolPointerRegisterFromCodeTargetAddress(r1); | 1105 __ LoadConstantPoolPointerRegisterFromCodeTargetAddress(r1); |
| 1105 } | 1106 } |
| 1106 __ add(r1, r1, Operand(Code::kHeaderSize - kHeapObjectTag)); | |
| 1107 __ add(pc, r1, r2); | 1107 __ add(pc, r1, r2); |
| 1108 } | 1108 } |
| 1109 | 1109 |
| 1110 | 1110 |
| 1111 void JSEntryStub::Generate(MacroAssembler* masm) { | 1111 void JSEntryStub::Generate(MacroAssembler* masm) { |
| 1112 // r0: code entry | 1112 // r0: code entry |
| 1113 // r1: function | 1113 // r1: function |
| 1114 // r2: receiver | 1114 // r2: receiver |
| 1115 // r3: argc | 1115 // r3: argc |
| 1116 // [sp+0]: argv | 1116 // [sp+0]: argv |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1340 | 1340 |
| 1341 // The map_load_offset was stored in r5 | 1341 // The map_load_offset was stored in r5 |
| 1342 // (See LCodeGen::DoDeferredLInstanceOfKnownGlobal). | 1342 // (See LCodeGen::DoDeferredLInstanceOfKnownGlobal). |
| 1343 const Register map_load_offset = r5; | 1343 const Register map_load_offset = r5; |
| 1344 __ sub(r9, lr, map_load_offset); | 1344 __ sub(r9, lr, map_load_offset); |
| 1345 // Get the map location in r5 and patch it. | 1345 // Get the map location in r5 and patch it. |
| 1346 __ GetRelocatedValueLocation(r9, map_load_offset, scratch); | 1346 __ GetRelocatedValueLocation(r9, map_load_offset, scratch); |
| 1347 __ ldr(map_load_offset, MemOperand(map_load_offset)); | 1347 __ ldr(map_load_offset, MemOperand(map_load_offset)); |
| 1348 __ str(map, FieldMemOperand(map_load_offset, Cell::kValueOffset)); | 1348 __ str(map, FieldMemOperand(map_load_offset, Cell::kValueOffset)); |
| 1349 | 1349 |
| 1350 __ mov(r8, map); | 1350 __ mov(scratch, map); |
| 1351 // |map_load_offset| points at the beginning of the cell. Calculate the | 1351 // |map_load_offset| points at the beginning of the cell. Calculate the |
| 1352 // field containing the map. | 1352 // field containing the map. |
| 1353 __ add(function, map_load_offset, Operand(Cell::kValueOffset - 1)); | 1353 __ add(function, map_load_offset, Operand(Cell::kValueOffset - 1)); |
| 1354 __ RecordWriteField(map_load_offset, Cell::kValueOffset, r8, function, | 1354 __ RecordWriteField(map_load_offset, Cell::kValueOffset, scratch, function, |
| 1355 kLRHasNotBeenSaved, kDontSaveFPRegs, | 1355 kLRHasNotBeenSaved, kDontSaveFPRegs, |
| 1356 OMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | 1356 OMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
| 1357 } | 1357 } |
| 1358 | 1358 |
| 1359 // Register mapping: r3 is object map and r4 is function prototype. | 1359 // Register mapping: r3 is object map and r4 is function prototype. |
| 1360 // Get prototype of object into r2. | 1360 // Get prototype of object into r2. |
| 1361 __ ldr(scratch, FieldMemOperand(map, Map::kPrototypeOffset)); | 1361 __ ldr(scratch, FieldMemOperand(map, Map::kPrototypeOffset)); |
| 1362 | 1362 |
| 1363 // We don't need map any more. Use it as a scratch register. | 1363 // We don't need map any more. Use it as a scratch register. |
| 1364 Register scratch2 = map; | 1364 Register scratch2 = map; |
| (...skipping 1061 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2426 // Load the cache state into r4. | 2426 // Load the cache state into r4. |
| 2427 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); | 2427 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); |
| 2428 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize)); | 2428 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize)); |
| 2429 | 2429 |
| 2430 // A monomorphic cache hit or an already megamorphic state: invoke the | 2430 // A monomorphic cache hit or an already megamorphic state: invoke the |
| 2431 // function without changing the state. | 2431 // function without changing the state. |
| 2432 // We don't know if r4 is a WeakCell or a Symbol, but it's harmless to read at | 2432 // We don't know if r4 is a WeakCell or a Symbol, but it's harmless to read at |
| 2433 // this position in a symbol (see static asserts in type-feedback-vector.h). | 2433 // this position in a symbol (see static asserts in type-feedback-vector.h). |
| 2434 Label check_allocation_site; | 2434 Label check_allocation_site; |
| 2435 Register feedback_map = r5; | 2435 Register feedback_map = r5; |
| 2436 Register weak_value = r8; | 2436 Register weak_value = r6; |
| 2437 __ ldr(weak_value, FieldMemOperand(r4, WeakCell::kValueOffset)); | 2437 __ ldr(weak_value, FieldMemOperand(r4, WeakCell::kValueOffset)); |
| 2438 __ cmp(r1, weak_value); | 2438 __ cmp(r1, weak_value); |
| 2439 __ b(eq, &done); | 2439 __ b(eq, &done); |
| 2440 __ CompareRoot(r4, Heap::kmegamorphic_symbolRootIndex); | 2440 __ CompareRoot(r4, Heap::kmegamorphic_symbolRootIndex); |
| 2441 __ b(eq, &done); | 2441 __ b(eq, &done); |
| 2442 __ ldr(feedback_map, FieldMemOperand(r4, HeapObject::kMapOffset)); | 2442 __ ldr(feedback_map, FieldMemOperand(r4, HeapObject::kMapOffset)); |
| 2443 __ CompareRoot(feedback_map, Heap::kWeakCellMapRootIndex); | 2443 __ CompareRoot(feedback_map, Heap::kWeakCellMapRootIndex); |
| 2444 __ b(ne, FLAG_pretenuring_call_new ? &miss : &check_allocation_site); | 2444 __ b(ne, FLAG_pretenuring_call_new ? &miss : &check_allocation_site); |
| 2445 | 2445 |
| 2446 // If the weak cell is cleared, we have a new chance to become monomorphic. | 2446 // If the weak cell is cleared, we have a new chance to become monomorphic. |
| (...skipping 2040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4487 } | 4487 } |
| 4488 | 4488 |
| 4489 | 4489 |
| 4490 void LoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 4490 void LoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { |
| 4491 Register receiver = LoadWithVectorDescriptor::ReceiverRegister(); // r1 | 4491 Register receiver = LoadWithVectorDescriptor::ReceiverRegister(); // r1 |
| 4492 Register name = LoadWithVectorDescriptor::NameRegister(); // r2 | 4492 Register name = LoadWithVectorDescriptor::NameRegister(); // r2 |
| 4493 Register vector = LoadWithVectorDescriptor::VectorRegister(); // r3 | 4493 Register vector = LoadWithVectorDescriptor::VectorRegister(); // r3 |
| 4494 Register slot = LoadWithVectorDescriptor::SlotRegister(); // r0 | 4494 Register slot = LoadWithVectorDescriptor::SlotRegister(); // r0 |
| 4495 Register feedback = r4; | 4495 Register feedback = r4; |
| 4496 Register receiver_map = r5; | 4496 Register receiver_map = r5; |
| 4497 Register scratch1 = r8; | 4497 Register scratch1 = r6; |
| 4498 | 4498 |
| 4499 __ add(feedback, vector, Operand::PointerOffsetFromSmiKey(slot)); | 4499 __ add(feedback, vector, Operand::PointerOffsetFromSmiKey(slot)); |
| 4500 __ ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize)); | 4500 __ ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize)); |
| 4501 | 4501 |
| 4502 // Try to quickly handle the monomorphic case without knowing for sure | 4502 // Try to quickly handle the monomorphic case without knowing for sure |
| 4503 // if we have a weak cell in feedback. We do know it's safe to look | 4503 // if we have a weak cell in feedback. We do know it's safe to look |
| 4504 // at WeakCell::kValueOffset. | 4504 // at WeakCell::kValueOffset. |
| 4505 Label try_array, load_smi_map, compare_map; | 4505 Label try_array, load_smi_map, compare_map; |
| 4506 Label not_array, miss; | 4506 Label not_array, miss; |
| 4507 HandleMonomorphicCase(masm, receiver, receiver_map, feedback, vector, slot, | 4507 HandleMonomorphicCase(masm, receiver, receiver_map, feedback, vector, slot, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4544 } | 4544 } |
| 4545 | 4545 |
| 4546 | 4546 |
| 4547 void KeyedLoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 4547 void KeyedLoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { |
| 4548 Register receiver = LoadWithVectorDescriptor::ReceiverRegister(); // r1 | 4548 Register receiver = LoadWithVectorDescriptor::ReceiverRegister(); // r1 |
| 4549 Register key = LoadWithVectorDescriptor::NameRegister(); // r2 | 4549 Register key = LoadWithVectorDescriptor::NameRegister(); // r2 |
| 4550 Register vector = LoadWithVectorDescriptor::VectorRegister(); // r3 | 4550 Register vector = LoadWithVectorDescriptor::VectorRegister(); // r3 |
| 4551 Register slot = LoadWithVectorDescriptor::SlotRegister(); // r0 | 4551 Register slot = LoadWithVectorDescriptor::SlotRegister(); // r0 |
| 4552 Register feedback = r4; | 4552 Register feedback = r4; |
| 4553 Register receiver_map = r5; | 4553 Register receiver_map = r5; |
| 4554 Register scratch1 = r8; | 4554 Register scratch1 = r6; |
| 4555 | 4555 |
| 4556 __ add(feedback, vector, Operand::PointerOffsetFromSmiKey(slot)); | 4556 __ add(feedback, vector, Operand::PointerOffsetFromSmiKey(slot)); |
| 4557 __ ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize)); | 4557 __ ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize)); |
| 4558 | 4558 |
| 4559 // Try to quickly handle the monomorphic case without knowing for sure | 4559 // Try to quickly handle the monomorphic case without knowing for sure |
| 4560 // if we have a weak cell in feedback. We do know it's safe to look | 4560 // if we have a weak cell in feedback. We do know it's safe to look |
| 4561 // at WeakCell::kValueOffset. | 4561 // at WeakCell::kValueOffset. |
| 4562 Label try_array, load_smi_map, compare_map; | 4562 Label try_array, load_smi_map, compare_map; |
| 4563 Label not_array, miss; | 4563 Label not_array, miss; |
| 4564 HandleMonomorphicCase(masm, receiver, receiver_map, feedback, vector, slot, | 4564 HandleMonomorphicCase(masm, receiver, receiver_map, feedback, vector, slot, |
| (...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5359 MemOperand(fp, 6 * kPointerSize), NULL); | 5359 MemOperand(fp, 6 * kPointerSize), NULL); |
| 5360 } | 5360 } |
| 5361 | 5361 |
| 5362 | 5362 |
| 5363 #undef __ | 5363 #undef __ |
| 5364 | 5364 |
| 5365 } // namespace internal | 5365 } // namespace internal |
| 5366 } // namespace v8 | 5366 } // namespace v8 |
| 5367 | 5367 |
| 5368 #endif // V8_TARGET_ARCH_ARM | 5368 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |