17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved. 27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// found in the LICENSE file. 47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 57d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifndef V8_COMPILER_FRAME_H_ 67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define V8_COMPILER_FRAME_H_ 77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 87d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/v8.h" 97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/data-flow.h" 117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace v8 { 137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace internal { 147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace compiler { 157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Collects the spill slot requirements and the allocated general and double 177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// registers for a compiled function. Frames are usually populated by the 187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// register allocator and are used by Linkage to generate code for the prologue 197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// and epilogue to compiled code. 207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass Frame { 217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Frame() 237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : register_save_area_size_(0), 247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org spill_slot_count_(0), 257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org double_spill_slot_count_(0), 267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org allocated_registers_(NULL), 277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org allocated_double_registers_(NULL) {} 287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org inline int GetSpillSlotCount() { return spill_slot_count_; } 307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org inline int GetDoubleSpillSlotCount() { return double_spill_slot_count_; } 317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void SetAllocatedRegisters(BitVector* regs) { 33e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(allocated_registers_ == NULL); 347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org allocated_registers_ = regs; 357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void SetAllocatedDoubleRegisters(BitVector* regs) { 38e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(allocated_double_registers_ == NULL); 397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org allocated_double_registers_ = regs; 407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool DidAllocateDoubleRegisters() { 437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return !allocated_double_registers_->IsEmpty(); 447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void SetRegisterSaveAreaSize(int size) { 47e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsAligned(size, kPointerSize)); 487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org register_save_area_size_ = size; 497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int GetRegisterSaveAreaSize() { return register_save_area_size_; } 527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int AllocateSpillSlot(bool is_double) { 547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // If 32-bit, skip one if the new slot is a double. 557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (is_double) { 567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (kDoubleSize > kPointerSize) { 57e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kDoubleSize == kPointerSize * 2); 587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org spill_slot_count_++; 597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org spill_slot_count_ |= 1; 607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org double_spill_slot_count_++; 627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return spill_slot_count_++; 647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private: 677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int register_save_area_size_; 687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int spill_slot_count_; 697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int double_spill_slot_count_; 707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BitVector* allocated_registers_; 717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BitVector* allocated_double_registers_; 727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Represents an offset from either the stack pointer or frame pointer. 767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass FrameOffset { 777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org inline bool from_stack_pointer() { return (offset_ & 1) == kFromSp; } 797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org inline bool from_frame_pointer() { return (offset_ & 1) == kFromFp; } 807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org inline int offset() { return offset_ & ~1; } 817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org inline static FrameOffset FromStackPointer(int offset) { 83e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((offset & 1) == 0); 847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return FrameOffset(offset | kFromSp); 857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org inline static FrameOffset FromFramePointer(int offset) { 88e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((offset & 1) == 0); 897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return FrameOffset(offset | kFromFp); 907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private: 937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit FrameOffset(int offset) : offset_(offset) {} 947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int offset_; // Encodes SP or FP in the low order bit. 967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static const int kFromSp = 1; 987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static const int kFromFp = 0; 997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 1007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 1017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 1027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} // namespace v8::internal::compiler 1037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif // V8_COMPILER_FRAME_H_ 105