// Copyright 2012 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #if V8_TARGET_ARCH_X64 #include "src/codegen.h" #include "src/ic/ic.h" #include "src/ic/stub-cache.h" #include "src/objects-inl.h" namespace v8 { namespace internal { Condition CompareIC::ComputeCondition(Token::Value op) { switch (op) { case Token::EQ_STRICT: case Token::EQ: return equal; case Token::LT: return less; case Token::GT: return greater; case Token::LTE: return less_equal; case Token::GTE: return greater_equal; default: UNREACHABLE(); return no_condition; } } bool CompareIC::HasInlinedSmiCode(Address address) { // The address of the instruction following the call. Address test_instruction_address = address + Assembler::kCallTargetAddressOffset; // If the instruction following the call is not a test al, nothing // was inlined. return *test_instruction_address == Assembler::kTestAlByte; } void PatchInlinedSmiCode(Isolate* isolate, Address address, InlinedSmiCheck check) { // The address of the instruction following the call. Address test_instruction_address = address + Assembler::kCallTargetAddressOffset; // If the instruction following the call is not a test al, nothing // was inlined. if (*test_instruction_address != Assembler::kTestAlByte) { DCHECK(*test_instruction_address == Assembler::kNopByte); return; } Address delta_address = test_instruction_address + 1; // The delta to the start of the map check instruction and the // condition code uses at the patched jump. uint8_t delta = *reinterpret_cast<uint8_t*>(delta_address); if (FLAG_trace_ic) { LOG(isolate, PatchIC(address, test_instruction_address, delta)); } // Patch with a short conditional jump. Enabling means switching from a short // jump-if-carry/not-carry to jump-if-zero/not-zero, whereas disabling is the // reverse operation of that. Address jmp_address = test_instruction_address - delta; DCHECK((check == ENABLE_INLINED_SMI_CHECK) ? (*jmp_address == Assembler::kJncShortOpcode || *jmp_address == Assembler::kJcShortOpcode) : (*jmp_address == Assembler::kJnzShortOpcode || *jmp_address == Assembler::kJzShortOpcode)); Condition cc = (check == ENABLE_INLINED_SMI_CHECK) ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); } } // namespace internal } // namespace v8 #endif // V8_TARGET_ARCH_X64