📄 assembler.cc.svn-base
字号:
// Copyright (c) 1994-2006 Sun Microsystems Inc.// All Rights Reserved.//// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met://// - Redistributions of source code must retain the above copyright notice,// this list of conditions and the following disclaimer.//// - Redistribution in binary form must reproduce the above copyright// notice, this list of conditions and the following disclaimer in the// documentation and/or other materials provided with the distribution.//// - Neither the name of Sun Microsystems or the names of contributors may// be used to endorse or promote products derived from this software without// specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.// The original source code covered by the above license above has been// modified significantly by Google Inc.// Copyright 2006-2008 the V8 project authors. All rights reserved.#include "v8.h"#include "arguments.h"#include "execution.h"#include "ic-inl.h"#include "factory.h"#include "runtime.h"#include "serialize.h"#include "stub-cache.h"namespace v8 { namespace internal {// -----------------------------------------------------------------------------// Implementation of Labelint Label::pos() const { if (pos_ < 0) return -pos_ - 1; if (pos_ > 0) return pos_ - 1; UNREACHABLE(); return 0;}// -----------------------------------------------------------------------------// Implementation of RelocInfoWriter and RelocIterator//// Encoding//// The most common modes are given single-byte encodings. Also, it is// easy to identify the type of reloc info and skip unwanted modes in// an iteration.//// The encoding relies on the fact that there are less than 14// different relocation modes.//// embedded_object: [6 bits pc delta] 00//// code_taget: [6 bits pc delta] 01//// position: [6 bits pc delta] 10,// [7 bits signed data delta] 0//// statement_position: [6 bits pc delta] 10,// [7 bits signed data delta] 1//// any nondata mode: 00 [4 bits rmode] 11, // rmode: 0..13 only// 00 [6 bits pc delta]//// pc-jump: 00 1111 11,// 00 [6 bits pc delta]//// pc-jump: 01 1111 11,// (variable length) 7 - 26 bit pc delta, written in chunks of 7// bits, the lowest 7 bits written first.//// data-jump + pos: 00 1110 11,// signed int, lowest byte written first//// data-jump + st.pos: 01 1110 11,// signed int, lowest byte written first//// data-jump + comm.: 10 1110 11,// signed int, lowest byte written first//const int kMaxRelocModes = 14;const int kTagBits = 2;const int kTagMask = (1 << kTagBits) - 1;const int kExtraTagBits = 4;const int kPositionTypeTagBits = 1;const int kSmallDataBits = kBitsPerByte - kPositionTypeTagBits;const int kEmbeddedObjectTag = 0;const int kCodeTargetTag = 1;const int kPositionTag = 2;const int kDefaultTag = 3;const int kPCJumpTag = (1 << kExtraTagBits) - 1;const int kSmallPCDeltaBits = kBitsPerByte - kTagBits;const int kSmallPCDeltaMask = (1 << kSmallPCDeltaBits) - 1;const int kVariableLengthPCJumpTopTag = 1;const int kChunkBits = 7;const int kChunkMask = (1 << kChunkBits) - 1;const int kLastChunkTagBits = 1;const int kLastChunkTagMask = 1;const int kLastChunkTag = 1;const int kDataJumpTag = kPCJumpTag - 1;const int kNonstatementPositionTag = 0;const int kStatementPositionTag = 1;const int kCommentTag = 2;uint32_t RelocInfoWriter::WriteVariableLengthPCJump(uint32_t pc_delta) { // Return if the pc_delta can fit in kSmallPCDeltaBits bits. // Otherwise write a variable length PC jump for the bits that do // not fit in the kSmallPCDeltaBits bits. if (is_uintn(pc_delta, kSmallPCDeltaBits)) return pc_delta; WriteExtraTag(kPCJumpTag, kVariableLengthPCJumpTopTag); uint32_t pc_jump = pc_delta >> kSmallPCDeltaBits; ASSERT(pc_jump > 0); // Write kChunkBits size chunks of the pc_jump. for (; pc_jump > 0; pc_jump = pc_jump >> kChunkBits) { byte b = pc_jump & kChunkMask; *--pos_ = b << kLastChunkTagBits; } // Tag the last chunk so it can be identified. *pos_ = *pos_ | kLastChunkTag; // Return the remaining kSmallPCDeltaBits of the pc_delta. return pc_delta & kSmallPCDeltaMask;}void RelocInfoWriter::WriteTaggedPC(uint32_t pc_delta, int tag) { // Write a byte of tagged pc-delta, possibly preceded by var. length pc-jump. pc_delta = WriteVariableLengthPCJump(pc_delta); *--pos_ = pc_delta << kTagBits | tag;}void RelocInfoWriter::WriteTaggedData(int32_t data_delta, int tag) { *--pos_ = data_delta << kPositionTypeTagBits | tag;}void RelocInfoWriter::WriteExtraTag(int extra_tag, int top_tag) { *--pos_ = top_tag << (kTagBits + kExtraTagBits) | extra_tag << kTagBits | kDefaultTag;}void RelocInfoWriter::WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag) { // Write two-byte tagged pc-delta, possibly preceded by var. length pc-jump. pc_delta = WriteVariableLengthPCJump(pc_delta); WriteExtraTag(extra_tag, 0); *--pos_ = pc_delta;}void RelocInfoWriter::WriteExtraTaggedData(int32_t data_delta, int top_tag) { WriteExtraTag(kDataJumpTag, top_tag); for (int i = 0; i < kIntSize; i++) { *--pos_ = data_delta; data_delta = ArithmeticShiftRight(data_delta, kBitsPerByte); }}void RelocInfoWriter::Write(const RelocInfo* rinfo) {#ifdef DEBUG byte* begin_pos = pos_;#endif Counters::reloc_info_count.Increment(); ASSERT(rinfo->pc() - last_pc_ >= 0); ASSERT(RelocInfo::NUMBER_OF_MODES < kMaxRelocModes); // Use unsigned delta-encoding for pc. uint32_t pc_delta = rinfo->pc() - last_pc_; RelocInfo::Mode rmode = rinfo->rmode(); // The two most common modes are given small tags, and usually fit in a byte. if (rmode == RelocInfo::EMBEDDED_OBJECT) { WriteTaggedPC(pc_delta, kEmbeddedObjectTag); } else if (rmode == RelocInfo::CODE_TARGET) { WriteTaggedPC(pc_delta, kCodeTargetTag); } else if (RelocInfo::IsPosition(rmode)) { // Use signed delta-encoding for data. int32_t data_delta = rinfo->data() - last_data_; int pos_type_tag = rmode == RelocInfo::POSITION ? kNonstatementPositionTag : kStatementPositionTag; // Check if data is small enough to fit in a tagged byte. if (is_intn(data_delta, kSmallDataBits)) { WriteTaggedPC(pc_delta, kPositionTag); WriteTaggedData(data_delta, pos_type_tag); last_data_ = rinfo->data(); } else { // Otherwise, use costly encoding. WriteExtraTaggedPC(pc_delta, kPCJumpTag); WriteExtraTaggedData(data_delta, pos_type_tag); last_data_ = rinfo->data(); } } else if (RelocInfo::IsComment(rmode)) { // Comments are normally not generated, so we use the costly encoding. WriteExtraTaggedPC(pc_delta, kPCJumpTag); WriteExtraTaggedData(rinfo->data() - last_data_, kCommentTag); last_data_ = rinfo->data(); } else { // For all other modes we simply use the mode as the extra tag. // None of these modes need a data component. ASSERT(rmode < kPCJumpTag && rmode < kDataJumpTag); WriteExtraTaggedPC(pc_delta, rmode); } last_pc_ = rinfo->pc();#ifdef DEBUG ASSERT(begin_pos - pos_ <= kMaxSize);#endif}inline int RelocIterator::AdvanceGetTag() { return *--pos_ & kTagMask;}inline int RelocIterator::GetExtraTag() { return (*pos_ >> kTagBits) & ((1 << kExtraTagBits) - 1);}inline int RelocIterator::GetTopTag() { return *pos_ >> (kTagBits + kExtraTagBits);}inline void RelocIterator::ReadTaggedPC() { rinfo_.pc_ += *pos_ >> kTagBits;}inline void RelocIterator::AdvanceReadPC() { rinfo_.pc_ += *--pos_;}void RelocIterator::AdvanceReadData() { int32_t x = 0; for (int i = 0; i < kIntSize; i++) { x |= *--pos_ << i * kBitsPerByte; } rinfo_.data_ += x;}void RelocIterator::AdvanceReadVariableLengthPCJump() { // Read the 32-kSmallPCDeltaBits most significant bits of the // pc jump in kChunkBits bit chunks and shift them into place. // Stop when the last chunk is encountered. uint32_t pc_jump = 0; for (int i = 0; i < kIntSize; i++) { byte pc_jump_part = *--pos_; pc_jump |= (pc_jump_part >> kLastChunkTagBits) << i * kChunkBits; if ((pc_jump_part & kLastChunkTagMask) == 1) break; } // The least significant kSmallPCDeltaBits bits will be added // later. rinfo_.pc_ += pc_jump << kSmallPCDeltaBits;}inline int RelocIterator::GetPositionTypeTag() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -