diff options
Diffstat (limited to 'V8Binding/v8/src/jump-target.cc')
-rw-r--r-- | V8Binding/v8/src/jump-target.cc | 383 |
1 files changed, 0 insertions, 383 deletions
diff --git a/V8Binding/v8/src/jump-target.cc b/V8Binding/v8/src/jump-target.cc deleted file mode 100644 index 3782f92..0000000 --- a/V8Binding/v8/src/jump-target.cc +++ /dev/null @@ -1,383 +0,0 @@ -// Copyright 2009 the V8 project authors. 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. -// * Redistributions 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 Google Inc. nor the names of its -// 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. - -#include "v8.h" - -#include "codegen-inl.h" -#include "jump-target-inl.h" -#include "register-allocator-inl.h" - -namespace v8 { -namespace internal { - -// ------------------------------------------------------------------------- -// JumpTarget implementation. - -bool JumpTarget::compiling_deferred_code_ = false; - - -void JumpTarget::Unuse() { - reaching_frames_.Clear(); - merge_labels_.Clear(); - entry_frame_ = NULL; - entry_label_.Unuse(); -} - - -void JumpTarget::ComputeEntryFrame() { - // Given: a collection of frames reaching by forward CFG edges and - // the directionality of the block. Compute: an entry frame for the - // block. - - Counters::compute_entry_frame.Increment(); -#ifdef DEBUG - if (compiling_deferred_code_) { - ASSERT(reaching_frames_.length() > 1); - VirtualFrame* frame = reaching_frames_[0]; - bool all_identical = true; - for (int i = 1; i < reaching_frames_.length(); i++) { - if (!frame->Equals(reaching_frames_[i])) { - all_identical = false; - break; - } - } - ASSERT(!all_identical || all_identical); - } -#endif - - // Choose an initial frame. - VirtualFrame* initial_frame = reaching_frames_[0]; - - // A list of pointers to frame elements in the entry frame. NULL - // indicates that the element has not yet been determined. - int length = initial_frame->element_count(); - ZoneList<FrameElement*> elements(length); - - // Initially populate the list of elements based on the initial - // frame. - for (int i = 0; i < length; i++) { - FrameElement element = initial_frame->elements_[i]; - // We do not allow copies or constants in bidirectional frames. - if (direction_ == BIDIRECTIONAL) { - if (element.is_constant() || element.is_copy()) { - elements.Add(NULL); - continue; - } - } - elements.Add(&initial_frame->elements_[i]); - } - - // Compute elements based on the other reaching frames. - if (reaching_frames_.length() > 1) { - for (int i = 0; i < length; i++) { - FrameElement* element = elements[i]; - for (int j = 1; j < reaching_frames_.length(); j++) { - // Element computation is monotonic: new information will not - // change our decision about undetermined or invalid elements. - if (element == NULL || !element->is_valid()) break; - - element = element->Combine(&reaching_frames_[j]->elements_[i]); - } - elements[i] = element; - } - } - - // Build the new frame. A freshly allocated frame has memory elements - // for the parameters and some platform-dependent elements (e.g., - // return address). Replace those first. - entry_frame_ = new VirtualFrame(); - int index = 0; - for (; index < entry_frame_->element_count(); index++) { - FrameElement* target = elements[index]; - // If the element is determined, set it now. Count registers. Mark - // elements as copied exactly when they have a copy. Undetermined - // elements are initially recorded as if in memory. - if (target != NULL) { - entry_frame_->elements_[index] = *target; - InitializeEntryElement(index, target); - } - } - // Then fill in the rest of the frame with new elements. - for (; index < length; index++) { - FrameElement* target = elements[index]; - if (target == NULL) { - entry_frame_->elements_.Add(FrameElement::MemoryElement()); - } else { - entry_frame_->elements_.Add(*target); - InitializeEntryElement(index, target); - } - } - - // Allocate any still-undetermined frame elements to registers or - // memory, from the top down. - for (int i = length - 1; i >= 0; i--) { - if (elements[i] == NULL) { - // Loop over all the reaching frames to check whether the element - // is synced on all frames and to count the registers it occupies. - bool is_synced = true; - RegisterFile candidate_registers; - int best_count = kMinInt; - int best_reg_num = RegisterAllocator::kInvalidRegister; - - for (int j = 0; j < reaching_frames_.length(); j++) { - FrameElement element = reaching_frames_[j]->elements_[i]; - is_synced = is_synced && element.is_synced(); - if (element.is_register() && !entry_frame_->is_used(element.reg())) { - // Count the register occurrence and remember it if better - // than the previous best. - int num = RegisterAllocator::ToNumber(element.reg()); - candidate_registers.Use(num); - if (candidate_registers.count(num) > best_count) { - best_count = candidate_registers.count(num); - best_reg_num = num; - } - } - } - - // If the value is synced on all frames, put it in memory. This - // costs nothing at the merge code but will incur a - // memory-to-register move when the value is needed later. - if (is_synced) { - // Already recorded as a memory element. - continue; - } - - // Try to put it in a register. If there was no best choice - // consider any free register. - if (best_reg_num == RegisterAllocator::kInvalidRegister) { - for (int j = 0; j < RegisterAllocator::kNumRegisters; j++) { - if (!entry_frame_->is_used(j)) { - best_reg_num = j; - break; - } - } - } - - if (best_reg_num != RegisterAllocator::kInvalidRegister) { - // If there was a register choice, use it. Preserve the copied - // flag on the element. - bool is_copied = entry_frame_->elements_[i].is_copied(); - Register reg = RegisterAllocator::ToRegister(best_reg_num); - entry_frame_->elements_[i] = - FrameElement::RegisterElement(reg, - FrameElement::NOT_SYNCED); - if (is_copied) entry_frame_->elements_[i].set_copied(); - entry_frame_->set_register_location(reg, i); - } - } - } - - // The stack pointer is at the highest synced element or the base of - // the expression stack. - int stack_pointer = length - 1; - while (stack_pointer >= entry_frame_->expression_base_index() && - !entry_frame_->elements_[stack_pointer].is_synced()) { - stack_pointer--; - } - entry_frame_->stack_pointer_ = stack_pointer; -} - - -void JumpTarget::Jump() { - DoJump(); -} - - -void JumpTarget::Jump(Result* arg) { - ASSERT(cgen()->has_valid_frame()); - - cgen()->frame()->Push(arg); - DoJump(); -} - - -void JumpTarget::Branch(Condition cc, Hint hint) { - DoBranch(cc, hint); -} - - -#ifdef DEBUG -#define DECLARE_ARGCHECK_VARS(name) \ - Result::Type name##_type = name->type(); \ - Register name##_reg = name->is_register() ? name->reg() : no_reg - -#define ASSERT_ARGCHECK(name) \ - ASSERT(name->type() == name##_type); \ - ASSERT(!name->is_register() || name->reg().is(name##_reg)) - -#else -#define DECLARE_ARGCHECK_VARS(name) do {} while (false) - -#define ASSERT_ARGCHECK(name) do {} while (false) -#endif - -void JumpTarget::Branch(Condition cc, Result* arg, Hint hint) { - ASSERT(cgen()->has_valid_frame()); - - // We want to check that non-frame registers at the call site stay in - // the same registers on the fall-through branch. - DECLARE_ARGCHECK_VARS(arg); - - cgen()->frame()->Push(arg); - DoBranch(cc, hint); - *arg = cgen()->frame()->Pop(); - - ASSERT_ARGCHECK(arg); -} - - -void BreakTarget::Branch(Condition cc, Result* arg, Hint hint) { - ASSERT(cgen()->has_valid_frame()); - - int count = cgen()->frame()->height() - expected_height_; - if (count > 0) { - // We negate and branch here rather than using DoBranch's negate - // and branch. This gives us a hook to remove statement state - // from the frame. - JumpTarget fall_through; - // Branch to fall through will not negate, because it is a - // forward-only target. - fall_through.Branch(NegateCondition(cc), NegateHint(hint)); - Jump(arg); // May emit merge code here. - fall_through.Bind(); - } else { - DECLARE_ARGCHECK_VARS(arg); - cgen()->frame()->Push(arg); - DoBranch(cc, hint); - *arg = cgen()->frame()->Pop(); - ASSERT_ARGCHECK(arg); - } -} - -#undef DECLARE_ARGCHECK_VARS -#undef ASSERT_ARGCHECK - - -void JumpTarget::Bind() { - DoBind(); -} - - -void JumpTarget::Bind(Result* arg) { - if (cgen()->has_valid_frame()) { - cgen()->frame()->Push(arg); - } - DoBind(); - *arg = cgen()->frame()->Pop(); -} - - -void JumpTarget::AddReachingFrame(VirtualFrame* frame) { - ASSERT(reaching_frames_.length() == merge_labels_.length()); - ASSERT(entry_frame_ == NULL); - Label fresh; - merge_labels_.Add(fresh); - reaching_frames_.Add(frame); -} - - -// ------------------------------------------------------------------------- -// BreakTarget implementation. - -void BreakTarget::set_direction(Directionality direction) { - JumpTarget::set_direction(direction); - ASSERT(cgen()->has_valid_frame()); - expected_height_ = cgen()->frame()->height(); -} - - -void BreakTarget::CopyTo(BreakTarget* destination) { - ASSERT(destination != NULL); - destination->direction_ = direction_; - destination->reaching_frames_.Rewind(0); - destination->reaching_frames_.AddAll(reaching_frames_); - destination->merge_labels_.Rewind(0); - destination->merge_labels_.AddAll(merge_labels_); - destination->entry_frame_ = entry_frame_; - destination->entry_label_ = entry_label_; - destination->expected_height_ = expected_height_; -} - - -void BreakTarget::Branch(Condition cc, Hint hint) { - ASSERT(cgen()->has_valid_frame()); - - int count = cgen()->frame()->height() - expected_height_; - if (count > 0) { - // We negate and branch here rather than using DoBranch's negate - // and branch. This gives us a hook to remove statement state - // from the frame. - JumpTarget fall_through; - // Branch to fall through will not negate, because it is a - // forward-only target. - fall_through.Branch(NegateCondition(cc), NegateHint(hint)); - Jump(); // May emit merge code here. - fall_through.Bind(); - } else { - DoBranch(cc, hint); - } -} - - -// ------------------------------------------------------------------------- -// ShadowTarget implementation. - -ShadowTarget::ShadowTarget(BreakTarget* shadowed) { - ASSERT(shadowed != NULL); - other_target_ = shadowed; - -#ifdef DEBUG - is_shadowing_ = true; -#endif - // While shadowing this shadow target saves the state of the original. - shadowed->CopyTo(this); - - // The original's state is reset. - shadowed->Unuse(); - ASSERT(cgen()->has_valid_frame()); - shadowed->set_expected_height(cgen()->frame()->height()); -} - - -void ShadowTarget::StopShadowing() { - ASSERT(is_shadowing_); - - // The states of this target, which was shadowed, and the original - // target, which was shadowing, are swapped. - BreakTarget temp; - other_target_->CopyTo(&temp); - CopyTo(other_target_); - temp.CopyTo(this); - temp.Unuse(); - -#ifdef DEBUG - is_shadowing_ = false; -#endif -} - - -} } // namespace v8::internal |