Line data Source code
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
3 : // found in the LICENSE file.
4 :
5 : #if V8_TARGET_ARCH_X64
6 :
7 : #include "src/codegen.h"
8 : #include "src/ic/ic.h"
9 : #include "src/ic/stub-cache.h"
10 : #include "src/objects-inl.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 :
16 465231 : Condition CompareIC::ComputeCondition(Token::Value op) {
17 465231 : switch (op) {
18 : case Token::EQ_STRICT:
19 : case Token::EQ:
20 : return equal;
21 : case Token::LT:
22 85130 : return less;
23 : case Token::GT:
24 43418 : return greater;
25 : case Token::LTE:
26 8210 : return less_equal;
27 : case Token::GTE:
28 12442 : return greater_equal;
29 : default:
30 0 : UNREACHABLE();
31 : return no_condition;
32 : }
33 : }
34 :
35 :
36 272912 : bool CompareIC::HasInlinedSmiCode(Address address) {
37 : // The address of the instruction following the call.
38 : Address test_instruction_address =
39 : address + Assembler::kCallTargetAddressOffset;
40 :
41 : // If the instruction following the call is not a test al, nothing
42 : // was inlined.
43 272912 : return *test_instruction_address == Assembler::kTestAlByte;
44 : }
45 :
46 :
47 633394 : void PatchInlinedSmiCode(Isolate* isolate, Address address,
48 : InlinedSmiCheck check) {
49 : // The address of the instruction following the call.
50 : Address test_instruction_address =
51 633394 : address + Assembler::kCallTargetAddressOffset;
52 :
53 : // If the instruction following the call is not a test al, nothing
54 : // was inlined.
55 633394 : if (*test_instruction_address != Assembler::kTestAlByte) {
56 : DCHECK(*test_instruction_address == Assembler::kNopByte);
57 633394 : return;
58 : }
59 :
60 : Address delta_address = test_instruction_address + 1;
61 : // The delta to the start of the map check instruction and the
62 : // condition code uses at the patched jump.
63 210442 : uint8_t delta = *reinterpret_cast<uint8_t*>(delta_address);
64 210442 : if (FLAG_trace_ic) {
65 0 : LOG(isolate, PatchIC(address, test_instruction_address, delta));
66 : }
67 :
68 : // Patch with a short conditional jump. Enabling means switching from a short
69 : // jump-if-carry/not-carry to jump-if-zero/not-zero, whereas disabling is the
70 : // reverse operation of that.
71 210442 : Address jmp_address = test_instruction_address - delta;
72 : DCHECK((check == ENABLE_INLINED_SMI_CHECK)
73 : ? (*jmp_address == Assembler::kJncShortOpcode ||
74 : *jmp_address == Assembler::kJcShortOpcode)
75 : : (*jmp_address == Assembler::kJnzShortOpcode ||
76 : *jmp_address == Assembler::kJzShortOpcode));
77 : Condition cc =
78 : (check == ENABLE_INLINED_SMI_CHECK)
79 210440 : ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
80 420882 : : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
81 210442 : *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
82 : }
83 : } // namespace internal
84 : } // namespace v8
85 :
86 : #endif // V8_TARGET_ARCH_X64
|