1e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org// Copyright 2013 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 4a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen.h" 6a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org#include <algorithm> 8ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/allocation-site-scopes.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/full-codegen.h" 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hashmap.h" 14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-bce.h" 15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-bch.h" 16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-canonicalize.h" 17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-check-elimination.h" 18196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-dce.h" 19196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-dehoist.h" 20196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-environment-liveness.h" 21196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-escape-analysis.h" 22196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-infer-representation.h" 23196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-infer-types.h" 24196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-load-elimination.h" 25196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-gvn.h" 26196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-mark-deoptimize.h" 27196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-mark-unreachable.h" 28196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-osr.h" 29196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-range-analysis.h" 30196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-redundant-phi.h" 31196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-removable-simulates.h" 32196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-representation-changes.h" 33196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-sce.h" 34196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-store-elimination.h" 35196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-uint32-analysis.h" 36196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/lithium-allocator.h" 37196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/parser.h" 38196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/runtime.h" 39196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopeinfo.h" 40196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopes.h" 41196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/stub-cache.h" 42196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/typing.h" 43a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 44a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#if V8_TARGET_ARCH_IA32 45196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/ia32/lithium-codegen-ia32.h" 46a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#elif V8_TARGET_ARCH_X64 47196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/x64/lithium-codegen-x64.h" 48fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org#elif V8_TARGET_ARCH_ARM64 49196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arm64/lithium-codegen-arm64.h" 50a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#elif V8_TARGET_ARCH_ARM 51196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arm/lithium-codegen-arm.h" 527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#elif V8_TARGET_ARCH_MIPS 53196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/mips/lithium-codegen-mips.h" 54864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#elif V8_TARGET_ARCH_X87 55196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/x87/lithium-codegen-x87.h" 56a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#else 57a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#error Unsupported target architecture. 58a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif 59a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 60a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace v8 { 61a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace internal { 62a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 63a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHBasicBlock::HBasicBlock(HGraph* graph) 64a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org : block_id_(graph->GetNextBlockID()), 65a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org graph_(graph), 667028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org phis_(4, graph->zone()), 67a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org first_(NULL), 68a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org last_(NULL), 69a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org end_(NULL), 70a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org loop_information_(NULL), 717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org predecessors_(2, graph->zone()), 72a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org dominator_(NULL), 737028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org dominated_blocks_(4, graph->zone()), 74a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org last_environment_(NULL), 75a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org argument_count_(-1), 76a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org first_instruction_index_(-1), 77a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org last_instruction_index_(-1), 787028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org deleted_phis_(4, graph->zone()), 79496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org parent_loop_header_(NULL), 80d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org inlined_entry_block_(NULL), 816d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org is_inline_return_target_(false), 82d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org is_reachable_(true), 837c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org dominates_loop_successors_(false), 8454ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org is_osr_entry_(false), 8554ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org is_ordered_(false) { } 86a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 87a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 88750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgIsolate* HBasicBlock::isolate() const { 89750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return graph_->isolate(); 90750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 91750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 92750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 93d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgvoid HBasicBlock::MarkUnreachable() { 94d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org is_reachable_ = false; 95d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org} 96d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 97d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 98a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::AttachLoopInformation() { 99a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(!IsLoopHeader()); 1007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org loop_information_ = new(zone()) HLoopInformation(this, zone()); 101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 103a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 104a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::DetachLoopInformation() { 105a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(IsLoopHeader()); 106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org loop_information_ = NULL; 107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 108a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 110a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::AddPhi(HPhi* phi) { 111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(!IsStartBlock()); 1127028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org phis_.Add(phi, zone()); 113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org phi->SetBlock(this); 114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 116a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 117a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::RemovePhi(HPhi* phi) { 118a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(phi->block() == this); 119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(phis_.Contains(phi)); 120ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org phi->Kill(); 121a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org phis_.RemoveElement(phi); 122a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org phi->SetBlock(NULL); 123a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 124a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 125a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 126f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid HBasicBlock::AddInstruction(HInstruction* instr, 127f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HSourcePosition position) { 128a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(!IsStartBlock() || !IsFinished()); 129a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(!instr->IsLinked()); 130a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(!IsFinished()); 131b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 132f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!position.IsUnknown()) { 13371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org instr->set_position(position); 13471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org } 135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (first_ == NULL) { 136b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org ASSERT(last_environment() != NULL); 137b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org ASSERT(!last_environment()->ast_id().IsNone()); 13874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org HBlockEntry* entry = new(zone()) HBlockEntry(); 139a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org entry->InitializeAsFirst(this); 140f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!position.IsUnknown()) { 14171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org entry->set_position(position); 14271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org } else { 143f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ASSERT(!FLAG_hydrogen_track_positions || 14471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org !graph()->info()->IsOptimizing()); 14571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org } 14649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org first_ = last_ = entry; 147a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 14849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org instr->InsertAfter(last_); 149a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 150a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 151a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 152ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.orgHPhi* HBasicBlock::AddNewPhi(int merged_index) { 153ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org if (graph()->IsInsideNoSideEffectsScope()) { 154ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org merged_index = HPhi::kInvalidMergedIndex; 155ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org } 156ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org HPhi* phi = new(zone()) HPhi(merged_index, zone()); 157ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org AddPhi(phi); 158ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org return phi; 159ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org} 160ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org 161ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org 162fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgHSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id, 163fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org RemovableSimulate removable) { 164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(HasEnvironment()); 165a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HEnvironment* environment = last_environment(); 166471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ASSERT(ast_id.IsNone() || 167a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ast_id == BailoutId::StubEntry() || 16804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org environment->closure()->shared()->VerifyBailoutId(ast_id)); 169a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 170a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int push_count = environment->push_count(); 171a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int pop_count = environment->pop_count(); 172a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 173fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org HSimulate* instr = 174fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org new(zone()) HSimulate(ast_id, pop_count, zone(), removable); 175d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org#ifdef DEBUG 176d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org instr->set_closure(environment->closure()); 177d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org#endif 178fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Order of pushed values: newest (top of stack) first. This allows 179a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org // HSimulate::MergeWith() to easily append additional pushed values 180fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // that are older (from further down the stack). 181fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org for (int i = 0; i < push_count; ++i) { 182a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org instr->AddPushedValue(environment->ExpressionStackAt(i)); 183a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 18459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org for (GrowableBitVector::Iterator it(environment->assigned_variables(), 18559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org zone()); 18659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org !it.Done(); 18759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org it.Advance()) { 18859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org int index = it.Current(); 189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org instr->AddAssignedValue(index, environment->Lookup(index)); 190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org environment->ClearHistory(); 192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return instr; 193a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 194a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 195a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 196f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid HBasicBlock::Finish(HControlInstruction* end, HSourcePosition position) { 197a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(!IsFinished()); 19871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org AddInstruction(end, position); 199a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org end_ = end; 2006d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { 2016d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org it.Current()->RegisterPredecessor(this); 202a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 203a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 204a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 206b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid HBasicBlock::Goto(HBasicBlock* block, 207f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HSourcePosition position, 208b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org FunctionState* state, 209b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org bool add_simulate) { 210471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org bool drop_extra = state != NULL && 211a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org state->inlining_kind() == NORMAL_RETURN; 21228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 2134d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org if (block->IsInlineReturnTarget()) { 214d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org HEnvironment* env = last_environment(); 215d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org int argument_count = env->arguments_environment()->parameter_count(); 21671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org AddInstruction(new(zone()) 21771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org HLeaveInlined(state->entry(), argument_count), 21871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org position); 219d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); 2204d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org } 22128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 22271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org if (add_simulate) AddNewSimulate(BailoutId::None(), position); 22374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org HGoto* instr = new(zone()) HGoto(block); 22471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Finish(instr, position); 225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 228394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid HBasicBlock::AddLeaveInlined(HValue* return_value, 22971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org FunctionState* state, 230f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HSourcePosition position) { 231471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org HBasicBlock* target = state->function_return(); 232a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org bool drop_extra = state->inlining_kind() == NORMAL_RETURN; 23328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 2344d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org ASSERT(target->IsInlineReturnTarget()); 2354d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org ASSERT(return_value != NULL); 236d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org HEnvironment* env = last_environment(); 237d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org int argument_count = env->arguments_environment()->parameter_count(); 23871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org AddInstruction(new(zone()) HLeaveInlined(state->entry(), argument_count), 23971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org position); 240d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); 2414d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org last_environment()->Push(return_value); 24271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org AddNewSimulate(BailoutId::None(), position); 24374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org HGoto* instr = new(zone()) HGoto(target); 24471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Finish(instr, position); 2454d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org} 2464d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org 2474d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org 248b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid HBasicBlock::SetInitialEnvironment(HEnvironment* env) { 249a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(!HasEnvironment()); 250a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(first() == NULL); 251a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org UpdateEnvironment(env); 252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 253a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 254a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 255d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgvoid HBasicBlock::UpdateEnvironment(HEnvironment* env) { 256d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org last_environment_ = env; 257d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org graph()->update_maximum_environment_size(env->first_expression_index()); 258d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org} 259d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 260d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 261471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid HBasicBlock::SetJoinId(BailoutId ast_id) { 262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int length = predecessors_.length(); 263a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(length > 0); 264a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < length; i++) { 265a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HBasicBlock* predecessor = predecessors_[i]; 266a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(predecessor->end()->IsGoto()); 26749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org HSimulate* simulate = HSimulate::cast(predecessor->end()->previous()); 268a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(i != 0 || 26994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org (predecessor->last_environment()->closure().is_null() || 27094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org predecessor->last_environment()->closure()->shared() 27194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ->VerifyBailoutId(ast_id))); 27204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org simulate->set_ast_id(ast_id); 273b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org predecessor->last_environment()->set_ast_id(ast_id); 274a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 275a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 276a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 277a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 278a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgbool HBasicBlock::Dominates(HBasicBlock* other) const { 279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HBasicBlock* current = other->dominator(); 280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org while (current != NULL) { 281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (current == this) return true; 282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org current = current->dominator(); 283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return false; 285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 28857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.orgbool HBasicBlock::EqualToOrDominates(HBasicBlock* other) const { 28957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (this == other) return true; 29057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org return Dominates(other); 29157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org} 29257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 29357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 29483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.orgint HBasicBlock::LoopNestingDepth() const { 29583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org const HBasicBlock* current = this; 29683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org int result = (current->IsLoopHeader()) ? 1 : 0; 29783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org while (current->parent_loop_header() != NULL) { 29883e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org current = current->parent_loop_header(); 29983e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org result++; 30083e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org } 30183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org return result; 30283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org} 30383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org 30483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org 305a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::PostProcessLoopHeader(IterationStatement* stmt) { 306a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(IsLoopHeader()); 307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 308a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org SetJoinId(stmt->EntryId()); 309a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (predecessors()->length() == 1) { 310a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // This is a degenerated loop. 311a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DetachLoopInformation(); 312a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return; 313a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 314a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 315a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Only the first entry into the loop is from outside the loop. All other 316a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // entries must be back edges. 317a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 1; i < predecessors()->length(); ++i) { 318a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org loop_information()->RegisterBackEdge(predecessors()->at(i)); 319a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 320a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 321a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 322a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 323f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid HBasicBlock::MarkSuccEdgeUnreachable(int succ) { 324f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ASSERT(IsFinished()); 325f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HBasicBlock* succ_block = end()->SuccessorAt(succ); 326f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 327f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ASSERT(succ_block->predecessors()->length() == 1); 328f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org succ_block->MarkUnreachable(); 329f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 330f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 331f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::RegisterPredecessor(HBasicBlock* pred) { 333160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (HasPredecessor()) { 334a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Only loop header blocks can have a predecessor added after 335a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // instructions have been added to the block (they have phis for all 336a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // values in the environment, these phis may be eliminated later). 337a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(IsLoopHeader() || first_ == NULL); 338a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HEnvironment* incoming_env = pred->last_environment(); 339a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (IsLoopHeader()) { 3405d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org ASSERT(phis()->length() == incoming_env->length()); 341a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < phis_.length(); ++i) { 342a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org phis_[i]->AddInput(incoming_env->values()->at(i)); 343a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 344a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 345a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org last_environment()->AddIncomingEdge(this, pred->last_environment()); 346a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 347a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (!HasEnvironment() && !IsFinished()) { 348a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(!IsLoopHeader()); 349b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org SetInitialEnvironment(pred->last_environment()->Copy()); 350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3527028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org predecessors_.Add(pred, zone()); 353a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 354a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 355a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 356a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::AddDominatedBlock(HBasicBlock* block) { 357a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(!dominated_blocks_.Contains(block)); 358a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Keep the list of dominated blocks sorted such that if there is two 359a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // succeeding block in this list, the predecessor is before the successor. 360a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int index = 0; 361a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org while (index < dominated_blocks_.length() && 362a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org dominated_blocks_[index]->block_id() < block->block_id()) { 363a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ++index; 364a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 3657028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org dominated_blocks_.InsertAt(index, block, zone()); 366a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 367a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 368a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 369a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::AssignCommonDominator(HBasicBlock* other) { 370a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (dominator_ == NULL) { 371a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org dominator_ = other; 372a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org other->AddDominatedBlock(this); 373a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (other->dominator() != NULL) { 374a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HBasicBlock* first = dominator_; 375a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HBasicBlock* second = other; 376a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 377a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org while (first != second) { 378a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (first->block_id() > second->block_id()) { 379a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org first = first->dominator(); 380a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 381a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org second = second->dominator(); 382a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 383a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(first != NULL && second != NULL); 384a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 385a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 386a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (dominator_ != first) { 387a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(dominator_->dominated_blocks_.Contains(this)); 388a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org dominator_->dominated_blocks_.RemoveElement(this); 389a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org dominator_ = first; 390a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org first->AddDominatedBlock(this); 391a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 392a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 393a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 394a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 395a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 39678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgvoid HBasicBlock::AssignLoopSuccessorDominators() { 39778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Mark blocks that dominate all subsequent reachable blocks inside their 39878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // loop. Exploit the fact that blocks are sorted in reverse post order. When 39978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // the loop is visited in increasing block id order, if the number of 40078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // non-loop-exiting successor edges at the dominator_candidate block doesn't 40178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // exceed the number of previously encountered predecessor edges, there is no 40278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // path from the loop header to any block with higher id that doesn't go 40378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // through the dominator_candidate block. In this case, the 40478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // dominator_candidate block is guaranteed to dominate all blocks reachable 40578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // from it with higher ids. 40678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org HBasicBlock* last = loop_information()->GetLastBackEdge(); 40778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org int outstanding_successors = 1; // one edge from the pre-header 40878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Header always dominates everything. 40978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org MarkAsLoopSuccessorDominator(); 41078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org for (int j = block_id(); j <= last->block_id(); ++j) { 41178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org HBasicBlock* dominator_candidate = graph_->blocks()->at(j); 41278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org for (HPredecessorIterator it(dominator_candidate); !it.Done(); 41378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org it.Advance()) { 41478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org HBasicBlock* predecessor = it.Current(); 41578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Don't count back edges. 41678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (predecessor->block_id() < dominator_candidate->block_id()) { 41778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org outstanding_successors--; 41878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 41978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 42078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 42178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // If more successors than predecessors have been seen in the loop up to 42278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // now, it's not possible to guarantee that the current block dominates 42378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // all of the blocks with higher IDs. In this case, assume conservatively 42478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // that those paths through loop that don't go through the current block 42578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // contain all of the loop's dependencies. Also be careful to record 42678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // dominator information about the current loop that's being processed, 42778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // and not nested loops, which will be processed when 42878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // AssignLoopSuccessorDominators gets called on their header. 42978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org ASSERT(outstanding_successors >= 0); 43078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org HBasicBlock* parent_loop_header = dominator_candidate->parent_loop_header(); 43178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (outstanding_successors == 0 && 43278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org (parent_loop_header == this && !dominator_candidate->IsLoopHeader())) { 43378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org dominator_candidate->MarkAsLoopSuccessorDominator(); 43478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 43578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org HControlInstruction* end = dominator_candidate->end(); 43678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { 43778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org HBasicBlock* successor = it.Current(); 43878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Only count successors that remain inside the loop and don't loop back 43978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // to a loop header. 44078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (successor->block_id() > dominator_candidate->block_id() && 44178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org successor->block_id() <= last->block_id()) { 44278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Backwards edges must land on loop headers. 44378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org ASSERT(successor->block_id() > dominator_candidate->block_id() || 44478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org successor->IsLoopHeader()); 44578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org outstanding_successors++; 44678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 44778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 44878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 44978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org} 45078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 45178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 452a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgint HBasicBlock::PredecessorIndexOf(HBasicBlock* predecessor) const { 453a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < predecessors_.length(); ++i) { 454a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (predecessors_[i] == predecessor) return i; 455a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 456a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org UNREACHABLE(); 457a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return -1; 458a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 460a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 461a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG 462a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::Verify() { 463a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Check that every block is finished. 464a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(IsFinished()); 465a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(block_id() >= 0); 4664d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org 4674d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // Check that the incoming edges are in edge split form. 4684d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org if (predecessors_.length() > 1) { 4694d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org for (int i = 0; i < predecessors_.length(); ++i) { 4704d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org ASSERT(predecessors_[i]->end()->SecondSuccessor() == NULL); 4714d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org } 4724d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org } 473a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 474a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif 475a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 476a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 477a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HLoopInformation::RegisterBackEdge(HBasicBlock* block) { 4787028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org this->back_edges_.Add(block, block->zone()); 479a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org AddBlock(block); 480a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 481a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 483a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHBasicBlock* HLoopInformation::GetLastBackEdge() const { 484a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int max_id = -1; 485a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HBasicBlock* result = NULL; 486a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < back_edges_.length(); ++i) { 487a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HBasicBlock* cur = back_edges_[i]; 488a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (cur->block_id() > max_id) { 489a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org max_id = cur->block_id(); 490a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org result = cur; 491a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 492a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 493a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return result; 494a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 495a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HLoopInformation::AddBlock(HBasicBlock* block) { 498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (block == loop_header()) return; 499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (block->parent_loop_header() == loop_header()) return; 500a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (block->parent_loop_header() != NULL) { 501a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org AddBlock(block->parent_loop_header()); 502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org block->set_parent_loop_header(loop_header()); 5047028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org blocks_.Add(block, block->zone()); 505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < block->predecessors()->length(); ++i) { 506a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org AddBlock(block->predecessors()->at(i)); 507a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 508a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 509a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 510a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 511a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 512a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG 513a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 514a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Checks reachability of the blocks in this graph and stores a bit in 515a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// the BitVector "reachable()" for every block that can be reached 516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// from the start block of the graph. If "dont_visit" is non-null, the given 517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// block is treated as if it would not be part of the graph. "visited_count()" 518a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// returns the number of reachable blocks. 519a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass ReachabilityAnalyzer BASE_EMBEDDED { 520a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public: 521a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ReachabilityAnalyzer(HBasicBlock* entry_block, 522a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int block_count, 523a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HBasicBlock* dont_visit) 524a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org : visited_count_(0), 5257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org stack_(16, entry_block->zone()), 5267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org reachable_(block_count, entry_block->zone()), 527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org dont_visit_(dont_visit) { 528a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PushBlock(entry_block); 529a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Analyze(); 530a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 531a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 532a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int visited_count() const { return visited_count_; } 533a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const BitVector* reachable() const { return &reachable_; } 534a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 535a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private: 536a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void PushBlock(HBasicBlock* block) { 537a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (block != NULL && block != dont_visit_ && 538a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org !reachable_.Contains(block->block_id())) { 539a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org reachable_.Add(block->block_id()); 5407028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org stack_.Add(block, block->zone()); 541a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org visited_count_++; 542a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 543a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 545a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org void Analyze() { 546a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org while (!stack_.is_empty()) { 547a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HControlInstruction* end = stack_.RemoveLast()->end(); 5486d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { 5496d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org PushBlock(it.Current()); 5506d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org } 551a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 552a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 553a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 554a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int visited_count_; 555a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ZoneList<HBasicBlock*> stack_; 556a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org BitVector reachable_; 557a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HBasicBlock* dont_visit_; 558a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}; 559a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 560a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 561c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid HGraph::Verify(bool do_full_verify) const { 5621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Heap::RelocationLock relocation_lock(isolate()->heap()); 5631fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org AllowHandleDereference allow_deref; 56479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference allow_deferred_deref; 565a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < blocks_.length(); i++) { 566a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HBasicBlock* block = blocks_.at(i); 567a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 568a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org block->Verify(); 569a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 570a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Check that every block contains at least one node and that only the last 571a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // node is a control instruction. 572a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HInstruction* current = block->first(); 573a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(current != NULL && current->IsBlockEntry()); 574a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org while (current != NULL) { 575a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT((current->next() == NULL) == current->IsControlInstruction()); 576a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(current->block() == block); 577a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org current->Verify(); 578a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org current = current->next(); 579a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 580a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 581a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Check that successors are correctly set. 582a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HBasicBlock* first = block->end()->FirstSuccessor(); 583a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HBasicBlock* second = block->end()->SecondSuccessor(); 584a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(second == NULL || first != NULL); 585a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 586a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Check that the predecessor array is correct. 587a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (first != NULL) { 588a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(first->predecessors()->Contains(block)); 589a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (second != NULL) { 590a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(second->predecessors()->Contains(block)); 591a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 592a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 593a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 594a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Check that phis have correct arguments. 595a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int j = 0; j < block->phis()->length(); j++) { 596a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HPhi* phi = block->phis()->at(j); 597a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org phi->Verify(); 598a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 599b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 600b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org // Check that all join blocks have predecessors that end with an 601b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org // unconditional goto and agree on their environment node id. 602b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org if (block->predecessors()->length() >= 2) { 603b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org BailoutId id = 604b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org block->predecessors()->first()->last_environment()->ast_id(); 605b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org for (int k = 0; k < block->predecessors()->length(); k++) { 606b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HBasicBlock* predecessor = block->predecessors()->at(k); 607ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ASSERT(predecessor->end()->IsGoto() || 608ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org predecessor->end()->IsDeoptimize()); 609b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org ASSERT(predecessor->last_environment()->ast_id() == id); 610b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 611b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 612a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 613a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 614a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Check special property of first block to have no predecessors. 615a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(blocks_.at(0)->predecessors()->is_empty()); 616a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 617c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (do_full_verify) { 618c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check that the graph is fully connected. 619c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ReachabilityAnalyzer analyzer(entry_block_, blocks_.length(), NULL); 620c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(analyzer.visited_count() == blocks_.length()); 621a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 622c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check that entry block dominator is NULL. 623c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(entry_block_->dominator() == NULL); 624a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 625c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check dominators. 626c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = 0; i < blocks_.length(); ++i) { 627c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HBasicBlock* block = blocks_.at(i); 628c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (block->dominator() == NULL) { 629c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Only start block may have no dominator assigned to. 630c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(i == 0); 631c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 632c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Assert that block is unreachable if dominator must not be visited. 633c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ReachabilityAnalyzer dominator_analyzer(entry_block_, 634c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com blocks_.length(), 635c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com block->dominator()); 636c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!dominator_analyzer.reachable()->Contains(block->block_id())); 637c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 638a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 639a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 640a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 641a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 642a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif 643a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 644a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 645b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.orgHConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer, 646b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org int32_t value) { 647657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org if (!pointer->is_set()) { 648d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org // Can't pass GetInvalidContext() to HConstant::New, because that will 649d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org // recursively call GetConstant 650d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HConstant* constant = HConstant::New(zone(), NULL, value); 65171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org constant->InsertAfter(entry_block()->first()); 652657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org pointer->set(constant); 65371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org return constant; 65471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org } 65571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org return ReinsertConstantIfNecessary(pointer->get()); 65671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org} 65771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org 65871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org 65971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.orgHConstant* HGraph::ReinsertConstantIfNecessary(HConstant* constant) { 66071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org if (!constant->IsLinked()) { 66171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org // The constant was removed from the graph. Reinsert. 66271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org constant->ClearFlag(HValue::kIsDead); 66371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org constant->InsertAfter(entry_block()->first()); 664657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org } 66571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org return constant; 666657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org} 667657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org 668657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org 66994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgHConstant* HGraph::GetConstant0() { 670b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org return GetConstant(&constant_0_, 0); 67194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 67294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 67394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 674a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHConstant* HGraph::GetConstant1() { 675b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org return GetConstant(&constant_1_, 1); 676a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 677a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 678a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 679a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHConstant* HGraph::GetConstantMinus1() { 680b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org return GetConstant(&constant_minus1_, -1); 681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 682a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 683a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 68429699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org#define DEFINE_GET_CONSTANT(Name, name, type, htype, boolean_value) \ 6852bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgHConstant* HGraph::GetConstant##Name() { \ 6862bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org if (!constant_##name##_.is_set()) { \ 6872bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org HConstant* constant = new(zone()) HConstant( \ 6883d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org Unique<Object>::CreateImmovable(isolate()->factory()->name##_value()), \ 68929699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org Unique<Map>::CreateImmovable(isolate()->factory()->type##_map()), \ 69029699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org false, \ 6912bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Representation::Tagged(), \ 6922bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org htype, \ 693f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org true, \ 694bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org boolean_value, \ 695e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org false, \ 696bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org ODDBALL_TYPE); \ 69771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org constant->InsertAfter(entry_block()->first()); \ 6982bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org constant_##name##_.set(constant); \ 6992bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org } \ 70071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org return ReinsertConstantIfNecessary(constant_##name##_.get()); \ 701a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 702a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 703a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 704eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.orgDEFINE_GET_CONSTANT(Undefined, undefined, undefined, HType::Undefined(), false) 70529699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.orgDEFINE_GET_CONSTANT(True, true, boolean, HType::Boolean(), true) 70629699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.orgDEFINE_GET_CONSTANT(False, false, boolean, HType::Boolean(), false) 707eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.orgDEFINE_GET_CONSTANT(Hole, the_hole, the_hole, HType::None(), false) 708eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.orgDEFINE_GET_CONSTANT(Null, null, null, HType::Null(), false) 709ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 710ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 7112bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org#undef DEFINE_GET_CONSTANT 712d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 713935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org#define DEFINE_IS_CONSTANT(Name, name) \ 714935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgbool HGraph::IsConstant##Name(HConstant* constant) { \ 715935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org return constant_##name##_.is_set() && constant == constant_##name##_.get(); \ 716935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org} 717935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgDEFINE_IS_CONSTANT(Undefined, undefined) 718935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgDEFINE_IS_CONSTANT(0, 0) 719935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgDEFINE_IS_CONSTANT(1, 1) 720935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgDEFINE_IS_CONSTANT(Minus1, minus1) 721935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgDEFINE_IS_CONSTANT(True, true) 722935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgDEFINE_IS_CONSTANT(False, false) 723935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgDEFINE_IS_CONSTANT(Hole, the_hole) 724935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgDEFINE_IS_CONSTANT(Null, null) 725935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 726935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org#undef DEFINE_IS_CONSTANT 727935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 728d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 729876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.orgHConstant* HGraph::GetInvalidContext() { 730b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org return GetConstant(&constant_invalid_context_, 0xFFFFC0C7); 731876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org} 732876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org 733876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org 734e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgbool HGraph::IsStandardConstant(HConstant* constant) { 735935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (IsConstantUndefined(constant)) return true; 736935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (IsConstant0(constant)) return true; 737935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (IsConstant1(constant)) return true; 738935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (IsConstantMinus1(constant)) return true; 739935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (IsConstantTrue(constant)) return true; 740935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (IsConstantFalse(constant)) return true; 741935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (IsConstantHole(constant)) return true; 742935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (IsConstantNull(constant)) return true; 743e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org return false; 744e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org} 745e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 746e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 74771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.orgHGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder) 74894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org : builder_(builder), 74994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org finished_(false), 750b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org did_then_(false), 7517bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org did_else_(false), 752ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org did_else_if_(false), 753b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org did_and_(false), 754b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org did_or_(false), 755b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org captured_(false), 756b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org needs_compare_(true), 757ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org pending_merge_block_(false), 758c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org split_edge_merge_block_(NULL), 759ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org merge_at_join_blocks_(NULL), 760ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org normal_merge_at_join_block_count_(0), 761ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org deopt_merge_at_join_block_count_(0) { 76294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org HEnvironment* env = builder->environment(); 763b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org first_true_block_ = builder->CreateBasicBlock(env->Copy()); 764b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org first_false_block_ = builder->CreateBasicBlock(env->Copy()); 76594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 76694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 76794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 768b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgHGraphBuilder::IfBuilder::IfBuilder( 769b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HGraphBuilder* builder, 770b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HIfContinuation* continuation) 771b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org : builder_(builder), 772b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org finished_(false), 773b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org did_then_(false), 774b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org did_else_(false), 775ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org did_else_if_(false), 776b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org did_and_(false), 777b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org did_or_(false), 778b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org captured_(false), 779b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org needs_compare_(false), 780ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org pending_merge_block_(false), 781b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org first_true_block_(NULL), 782b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org first_false_block_(NULL), 783b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org split_edge_merge_block_(NULL), 784ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org merge_at_join_blocks_(NULL), 785ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org normal_merge_at_join_block_count_(0), 786ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org deopt_merge_at_join_block_count_(0) { 787b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org continuation->Continue(&first_true_block_, 78871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org &first_false_block_); 789b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org} 790b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 791b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 792528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgHControlInstruction* HGraphBuilder::IfBuilder::AddCompare( 793528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org HControlInstruction* compare) { 794ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ASSERT(did_then_ == did_else_); 795ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (did_else_) { 796ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // Handle if-then-elseif 797ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org did_else_if_ = true; 798ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org did_else_ = false; 799ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org did_then_ = false; 800ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org did_and_ = false; 801ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org did_or_ = false; 802ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org pending_merge_block_ = false; 803ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org split_edge_merge_block_ = NULL; 804ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HEnvironment* env = builder_->environment(); 805ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org first_true_block_ = builder_->CreateBasicBlock(env->Copy()); 806ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org first_false_block_ = builder_->CreateBasicBlock(env->Copy()); 807ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 808b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org if (split_edge_merge_block_ != NULL) { 809b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HEnvironment* env = first_false_block_->last_environment(); 810b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HBasicBlock* split_edge = 811b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org builder_->CreateBasicBlock(env->Copy()); 812b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org if (did_or_) { 813b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org compare->SetSuccessorAt(0, split_edge); 814b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org compare->SetSuccessorAt(1, first_false_block_); 815b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } else { 816b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org compare->SetSuccessorAt(0, first_true_block_); 817b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org compare->SetSuccessorAt(1, split_edge); 818b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 81971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org builder_->GotoNoSimulate(split_edge, split_edge_merge_block_); 820b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } else { 821b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org compare->SetSuccessorAt(0, first_true_block_); 822b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org compare->SetSuccessorAt(1, first_false_block_); 823b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 82471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org builder_->FinishCurrentBlock(compare); 825b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org needs_compare_ = false; 826528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return compare; 827b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org} 828b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 829b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 830b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid HGraphBuilder::IfBuilder::Or() { 831db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org ASSERT(!needs_compare_); 832b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org ASSERT(!did_and_); 833b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org did_or_ = true; 834b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HEnvironment* env = first_false_block_->last_environment(); 835b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org if (split_edge_merge_block_ == NULL) { 836b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org split_edge_merge_block_ = 837b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org builder_->CreateBasicBlock(env->Copy()); 83871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org builder_->GotoNoSimulate(first_true_block_, split_edge_merge_block_); 839b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org first_true_block_ = split_edge_merge_block_; 840b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 841b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org builder_->set_current_block(first_false_block_); 842b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org first_false_block_ = builder_->CreateBasicBlock(env->Copy()); 843b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org} 844b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 845b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 846b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid HGraphBuilder::IfBuilder::And() { 847db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org ASSERT(!needs_compare_); 848b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org ASSERT(!did_or_); 849b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org did_and_ = true; 850b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HEnvironment* env = first_false_block_->last_environment(); 851b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org if (split_edge_merge_block_ == NULL) { 852b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org split_edge_merge_block_ = builder_->CreateBasicBlock(env->Copy()); 85371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org builder_->GotoNoSimulate(first_false_block_, split_edge_merge_block_); 854b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org first_false_block_ = split_edge_merge_block_; 855b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 856b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org builder_->set_current_block(first_true_block_); 857b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org first_true_block_ = builder_->CreateBasicBlock(env->Copy()); 858b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org} 859b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 860b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 861b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid HGraphBuilder::IfBuilder::CaptureContinuation( 862b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HIfContinuation* continuation) { 863ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ASSERT(!did_else_if_); 864b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org ASSERT(!finished_); 865b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org ASSERT(!captured_); 866ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 867ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HBasicBlock* true_block = NULL; 868ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HBasicBlock* false_block = NULL; 869ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Finish(&true_block, &false_block); 870ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ASSERT(true_block != NULL); 871ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ASSERT(false_block != NULL); 87271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org continuation->Capture(true_block, false_block); 873b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org captured_ = true; 874ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org builder_->set_current_block(NULL); 875b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org End(); 876b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org} 877b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 878b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 879528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) { 880ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ASSERT(!did_else_if_); 881528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org ASSERT(!finished_); 882528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org ASSERT(!captured_); 883ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HBasicBlock* true_block = NULL; 884ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HBasicBlock* false_block = NULL; 885ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Finish(&true_block, &false_block); 886ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org merge_at_join_blocks_ = NULL; 887528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (true_block != NULL && !true_block->IsFinished()) { 888528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org ASSERT(continuation->IsTrueReachable()); 88971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org builder_->GotoNoSimulate(true_block, continuation->true_branch()); 890528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 891528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (false_block != NULL && !false_block->IsFinished()) { 892528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org ASSERT(continuation->IsFalseReachable()); 89371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org builder_->GotoNoSimulate(false_block, continuation->false_branch()); 894528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 895528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org captured_ = true; 896528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org End(); 897528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 898528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 899528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 900b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid HGraphBuilder::IfBuilder::Then() { 901b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org ASSERT(!captured_); 902b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org ASSERT(!finished_); 903b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org did_then_ = true; 904b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org if (needs_compare_) { 905b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org // Handle if's without any expressions, they jump directly to the "else" 906d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org // branch. However, we must pretend that the "then" branch is reachable, 907d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org // so that the graph builder visits it and sees any live range extending 908d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org // constructs within it. 909d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org HConstant* constant_false = builder_->graph()->GetConstantFalse(); 9101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ToBooleanStub::Types boolean_type = ToBooleanStub::Types(); 911d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org boolean_type.Add(ToBooleanStub::BOOLEAN); 912528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org HBranch* branch = builder()->New<HBranch>( 913528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org constant_false, boolean_type, first_true_block_, first_false_block_); 91471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org builder_->FinishCurrentBlock(branch); 915b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 9167bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org builder_->set_current_block(first_true_block_); 917ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org pending_merge_block_ = true; 9187bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org} 9197bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 9207bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 921b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid HGraphBuilder::IfBuilder::Else() { 922b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org ASSERT(did_then_); 923b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org ASSERT(!captured_); 924b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org ASSERT(!finished_); 925ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org AddMergeAtJoinBlock(false); 92609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org builder_->set_current_block(first_false_block_); 927ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org pending_merge_block_ = true; 9287bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org did_else_ = true; 92994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 93094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 93194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 932594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid HGraphBuilder::IfBuilder::Deopt(const char* reason) { 933c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org ASSERT(did_then_); 934594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org builder_->Add<HDeoptimize>(reason, Deoptimizer::EAGER); 935ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org AddMergeAtJoinBlock(true); 936b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org} 937b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 938b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 939ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvoid HGraphBuilder::IfBuilder::Return(HValue* value) { 940b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org HValue* parameter_count = builder_->graph()->GetConstantMinus1(); 94171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org builder_->FinishExitCurrentBlock( 94271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org builder_->New<HReturn>(value, parameter_count)); 943ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org AddMergeAtJoinBlock(false); 944ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org} 945ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 946ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 947ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgvoid HGraphBuilder::IfBuilder::AddMergeAtJoinBlock(bool deopt) { 948ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (!pending_merge_block_) return; 949ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HBasicBlock* block = builder_->current_block(); 950ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ASSERT(block == NULL || !block->IsFinished()); 951ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org MergeAtJoinBlock* record = 952ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org new(builder_->zone()) MergeAtJoinBlock(block, deopt, 953ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org merge_at_join_blocks_); 954ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org merge_at_join_blocks_ = record; 955ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (block != NULL) { 956ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ASSERT(block->end() == NULL); 957ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (deopt) { 958ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org normal_merge_at_join_block_count_++; 959ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } else { 960ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org deopt_merge_at_join_block_count_++; 961ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 962ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 963ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org builder_->set_current_block(NULL); 964ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org pending_merge_block_ = false; 965ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org} 966ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 967ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 968ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgvoid HGraphBuilder::IfBuilder::Finish() { 969ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ASSERT(!finished_); 970ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (!did_then_) { 971ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Then(); 972ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 973ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org AddMergeAtJoinBlock(false); 974ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (!did_else_) { 975ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Else(); 976ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org AddMergeAtJoinBlock(false); 977ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 978ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org finished_ = true; 979ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org} 980ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 981ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 982ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgvoid HGraphBuilder::IfBuilder::Finish(HBasicBlock** then_continuation, 983ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HBasicBlock** else_continuation) { 984ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Finish(); 985ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 986ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org MergeAtJoinBlock* else_record = merge_at_join_blocks_; 987ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (else_continuation != NULL) { 988ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org *else_continuation = else_record->block_; 989ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 990ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org MergeAtJoinBlock* then_record = else_record->next_; 991ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (then_continuation != NULL) { 992ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org *then_continuation = then_record->block_; 993ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 994ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ASSERT(then_record->next_ == NULL); 995ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 996ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 997ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 99894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid HGraphBuilder::IfBuilder::End() { 999ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (captured_) return; 1000ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Finish(); 1001ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1002ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org int total_merged_blocks = normal_merge_at_join_block_count_ + 1003ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org deopt_merge_at_join_block_count_; 1004ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ASSERT(total_merged_blocks >= 1); 1005ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HBasicBlock* merge_block = total_merged_blocks == 1 1006ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ? NULL : builder_->graph()->CreateBasicBlock(); 1007ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1008ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // Merge non-deopt blocks first to ensure environment has right size for 1009ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // padding. 1010ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org MergeAtJoinBlock* current = merge_at_join_blocks_; 1011ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org while (current != NULL) { 1012ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (!current->deopt_ && current->block_ != NULL) { 1013ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // If there is only one block that makes it through to the end of the 1014ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // if, then just set it as the current block and continue rather then 1015ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // creating an unnecessary merge block. 1016ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (total_merged_blocks == 1) { 1017ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org builder_->set_current_block(current->block_); 1018ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org return; 1019c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } 1020ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org builder_->GotoNoSimulate(current->block_, merge_block); 1021b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 1022ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org current = current->next_; 1023b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 1024ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1025ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // Merge deopt blocks, padding when necessary. 1026ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org current = merge_at_join_blocks_; 1027ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org while (current != NULL) { 1028ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (current->deopt_ && current->block_ != NULL) { 1029f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org current->block_->FinishExit( 1030f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HAbnormalExit::New(builder_->zone(), NULL), 1031f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HSourcePosition::Unknown()); 1032ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 1033ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org current = current->next_; 1034ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 1035ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org builder_->set_current_block(merge_block); 103694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 103794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 103894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 103994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgHGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, 104094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org HValue* context, 10412d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org LoopBuilder::Direction direction) 104294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org : builder_(builder), 104394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org context_(context), 104494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org direction_(direction), 104594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org finished_(false) { 1046b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org header_block_ = builder->CreateLoopHeaderBlock(); 104709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org body_block_ = NULL; 104809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org exit_block_ = NULL; 1049662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org exit_trampoline_block_ = NULL; 1050662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org increment_amount_ = builder_->graph()->GetConstant1(); 1051662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org} 1052662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 1053662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 1054662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgHGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, 1055662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org HValue* context, 1056662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org LoopBuilder::Direction direction, 1057662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org HValue* increment_amount) 1058662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org : builder_(builder), 1059662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org context_(context), 1060662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org direction_(direction), 1061662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org finished_(false) { 1062662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org header_block_ = builder->CreateLoopHeaderBlock(); 1063662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org body_block_ = NULL; 1064662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org exit_block_ = NULL; 1065662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org exit_trampoline_block_ = NULL; 1066662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org increment_amount_ = increment_amount; 106794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 106894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 106994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 107009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.orgHValue* HGraphBuilder::LoopBuilder::BeginBody( 107109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org HValue* initial, 107209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org HValue* terminating, 1073dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org Token::Value token) { 107409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org HEnvironment* env = builder_->environment(); 1075ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org phi_ = header_block_->AddNewPhi(env->values()->length()); 107694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org phi_->AddInput(initial); 107794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org env->Push(initial); 107871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org builder_->GotoNoSimulate(header_block_); 107909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org 108009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org HEnvironment* body_env = env->Copy(); 108109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org HEnvironment* exit_env = env->Copy(); 108209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org // Remove the phi from the expression stack 108309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org body_env->Pop(); 1084662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org exit_env->Pop(); 1085662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org body_block_ = builder_->CreateBasicBlock(body_env); 1086662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org exit_block_ = builder_->CreateBasicBlock(exit_env); 108794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 108894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org builder_->set_current_block(header_block_); 1089662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org env->Pop(); 109071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org builder_->FinishCurrentBlock(builder_->New<HCompareNumericAndBranch>( 1091528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org phi_, terminating, token, body_block_, exit_block_)); 109294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 109394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org builder_->set_current_block(body_block_); 109494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (direction_ == kPreIncrement || direction_ == kPreDecrement) { 109594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org HValue* one = builder_->graph()->GetConstant1(); 109694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (direction_ == kPreIncrement) { 10972e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org increment_ = HAdd::New(zone(), context_, phi_, one); 109894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } else { 10992e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org increment_ = HSub::New(zone(), context_, phi_, one); 110094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 110194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org increment_->ClearFlag(HValue::kCanOverflow); 110294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org builder_->AddInstruction(increment_); 110394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org return increment_; 110494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } else { 110594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org return phi_; 110694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 110794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 110894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 110994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 1110662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgvoid HGraphBuilder::LoopBuilder::Break() { 1111662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org if (exit_trampoline_block_ == NULL) { 1112662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // Its the first time we saw a break. 1113662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org HEnvironment* env = exit_block_->last_environment()->Copy(); 1114662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org exit_trampoline_block_ = builder_->CreateBasicBlock(env); 111571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org builder_->GotoNoSimulate(exit_block_, exit_trampoline_block_); 1116662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } 1117662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 111871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org builder_->GotoNoSimulate(exit_trampoline_block_); 1119ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org builder_->set_current_block(NULL); 1120662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org} 1121662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 1122662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 112394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid HGraphBuilder::LoopBuilder::EndBody() { 112494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ASSERT(!finished_); 112594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 112694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (direction_ == kPostIncrement || direction_ == kPostDecrement) { 112794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (direction_ == kPostIncrement) { 1128662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org increment_ = HAdd::New(zone(), context_, phi_, increment_amount_); 112994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } else { 1130662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org increment_ = HSub::New(zone(), context_, phi_, increment_amount_); 113194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 113294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org increment_->ClearFlag(HValue::kCanOverflow); 113394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org builder_->AddInstruction(increment_); 113494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 113594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 113609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org // Push the new increment value on the expression stack to merge into the phi. 113794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org builder_->environment()->Push(increment_); 1138594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org HBasicBlock* last_block = builder_->current_block(); 113971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org builder_->GotoNoSimulate(last_block, header_block_); 1140594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org header_block_->loop_information()->RegisterBackEdge(last_block); 114109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org 1142662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org if (exit_trampoline_block_ != NULL) { 1143662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org builder_->set_current_block(exit_trampoline_block_); 1144662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } else { 1145662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org builder_->set_current_block(exit_block_); 1146662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } 114794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org finished_ = true; 114894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 114994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 115094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 1151a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHGraph* HGraphBuilder::CreateGraph() { 1152a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org graph_ = new(zone()) HGraph(info_); 1153750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_); 11541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org CompilationPhase phase("H_Block building", info_); 1155a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org set_current_block(graph()->entry_block()); 1156a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (!BuildGraph()) return NULL; 11573d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org graph()->FinalizeUniqueness(); 1158a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return graph_; 1159a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 1160a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1161a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1162a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { 1163a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(current_block() != NULL); 1164f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ASSERT(!FLAG_hydrogen_track_positions || 1165f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org !position_.IsUnknown() || 1166f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org !info_->IsOptimizing()); 1167f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org current_block()->AddInstruction(instr, source_position()); 1168ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org if (graph()->IsInsideNoSideEffectsScope()) { 1169e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org instr->SetFlag(HValue::kHasNoObservableSideEffects); 1170e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 1171a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return instr; 1172a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 1173a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1174a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 117571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.orgvoid HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) { 1176f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ASSERT(!FLAG_hydrogen_track_positions || 1177f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org !info_->IsOptimizing() || 1178f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org !position_.IsUnknown()); 1179f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org current_block()->Finish(last, source_position()); 118071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org if (last->IsReturn() || last->IsAbnormalExit()) { 118171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org set_current_block(NULL); 118271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org } 118371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org} 118471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org 118571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org 118671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.orgvoid HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) { 1187f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ASSERT(!FLAG_hydrogen_track_positions || !info_->IsOptimizing() || 1188f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org !position_.IsUnknown()); 1189f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org current_block()->FinishExit(instruction, source_position()); 119071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org if (instruction->IsReturn() || instruction->IsAbnormalExit()) { 119171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org set_current_block(NULL); 119271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org } 119371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org} 119471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org 119571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org 1196528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { 1197d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (FLAG_native_code_counters && counter->Enabled()) { 1198d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HValue* reference = Add<HConstant>(ExternalReference(counter)); 119909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* old_value = Add<HLoadNamedField>( 120009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org reference, static_cast<HValue*>(NULL), HObjectAccess::ForCounter()); 1201f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1()); 1202d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow 1203d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), 120405150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org new_value, STORE_TO_INITIALIZED_ENTRY); 1205d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 1206d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 1207d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 1208d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 1209d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgvoid HGraphBuilder::AddSimulate(BailoutId id, 1210d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org RemovableSimulate removable) { 1211d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ASSERT(current_block() != NULL); 1212ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org ASSERT(!graph()->IsInsideNoSideEffectsScope()); 1213f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org current_block()->AddNewSimulate(id, source_position(), removable); 1214d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 1215d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 1216d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 1217b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgHBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { 121894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org HBasicBlock* b = graph()->CreateBasicBlock(); 1219b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org b->SetInitialEnvironment(env); 122094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org return b; 122194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 122294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 122394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 1224b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgHBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { 122594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org HBasicBlock* header = graph()->CreateBasicBlock(); 122694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); 1227b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org header->SetInitialEnvironment(entry_env); 122894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org header->AttachLoopInformation(); 122994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org return header; 123094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 123194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 123294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 12331845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgHValue* HGraphBuilder::BuildGetElementsKind(HValue* object) { 12341845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* map = Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), 12351845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HObjectAccess::ForMap()); 12361845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 12371845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* bit_field2 = Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), 12381845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HObjectAccess::ForMapBitField2()); 12391845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org return BuildDecodeField<Map::ElementsKindBits>(bit_field2); 12401845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org} 12411845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 12421845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 12431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgHValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { 1244906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (obj->type().IsHeapObject()) return obj; 12451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return Add<HCheckHeapObject>(obj); 1246b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org} 1247b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 1248b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 1249f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid HGraphBuilder::FinishExitWithHardDeoptimization(const char* reason) { 1250594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Add<HDeoptimize>(reason, Deoptimizer::EAGER); 1251f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org FinishExitCurrentBlock(New<HAbnormalExit>()); 1252c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org} 1253c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 1254c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 125590dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.orgHValue* HGraphBuilder::BuildCheckString(HValue* string) { 125690dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org if (!string->type().IsString()) { 125790dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org ASSERT(!string->IsConstant() || 125890dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org !HConstant::cast(string)->HasStringValue()); 125990dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org BuildCheckHeapObject(string); 126090dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org return Add<HCheckInstanceType>(string, HCheckInstanceType::IS_STRING); 12617ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org } 126290dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org return string; 12637ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org} 12647ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 12657ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 1266c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgHValue* HGraphBuilder::BuildWrapReceiver(HValue* object, HValue* function) { 1267c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (object->type().IsJSObject()) return object; 126857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (function->IsConstant() && 126957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HConstant::cast(function)->handle(isolate())->IsJSFunction()) { 127057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Handle<JSFunction> f = Handle<JSFunction>::cast( 127157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HConstant::cast(function)->handle(isolate())); 127257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org SharedFunctionInfo* shared = f->shared(); 1273486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (shared->strict_mode() == STRICT || shared->native()) return object; 127457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } 1275c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org return Add<HWrapReceiver>(object, function); 1276c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org} 1277c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 1278c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 1279f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgHValue* HGraphBuilder::BuildCheckForCapacityGrow( 1280f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HValue* object, 1281f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HValue* elements, 1282f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ElementsKind kind, 1283f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HValue* length, 1284f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HValue* key, 1285f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool is_js_array, 1286f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PropertyAccessType access_type) { 12872d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org IfBuilder length_checker(this); 12887bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 1289169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ; 1290169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org length_checker.If<HCompareNumericAndBranch>(key, length, token); 1291169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 1292b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org length_checker.Then(); 12937bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 1294c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org HValue* current_capacity = AddLoadFixedArrayLength(elements); 12957bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 12962d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org IfBuilder capacity_checker(this); 12977bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 1298169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity, 1299169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org Token::GTE); 1300b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org capacity_checker.Then(); 13017bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 1302d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap)); 13037ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HValue* max_capacity = AddUncasted<HAdd>(current_capacity, max_gap); 1304a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org 1305a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Add<HBoundsCheck>(key, max_capacity); 1306c22f2d813ad21e25e8df5d4a371fd63f582e4262danno@chromium.org 1307d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HValue* new_capacity = BuildNewElementsCapacity(key); 13087bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org HValue* new_elements = BuildGrowElementsCapacity(object, elements, 1309bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org kind, kind, length, 13102d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org new_capacity); 13117bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 13127bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org environment()->Push(new_elements); 1313b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org capacity_checker.Else(); 13147bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 13157bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org environment()->Push(elements); 13167bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org capacity_checker.End(); 13177bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 13187bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org if (is_js_array) { 1319db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HValue* new_length = AddUncasted<HAdd>(key, graph_->GetConstant1()); 13207bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org new_length->ClearFlag(HValue::kCanOverflow); 13217bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 1322d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind), 13230a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org new_length); 13247bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org } 13257bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 1326f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (access_type == STORE && kind == FAST_SMI_ELEMENTS) { 132771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org HValue* checked_elements = environment()->Top(); 132871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 132971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org // Write zero to ensure that the new element is initialized with some smi. 13300a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HStoreKeyed>(checked_elements, key, graph()->GetConstant0(), kind); 133171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } 133271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 1333b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org length_checker.Else(); 13341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Add<HBoundsCheck>(key, length); 13357bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 1336169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org environment()->Push(elements); 13377bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org length_checker.End(); 13387bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 13397bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org return environment()->Pop(); 13407bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org} 13417bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 13427bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 13437bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgHValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, 13447bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org HValue* elements, 13457bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org ElementsKind kind, 13467bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org HValue* length) { 1347e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org Factory* factory = isolate()->factory(); 13487bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 13492d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org IfBuilder cow_checker(this); 13507bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 1351052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org cow_checker.If<HCompareMap>(elements, factory->fixed_cow_array_map()); 1352b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org cow_checker.Then(); 13537bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 1354c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org HValue* capacity = AddLoadFixedArrayLength(elements); 13557bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 1356bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HValue* new_elements = BuildGrowElementsCapacity(object, elements, kind, 1357b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org kind, length, capacity); 13587bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 13597bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org environment()->Push(new_elements); 13607bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 1361b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org cow_checker.Else(); 13627bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 13637bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org environment()->Push(elements); 13647bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 13657bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org cow_checker.End(); 13667bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 13677bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org return environment()->Pop(); 13687bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org} 13697bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 13707bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 1371ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgvoid HGraphBuilder::BuildTransitionElementsKind(HValue* object, 1372ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HValue* map, 1373ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ElementsKind from_kind, 1374ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ElementsKind to_kind, 1375ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org bool is_jsarray) { 1376ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ASSERT(!IsFastHoleyElementsKind(from_kind) || 1377ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org IsFastHoleyElementsKind(to_kind)); 1378ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 1379ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) { 1380ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Add<HTrapAllocationMemento>(object); 1381ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 1382ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 1383ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if (!IsSimpleMapChangeTransition(from_kind, to_kind)) { 1384ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org HInstruction* elements = AddLoadElements(object); 1385ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 1386ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HInstruction* empty_fixed_array = Add<HConstant>( 1387d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org isolate()->factory()->empty_fixed_array()); 1388ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 1389ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org IfBuilder if_builder(this); 1390ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 1391ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array); 1392ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 1393ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if_builder.Then(); 1394ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 1395ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HInstruction* elements_length = AddLoadFixedArrayLength(elements); 1396ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 1397ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HInstruction* array_length = is_jsarray 139809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org ? Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), 139909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HObjectAccess::ForArrayLength(from_kind)) 1400ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org : elements_length; 1401ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 1402ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org BuildGrowElementsCapacity(object, elements, from_kind, to_kind, 1403ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org array_length, elements_length); 1404ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 1405ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if_builder.End(); 1406ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 1407ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 14080a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map); 1409ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org} 1410ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 1411ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 14121845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgvoid HGraphBuilder::BuildJSObjectCheck(HValue* receiver, 14131845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org int bit_field_mask) { 14141845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // Check that the object isn't a smi. 14151845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Add<HCheckHeapObject>(receiver); 14161845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 14171845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // Get the map of the receiver. 14181845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), 14191845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HObjectAccess::ForMap()); 14201845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 14211845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // Check the instance type and if an access check is needed, this can be 14221845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // done with a single load, since both bytes are adjacent in the map. 14231845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HObjectAccess access(HObjectAccess::ForMapInstanceTypeAndBitField()); 14241845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* instance_type_and_bit_field = 14251845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), access); 14261845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 14271845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* mask = Add<HConstant>(0x00FF | (bit_field_mask << 8)); 14281845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* and_result = AddUncasted<HBitwise>(Token::BIT_AND, 14291845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org instance_type_and_bit_field, 14301845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org mask); 14311845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* sub_result = AddUncasted<HSub>(and_result, 14321845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Add<HConstant>(JS_OBJECT_TYPE)); 14331845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Add<HBoundsCheck>(sub_result, Add<HConstant>(0x100 - JS_OBJECT_TYPE)); 14341845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org} 14351845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 14361845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 14371845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgvoid HGraphBuilder::BuildKeyedIndexCheck(HValue* key, 14381845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HIfContinuation* join_continuation) { 14391845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // The sometimes unintuitively backward ordering of the ifs below is 14401845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // convoluted, but necessary. All of the paths must guarantee that the 14411845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // if-true of the continuation returns a smi element index and the if-false of 14421845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // the continuation returns either a symbol or a unique string key. All other 14431845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // object types cause a deopt to fall back to the runtime. 14441845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 14451845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org IfBuilder key_smi_if(this); 14461845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org key_smi_if.If<HIsSmiAndBranch>(key); 14471845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org key_smi_if.Then(); 14481845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org { 14491845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Push(key); // Nothing to do, just continue to true of continuation. 14501845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org } 14511845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org key_smi_if.Else(); 14521845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org { 14531845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* map = Add<HLoadNamedField>(key, static_cast<HValue*>(NULL), 14541845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HObjectAccess::ForMap()); 14551845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* instance_type = 14561845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), 14571845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HObjectAccess::ForMapInstanceType()); 14581845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 14591845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // Non-unique string, check for a string with a hash code that is actually 14601845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // an index. 14611845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org STATIC_ASSERT(LAST_UNIQUE_NAME_TYPE == FIRST_NONSTRING_TYPE); 14621845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org IfBuilder not_string_or_name_if(this); 14631845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org not_string_or_name_if.If<HCompareNumericAndBranch>( 14641845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org instance_type, 14651845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Add<HConstant>(LAST_UNIQUE_NAME_TYPE), 14661845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Token::GT); 14671845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 14681845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org not_string_or_name_if.Then(); 14691845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org { 14701845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // Non-smi, non-Name, non-String: Try to convert to smi in case of 14711845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // HeapNumber. 14721845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // TODO(danno): This could call some variant of ToString 14731845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Push(AddUncasted<HForceRepresentation>(key, Representation::Smi())); 14741845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org } 14751845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org not_string_or_name_if.Else(); 14761845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org { 14771845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // String or Name: check explicitly for Name, they can short-circuit 14781845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // directly to unique non-index key path. 14791845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org IfBuilder not_symbol_if(this); 14801845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org not_symbol_if.If<HCompareNumericAndBranch>( 14811845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org instance_type, 14821845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Add<HConstant>(SYMBOL_TYPE), 14831845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Token::NE); 14841845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 14851845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org not_symbol_if.Then(); 14861845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org { 14871845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // String: check whether the String is a String of an index. If it is, 14881845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // extract the index value from the hash. 14891845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* hash = 14901845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Add<HLoadNamedField>(key, static_cast<HValue*>(NULL), 14911845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HObjectAccess::ForNameHashField()); 14921845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* not_index_mask = Add<HConstant>(static_cast<int>( 14931845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org String::kContainsCachedArrayIndexMask)); 14941845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 14951845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* not_index_test = AddUncasted<HBitwise>( 14961845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Token::BIT_AND, hash, not_index_mask); 14971845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 14981845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org IfBuilder string_index_if(this); 14991845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org string_index_if.If<HCompareNumericAndBranch>(not_index_test, 15001845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org graph()->GetConstant0(), 15011845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Token::EQ); 15021845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org string_index_if.Then(); 15031845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org { 15041845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // String with index in hash: extract string and merge to index path. 15051845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Push(BuildDecodeField<String::ArrayIndexValueBits>(hash)); 15061845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org } 15071845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org string_index_if.Else(); 15081845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org { 15091845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // Key is a non-index String, check for uniqueness/internalization. If 15101845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // it's not, deopt. 15111845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* not_internalized_bit = AddUncasted<HBitwise>( 15121845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Token::BIT_AND, 15131845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org instance_type, 15141845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Add<HConstant>(static_cast<int>(kIsNotInternalizedMask))); 15151845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org DeoptimizeIf<HCompareNumericAndBranch>( 15161845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org not_internalized_bit, 15171845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org graph()->GetConstant0(), 15181845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Token::NE, 15191845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org "BuildKeyedIndexCheck: string isn't internalized"); 15201845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // Key guaranteed to be a unqiue string 15211845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Push(key); 15221845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org } 15231845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org string_index_if.JoinContinuation(join_continuation); 15241845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org } 15251845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org not_symbol_if.Else(); 15261845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org { 15271845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Push(key); // Key is symbol 15281845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org } 15291845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org not_symbol_if.JoinContinuation(join_continuation); 15301845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org } 15311845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org not_string_or_name_if.JoinContinuation(join_continuation); 15321845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org } 15331845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org key_smi_if.JoinContinuation(join_continuation); 15341845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org} 15351845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 15361845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 15371845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgvoid HGraphBuilder::BuildNonGlobalObjectCheck(HValue* receiver) { 15381845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // Get the the instance type of the receiver, and make sure that it is 15391845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // not one of the global object types. 15401845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), 15411845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HObjectAccess::ForMap()); 15421845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* instance_type = 15431845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), 15441845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HObjectAccess::ForMapInstanceType()); 15451845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org STATIC_ASSERT(JS_BUILTINS_OBJECT_TYPE == JS_GLOBAL_OBJECT_TYPE + 1); 15461845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* min_global_type = Add<HConstant>(JS_GLOBAL_OBJECT_TYPE); 15471845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* max_global_type = Add<HConstant>(JS_BUILTINS_OBJECT_TYPE); 15481845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 15491845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org IfBuilder if_global_object(this); 15501845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org if_global_object.If<HCompareNumericAndBranch>(instance_type, 15511845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org max_global_type, 15521845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Token::LTE); 15531845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org if_global_object.And(); 15541845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org if_global_object.If<HCompareNumericAndBranch>(instance_type, 15551845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org min_global_type, 15561845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Token::GTE); 15571845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org if_global_object.ThenDeopt("receiver was a global object"); 15581845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org if_global_object.End(); 15591845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org} 15601845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 15611845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 15621845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgvoid HGraphBuilder::BuildTestForDictionaryProperties( 15631845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* object, 15641845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HIfContinuation* continuation) { 15651845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* properties = Add<HLoadNamedField>( 15661845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org object, static_cast<HValue*>(NULL), 15671845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HObjectAccess::ForPropertiesPointer()); 15681845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* properties_map = 15691845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Add<HLoadNamedField>(properties, static_cast<HValue*>(NULL), 15701845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HObjectAccess::ForMap()); 15711845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* hash_map = Add<HLoadRoot>(Heap::kHashTableMapRootIndex); 15721845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org IfBuilder builder(this); 15731845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org builder.If<HCompareObjectEqAndBranch>(properties_map, hash_map); 15741845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org builder.CaptureContinuation(continuation); 15751845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org} 15761845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 15771845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 15781845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgHValue* HGraphBuilder::BuildKeyedLookupCacheHash(HValue* object, 15791845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* key) { 15801845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // Load the map of the receiver, compute the keyed lookup cache hash 15811845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // based on 32 bits of the map pointer and the string hash. 15821845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* object_map = 15831845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), 15841845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HObjectAccess::ForMapAsInteger32()); 15851845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* shifted_map = AddUncasted<HShr>( 15861845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org object_map, Add<HConstant>(KeyedLookupCache::kMapHashShift)); 15871845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* string_hash = 15881845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Add<HLoadNamedField>(key, static_cast<HValue*>(NULL), 15891845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HObjectAccess::ForStringHashField()); 15901845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* shifted_hash = AddUncasted<HShr>( 15911845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org string_hash, Add<HConstant>(String::kHashShift)); 15921845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* xor_result = AddUncasted<HBitwise>(Token::BIT_XOR, shifted_map, 15931845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org shifted_hash); 15941845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask); 15951845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org return AddUncasted<HBitwise>(Token::BIT_AND, xor_result, 15961845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Add<HConstant>(mask)); 15971845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org} 15981845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 15991845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 1600ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgHValue* HGraphBuilder::BuildUncheckedDictionaryElementLoadHelper( 1601ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HValue* elements, 1602ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HValue* key, 1603ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HValue* hash, 1604ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HValue* mask, 1605ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org int current_probe) { 1606ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (current_probe == kNumberDictionaryProbes) { 1607ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org return NULL; 1608ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 1609ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1610ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org int32_t offset = SeededNumberDictionary::GetProbeOffset(current_probe); 1611ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HValue* raw_index = (current_probe == 0) 1612ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ? hash 16137ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org : AddUncasted<HAdd>(hash, Add<HConstant>(offset)); 16147ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org raw_index = AddUncasted<HBitwise>(Token::BIT_AND, raw_index, mask); 1615ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org int32_t entry_size = SeededNumberDictionary::kEntrySize; 16167ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org raw_index = AddUncasted<HMul>(raw_index, Add<HConstant>(entry_size)); 1617ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org raw_index->ClearFlag(HValue::kCanOverflow); 1618ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1619ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org int32_t base_offset = SeededNumberDictionary::kElementsStartIndex; 16207ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HValue* key_index = AddUncasted<HAdd>(raw_index, Add<HConstant>(base_offset)); 1621ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org key_index->ClearFlag(HValue::kCanOverflow); 1622ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1623ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HValue* candidate_key = Add<HLoadKeyed>(elements, key_index, 1624ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org static_cast<HValue*>(NULL), 1625f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org FAST_ELEMENTS); 1626ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1627ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org IfBuilder key_compare(this); 1628ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org key_compare.IfNot<HCompareObjectEqAndBranch>(key, candidate_key); 1629ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org key_compare.Then(); 1630ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org { 1631ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // Key at the current probe doesn't match, try at the next probe. 1632ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HValue* result = BuildUncheckedDictionaryElementLoadHelper( 1633ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org elements, key, hash, mask, current_probe + 1); 1634ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (result == NULL) { 1635ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org key_compare.Deopt("probes exhausted in keyed load dictionary lookup"); 1636ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org result = graph()->GetConstantUndefined(); 1637ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } else { 1638ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Push(result); 1639ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 1640ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 1641ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org key_compare.Else(); 1642ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org { 1643ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // Key at current probe matches. Details must be zero, otherwise the 1644ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // dictionary element requires special handling. 16457ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HValue* details_index = AddUncasted<HAdd>( 16467ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org raw_index, Add<HConstant>(base_offset + 2)); 1647ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org details_index->ClearFlag(HValue::kCanOverflow); 1648ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1649ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HValue* details = Add<HLoadKeyed>(elements, details_index, 1650ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org static_cast<HValue*>(NULL), 1651f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org FAST_ELEMENTS); 1652ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org IfBuilder details_compare(this); 1653ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org details_compare.If<HCompareNumericAndBranch>(details, 1654ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org graph()->GetConstant0(), 1655ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Token::NE); 1656ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org details_compare.ThenDeopt("keyed load dictionary element not fast case"); 1657ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1658ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org details_compare.Else(); 1659ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org { 1660ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // Key matches and details are zero --> fast case. Load and return the 1661ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // value. 16627ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HValue* result_index = AddUncasted<HAdd>( 16637ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org raw_index, Add<HConstant>(base_offset + 1)); 1664ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org result_index->ClearFlag(HValue::kCanOverflow); 1665ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1666ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Push(Add<HLoadKeyed>(elements, result_index, 1667ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org static_cast<HValue*>(NULL), 1668ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org FAST_ELEMENTS)); 1669ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 1670ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org details_compare.End(); 1671ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 1672ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org key_compare.End(); 1673ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1674ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org return Pop(); 1675ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org} 1676ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1677ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1678ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgHValue* HGraphBuilder::BuildElementIndexHash(HValue* index) { 1679ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org int32_t seed_value = static_cast<uint32_t>(isolate()->heap()->HashSeed()); 1680ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HValue* seed = Add<HConstant>(seed_value); 16817ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, index, seed); 1682ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1683ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // hash = ~hash + (hash << 15); 16847ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HValue* shifted_hash = AddUncasted<HShl>(hash, Add<HConstant>(15)); 16857ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HValue* not_hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash, 16867ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org graph()->GetConstantMinus1()); 16877ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org hash = AddUncasted<HAdd>(shifted_hash, not_hash); 1688ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1689ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // hash = hash ^ (hash >> 12); 16907ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(12)); 16917ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); 1692ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1693ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // hash = hash + (hash << 2); 16947ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org shifted_hash = AddUncasted<HShl>(hash, Add<HConstant>(2)); 16957ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org hash = AddUncasted<HAdd>(hash, shifted_hash); 1696ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1697ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // hash = hash ^ (hash >> 4); 16987ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(4)); 16997ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); 1700ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1701ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // hash = hash * 2057; 17027ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org hash = AddUncasted<HMul>(hash, Add<HConstant>(2057)); 1703ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org hash->ClearFlag(HValue::kCanOverflow); 1704ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1705ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // hash = hash ^ (hash >> 16); 17067ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(16)); 17077ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org return AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); 1708ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org} 1709ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1710ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1711ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgHValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver, 17121845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* elements, 17131845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* key, 17141845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org HValue* hash) { 1715ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HValue* capacity = Add<HLoadKeyed>( 1716ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org elements, 1717ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Add<HConstant>(NameDictionary::kCapacityIndex), 1718ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org static_cast<HValue*>(NULL), 1719f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org FAST_ELEMENTS); 1720ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1721f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1()); 1722ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org mask->ChangeRepresentation(Representation::Integer32()); 1723ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org mask->ClearFlag(HValue::kCanOverflow); 1724ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1725ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org return BuildUncheckedDictionaryElementLoadHelper(elements, key, 1726ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org hash, mask, 0); 1727ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org} 1728ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 1729ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 173009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.orgHValue* HGraphBuilder::BuildRegExpConstructResult(HValue* length, 173109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* index, 173209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* input) { 173309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org NoObservableSideEffectsScope scope(this); 173438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HConstant* max_length = Add<HConstant>(JSObject::kInitialMaxFastElementArray); 173538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Add<HBoundsCheck>(length, max_length); 173609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 173738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // Generate size calculation code here in order to make it dominate 173838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // the JSRegExpResult allocation. 173938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org ElementsKind elements_kind = FAST_ELEMENTS; 174038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* size = BuildCalculateElementsSize(elements_kind, length); 174109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 174209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org // Allocate the JSRegExpResult and the FixedArray in one step. 174309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* result = Add<HAllocate>( 174438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Add<HConstant>(JSRegExpResult::kSize), HType::JSArray(), 174538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org NOT_TENURED, JS_ARRAY_TYPE); 174609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 174709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org // Initialize the JSRegExpResult header. 174809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* global_object = Add<HLoadNamedField>( 174909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org context(), static_cast<HValue*>(NULL), 175009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 175109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* native_context = Add<HLoadNamedField>( 175209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org global_object, static_cast<HValue*>(NULL), 175309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HObjectAccess::ForGlobalObjectNativeContext()); 17546a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Add<HStoreNamedField>( 17556a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org result, HObjectAccess::ForMap(), 17566a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Add<HLoadNamedField>( 175709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org native_context, static_cast<HValue*>(NULL), 175809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HObjectAccess::ForContextSlot(Context::REGEXP_RESULT_MAP_INDEX))); 175938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HConstant* empty_fixed_array = 176038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Add<HConstant>(isolate()->factory()->empty_fixed_array()); 176109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org Add<HStoreNamedField>( 176209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org result, HObjectAccess::ForJSArrayOffset(JSArray::kPropertiesOffset), 176338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org empty_fixed_array); 176409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org Add<HStoreNamedField>( 176509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset), 176638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org empty_fixed_array); 176709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org Add<HStoreNamedField>( 17680a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org result, HObjectAccess::ForJSArrayOffset(JSArray::kLengthOffset), length); 176909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 177009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org // Initialize the additional fields. 177109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org Add<HStoreNamedField>( 177209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kIndexOffset), 17730a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org index); 177409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org Add<HStoreNamedField>( 177509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kInputOffset), 17760a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org input); 177709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 177838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // Allocate and initialize the elements header. 177938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HAllocate* elements = BuildAllocateElements(elements_kind, size); 178038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org BuildInitializeElementsHeader(elements, elements_kind, length); 178138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 178238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HConstant* size_in_bytes_upper_bound = EstablishElementsAllocationSize( 178338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org elements_kind, max_length->Integer32Value()); 178438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org elements->set_size_upper_bound(size_in_bytes_upper_bound); 178538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 178638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Add<HStoreNamedField>( 178738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset), 178838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org elements); 178909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 179009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org // Initialize the elements contents with undefined. 179138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org BuildFillElementsWithValue( 179238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org elements, elements_kind, graph()->GetConstant0(), length, 179338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org graph()->GetConstantUndefined()); 179409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 179509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org return result; 179609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org} 179709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 179809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 17996d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.orgHValue* HGraphBuilder::BuildNumberToString(HValue* object, Type* type) { 1800e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org NoObservableSideEffectsScope scope(this); 1801e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org 18027ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // Convert constant numbers at compile time. 18037ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org if (object->IsConstant() && HConstant::cast(object)->HasNumberValue()) { 18047ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org Handle<Object> number = HConstant::cast(object)->handle(isolate()); 18057ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org Handle<String> result = isolate()->factory()->NumberToString(number); 18067ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org return Add<HConstant>(result); 18077ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org } 18087ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 18093d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // Create a joinable continuation. 18103d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org HIfContinuation found(graph()->CreateBasicBlock(), 18113d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org graph()->CreateBasicBlock()); 18123d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 18133d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // Load the number string cache. 18143d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org HValue* number_string_cache = 18153d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org Add<HLoadRoot>(Heap::kNumberStringCacheRootIndex); 18163d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 1817e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org // Make the hash mask from the length of the number string cache. It 18183d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // contains two elements (number and string) for each cache entry. 18193d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org HValue* mask = AddLoadFixedArrayLength(number_string_cache); 18203d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org mask->set_type(HType::Smi()); 1821f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org mask = AddUncasted<HSar>(mask, graph()->GetConstant1()); 1822f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org mask = AddUncasted<HSub>(mask, graph()->GetConstant1()); 18233d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 18243d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // Check whether object is a smi. 18253d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org IfBuilder if_objectissmi(this); 18263d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org if_objectissmi.If<HIsSmiAndBranch>(object); 18273d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org if_objectissmi.Then(); 18283d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org { 18293d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // Compute hash for smi similar to smi_get_hash(). 18307ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HValue* hash = AddUncasted<HBitwise>(Token::BIT_AND, object, mask); 18313d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 18323d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // Load the key. 18337ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); 1834b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, 1835b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org static_cast<HValue*>(NULL), 1836b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org FAST_ELEMENTS, ALLOW_RETURN_HOLE); 18373d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 18383d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // Check if object == key. 18393d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org IfBuilder if_objectiskey(this); 1840e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org if_objectiskey.If<HCompareObjectEqAndBranch>(object, key); 18413d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org if_objectiskey.Then(); 18423d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org { 18433d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // Make the key_index available. 18443d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org Push(key_index); 18453d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org } 18463d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org if_objectiskey.JoinContinuation(&found); 18473d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org } 18483d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org if_objectissmi.Else(); 18493d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org { 18504452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org if (type->Is(Type::SignedSmall())) { 1851cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org if_objectissmi.Deopt("Expected smi"); 1852e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org } else { 1853e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org // Check if the object is a heap number. 1854e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org IfBuilder if_objectisnumber(this); 185509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* objectisnumber = if_objectisnumber.If<HCompareMap>( 1856052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org object, isolate()->factory()->heap_number_map()); 1857e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org if_objectisnumber.Then(); 18583d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org { 1859e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org // Compute hash for heap number similar to double_get_hash(). 1860e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org HValue* low = Add<HLoadNamedField>( 186109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org object, objectisnumber, 186209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HObjectAccess::ForHeapNumberValueLowestBits()); 1863e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org HValue* high = Add<HLoadNamedField>( 186409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org object, objectisnumber, 186509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HObjectAccess::ForHeapNumberValueHighestBits()); 18667ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, low, high); 18677ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org hash = AddUncasted<HBitwise>(Token::BIT_AND, hash, mask); 1868e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org 1869e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org // Load the key. 18707ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); 1871e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, 1872e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org static_cast<HValue*>(NULL), 1873e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org FAST_ELEMENTS, ALLOW_RETURN_HOLE); 1874e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org 1875eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org // Check if the key is a heap number and compare it with the object. 1876e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org IfBuilder if_keyisnotsmi(this); 187709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* keyisnotsmi = if_keyisnotsmi.IfNot<HIsSmiAndBranch>(key); 1878e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org if_keyisnotsmi.Then(); 18793d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org { 1880eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org IfBuilder if_keyisheapnumber(this); 1881eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org if_keyisheapnumber.If<HCompareMap>( 1882eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org key, isolate()->factory()->heap_number_map()); 1883eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org if_keyisheapnumber.Then(); 1884e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org { 1885eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org // Check if values of key and object match. 1886eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org IfBuilder if_keyeqobject(this); 1887eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org if_keyeqobject.If<HCompareNumericAndBranch>( 1888eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org Add<HLoadNamedField>(key, keyisnotsmi, 1889eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org HObjectAccess::ForHeapNumberValue()), 1890eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org Add<HLoadNamedField>(object, objectisnumber, 1891eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org HObjectAccess::ForHeapNumberValue()), 1892eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org Token::EQ); 1893eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org if_keyeqobject.Then(); 1894eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org { 1895eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org // Make the key_index available. 1896eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org Push(key_index); 1897eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org } 1898eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org if_keyeqobject.JoinContinuation(&found); 1899e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org } 1900eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org if_keyisheapnumber.JoinContinuation(&found); 1901e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org } 1902e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org if_keyisnotsmi.JoinContinuation(&found); 1903e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org } 1904e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org if_objectisnumber.Else(); 1905e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org { 1906e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org if (type->Is(Type::Number())) { 1907e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org if_objectisnumber.Deopt("Expected heap number"); 19083d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org } 19093d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org } 1910e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org if_objectisnumber.JoinContinuation(&found); 19113d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org } 19123d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org } 1913e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org if_objectissmi.JoinContinuation(&found); 19143d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 19153d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // Check for cache hit. 19163d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org IfBuilder if_found(this, &found); 19173d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org if_found.Then(); 1918e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org { 1919e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org // Count number to string operation in native code. 1920e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org AddIncrementCounter(isolate()->counters()->number_to_string_native()); 19213d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 1922e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org // Load the value in case of cache hit. 1923e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org HValue* key_index = Pop(); 19247ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1()); 1925e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org Push(Add<HLoadKeyed>(number_string_cache, value_index, 1926e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org static_cast<HValue*>(NULL), 1927e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org FAST_ELEMENTS, ALLOW_RETURN_HOLE)); 1928e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org } 19293d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org if_found.Else(); 1930e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org { 1931e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org // Cache miss, fallback to runtime. 19328d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Add<HPushArguments>(object); 1933e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org Push(Add<HCallRuntime>( 1934e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org isolate()->factory()->empty_string(), 1935895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Runtime::FunctionForId(Runtime::kHiddenNumberToStringSkipCache), 1936e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org 1)); 1937e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org } 19383d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org if_found.End(); 19393d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 19403d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org return Pop(); 19413d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org} 19423d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 19433d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 19440f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgHAllocate* HGraphBuilder::BuildAllocate( 19450f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* object_size, 19460f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HType type, 19470f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org InstanceType instance_type, 19480f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HAllocationMode allocation_mode) { 19490f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Compute the effective allocation size. 19500f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* size = object_size; 19510f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if (allocation_mode.CreateAllocationMementos()) { 19520f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org size = AddUncasted<HAdd>(size, Add<HConstant>(AllocationMemento::kSize)); 19530cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org size->ClearFlag(HValue::kCanOverflow); 19540cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org } 19550f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 19560f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Perform the actual allocation. 19570f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HAllocate* object = Add<HAllocate>( 19580f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org size, type, allocation_mode.GetPretenureMode(), 19590f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org instance_type, allocation_mode.feedback_site()); 19600f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 19610f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Setup the allocation memento. 19620f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if (allocation_mode.CreateAllocationMementos()) { 19630f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org BuildCreateAllocationMemento( 19640f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org object, object_size, allocation_mode.current_site()); 19650f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } 19660f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 19670f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org return object; 19680f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org} 19690f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 19700f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 19710f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgHValue* HGraphBuilder::BuildAddStringLengths(HValue* left_length, 19720f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* right_length) { 197386b1631344aedfc4be5dcd5237e28d0b28e5974emachenbach@chromium.org // Compute the combined string length and check against max string length. 19740f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* length = AddUncasted<HAdd>(left_length, right_length); 19754edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org // Check that length <= kMaxLength <=> length < MaxLength + 1. 19764edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org HValue* max_length = Add<HConstant>(String::kMaxLength + 1); 19777010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org Add<HBoundsCheck>(length, max_length); 19780f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org return length; 19790f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org} 19800f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 19810f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 19820f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgHValue* HGraphBuilder::BuildCreateConsString( 19830f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* length, 19840f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* left, 19850f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* right, 19860f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HAllocationMode allocation_mode) { 19870f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Determine the string instance types. 19880f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HInstruction* left_instance_type = AddLoadStringInstanceType(left); 19890f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HInstruction* right_instance_type = AddLoadStringInstanceType(right); 19900f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 19910f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Allocate the cons string object. HAllocate does not care whether we 19920f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use 19930f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // CONS_STRING_TYPE here. Below we decide whether the cons string is 19940f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // one-byte or two-byte and set the appropriate map. 19950f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org ASSERT(HAllocate::CompatibleInstanceTypes(CONS_STRING_TYPE, 19960f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org CONS_ASCII_STRING_TYPE)); 19970f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HAllocate* result = BuildAllocate(Add<HConstant>(ConsString::kSize), 19980f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HType::String(), CONS_STRING_TYPE, 19990f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org allocation_mode); 20000f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 20010f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Compute intersection and difference of instance types. 20020f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* anded_instance_types = AddUncasted<HBitwise>( 20030f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Token::BIT_AND, left_instance_type, right_instance_type); 20040f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* xored_instance_types = AddUncasted<HBitwise>( 20050f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Token::BIT_XOR, left_instance_type, right_instance_type); 20060f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 20070f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // We create a one-byte cons string if 20080f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // 1. both strings are one-byte, or 20090f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // 2. at least one of the strings is two-byte, but happens to contain only 20100f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // one-byte characters. 20110f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // To do this, we check 20120f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // 1. if both strings are one-byte, or if the one-byte data hint is set in 20130f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // both strings, or 20140f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // 2. if one of the strings has the one-byte data hint set and the other 20150f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // string is one-byte. 20160f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org IfBuilder if_onebyte(this); 20170f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org STATIC_ASSERT(kOneByteStringTag != 0); 20180f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org STATIC_ASSERT(kOneByteDataHintMask != 0); 20190f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_onebyte.If<HCompareNumericAndBranch>( 20200f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org AddUncasted<HBitwise>( 20210f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Token::BIT_AND, anded_instance_types, 20220f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Add<HConstant>(static_cast<int32_t>( 20230f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org kStringEncodingMask | kOneByteDataHintMask))), 20240f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org graph()->GetConstant0(), Token::NE); 20250f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_onebyte.Or(); 20260f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org STATIC_ASSERT(kOneByteStringTag != 0 && 20270f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org kOneByteDataHintTag != 0 && 20280f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org kOneByteDataHintTag != kOneByteStringTag); 20290f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_onebyte.If<HCompareNumericAndBranch>( 20300f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org AddUncasted<HBitwise>( 20310f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Token::BIT_AND, xored_instance_types, 20320f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Add<HConstant>(static_cast<int32_t>( 20330f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org kOneByteStringTag | kOneByteDataHintTag))), 20340f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Add<HConstant>(static_cast<int32_t>( 20350f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org kOneByteStringTag | kOneByteDataHintTag)), Token::EQ); 20360f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_onebyte.Then(); 20370f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org { 20380f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // We can safely skip the write barrier for storing the map here. 20396a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Add<HStoreNamedField>( 20406a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org result, HObjectAccess::ForMap(), 20416a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Add<HConstant>(isolate()->factory()->cons_ascii_string_map())); 20420f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } 20430f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_onebyte.Else(); 20440f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org { 20450f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // We can safely skip the write barrier for storing the map here. 20466a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Add<HStoreNamedField>( 20476a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org result, HObjectAccess::ForMap(), 20486a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Add<HConstant>(isolate()->factory()->cons_string_map())); 20490f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } 20500f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_onebyte.End(); 20510f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 20520f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Initialize the cons string fields. 20530f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(), 20540a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HConstant>(String::kEmptyHashField)); 20550a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length); 20560a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HStoreNamedField>(result, HObjectAccess::ForConsStringFirst(), left); 20570a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HStoreNamedField>(result, HObjectAccess::ForConsStringSecond(), right); 20580f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 20590f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Count the native string addition. 20600f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org AddIncrementCounter(isolate()->counters()->string_add_native()); 20610f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 20620f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org return result; 20630cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org} 20640cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 20650cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 20660cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.orgvoid HGraphBuilder::BuildCopySeqStringChars(HValue* src, 20670cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org HValue* src_offset, 20680cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org String::Encoding src_encoding, 20690cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org HValue* dst, 20700cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org HValue* dst_offset, 20710cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org String::Encoding dst_encoding, 20720cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org HValue* length) { 20730cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org ASSERT(dst_encoding != String::ONE_BYTE_ENCODING || 20740cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org src_encoding == String::ONE_BYTE_ENCODING); 20750cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); 20760cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org HValue* index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT); 20770cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org { 20787ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HValue* src_index = AddUncasted<HAdd>(src_offset, index); 2079f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org HValue* value = 2080f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org AddUncasted<HSeqStringGetChar>(src_encoding, src, src_index); 20817ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HValue* dst_index = AddUncasted<HAdd>(dst_offset, index); 20820cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Add<HSeqStringSetChar>(dst_encoding, dst, dst_index, value); 20830cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org } 20840cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org loop.EndBody(); 20850cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org} 20860cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 20870cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 2088895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgHValue* HGraphBuilder::BuildObjectSizeAlignment( 2089895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HValue* unaligned_size, int header_size) { 2090895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org ASSERT((header_size & kObjectAlignmentMask) == 0); 2091895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HValue* size = AddUncasted<HAdd>( 2092895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org unaligned_size, Add<HConstant>(static_cast<int32_t>( 2093895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org header_size + kObjectAlignmentMask))); 2094895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org size->ClearFlag(HValue::kCanOverflow); 2095895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org return AddUncasted<HBitwise>( 2096895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>( 2097895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org ~kObjectAlignmentMask))); 2098895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org} 2099895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 2100895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 21010f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgHValue* HGraphBuilder::BuildUncheckedStringAdd( 21020f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* left, 21030f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* right, 21040f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HAllocationMode allocation_mode) { 21050cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org // Determine the string lengths. 21060f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* left_length = AddLoadStringLength(left); 21070f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* right_length = AddLoadStringLength(right); 21080cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 21090f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Compute the combined string length. 21100f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* length = BuildAddStringLengths(left_length, right_length); 2111f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 21120f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Do some manual constant folding here. 21130f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if (left_length->IsConstant()) { 21140f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HConstant* c_left_length = HConstant::cast(left_length); 21150f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org ASSERT_NE(0, c_left_length->Integer32Value()); 21160f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if (c_left_length->Integer32Value() + 1 >= ConsString::kMinLength) { 21170f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // The right string contains at least one character. 21180f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org return BuildCreateConsString(length, left, right, allocation_mode); 21190f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } 21200f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } else if (right_length->IsConstant()) { 21210f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HConstant* c_right_length = HConstant::cast(right_length); 21220f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org ASSERT_NE(0, c_right_length->Integer32Value()); 21230f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if (c_right_length->Integer32Value() + 1 >= ConsString::kMinLength) { 21240f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // The left string contains at least one character. 21250f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org return BuildCreateConsString(length, left, right, allocation_mode); 21260f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } 21270f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } 2128f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 2129f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // Check if we should create a cons string. 2130f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org IfBuilder if_createcons(this); 2131f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if_createcons.If<HCompareNumericAndBranch>( 2132f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org length, Add<HConstant>(ConsString::kMinLength), Token::GTE); 2133f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if_createcons.Then(); 21340cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org { 21350f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Create a cons string. 21360f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Push(BuildCreateConsString(length, left, right, allocation_mode)); 2137f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } 2138f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if_createcons.Else(); 2139f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org { 21400f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Determine the string instance types. 21410f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* left_instance_type = AddLoadStringInstanceType(left); 21420f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* right_instance_type = AddLoadStringInstanceType(right); 21430f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 21440f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Compute union and difference of instance types. 2145f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org HValue* ored_instance_types = AddUncasted<HBitwise>( 2146f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Token::BIT_OR, left_instance_type, right_instance_type); 21470f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* xored_instance_types = AddUncasted<HBitwise>( 21480f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Token::BIT_XOR, left_instance_type, right_instance_type); 2149f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 2150f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // Check if both strings have the same encoding and both are 2151f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // sequential. 2152f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org IfBuilder if_sameencodingandsequential(this); 2153f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if_sameencodingandsequential.If<HCompareNumericAndBranch>( 2154f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org AddUncasted<HBitwise>( 2155f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Token::BIT_AND, xored_instance_types, 2156f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))), 2157f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org graph()->GetConstant0(), Token::EQ); 2158f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if_sameencodingandsequential.And(); 2159f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org STATIC_ASSERT(kSeqStringTag == 0); 2160f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if_sameencodingandsequential.If<HCompareNumericAndBranch>( 2161f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org AddUncasted<HBitwise>( 2162f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Token::BIT_AND, ored_instance_types, 2163f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Add<HConstant>(static_cast<int32_t>(kStringRepresentationMask))), 2164f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org graph()->GetConstant0(), Token::EQ); 2165f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if_sameencodingandsequential.Then(); 2166f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org { 21670f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HConstant* string_map = 21680f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Add<HConstant>(isolate()->factory()->string_map()); 21690f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HConstant* ascii_string_map = 21700f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Add<HConstant>(isolate()->factory()->ascii_string_map()); 21710f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 21720f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Determine map and size depending on whether result is one-byte string. 21730cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org IfBuilder if_onebyte(this); 21740cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org STATIC_ASSERT(kOneByteStringTag != 0); 21750cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org if_onebyte.If<HCompareNumericAndBranch>( 21767ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org AddUncasted<HBitwise>( 2177f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Token::BIT_AND, ored_instance_types, 2178f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))), 21790cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org graph()->GetConstant0(), Token::NE); 21800cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org if_onebyte.Then(); 21810cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org { 21820f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Allocate sequential one-byte string object. 21830f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Push(length); 21840f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Push(ascii_string_map); 21850f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } 21860f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_onebyte.Else(); 21870f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org { 21880f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Allocate sequential two-byte string object. 21890f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* size = AddUncasted<HShl>(length, graph()->GetConstant1()); 21900f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org size->ClearFlag(HValue::kCanOverflow); 21910f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org size->SetFlag(HValue::kUint32); 21920f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Push(size); 21930f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Push(string_map); 21940f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } 21950f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_onebyte.End(); 21960f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* map = Pop(); 21970f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 21980f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Calculate the number of bytes needed for the characters in the 21990f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // string while observing object alignment. 22000f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0); 2201895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HValue* size = BuildObjectSizeAlignment(Pop(), SeqString::kHeaderSize); 22020f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 22030f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Allocate the string object. HAllocate does not care whether we pass 22040f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // STRING_TYPE or ASCII_STRING_TYPE here, so we just use STRING_TYPE here. 22050f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HAllocate* result = BuildAllocate( 22060f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org size, HType::String(), STRING_TYPE, allocation_mode); 22076a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Add<HStoreNamedField>(result, HObjectAccess::ForMap(), map); 22080f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 22090f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Initialize the string fields. 22100f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(), 22110a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HConstant>(String::kEmptyHashField)); 22120a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length); 22130f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 22140f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Copy characters to the result string. 22150f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org IfBuilder if_twobyte(this); 22160f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_twobyte.If<HCompareObjectEqAndBranch>(map, string_map); 22170f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_twobyte.Then(); 22180f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org { 22190f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Copy characters from the left string. 2220f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org BuildCopySeqStringChars( 22210f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org left, graph()->GetConstant0(), String::TWO_BYTE_ENCODING, 22220f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org result, graph()->GetConstant0(), String::TWO_BYTE_ENCODING, 2223f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org left_length); 2224f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 22250f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Copy characters from the right string. 2226f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org BuildCopySeqStringChars( 22270f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org right, graph()->GetConstant0(), String::TWO_BYTE_ENCODING, 22280f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org result, left_length, String::TWO_BYTE_ENCODING, 2229f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org right_length); 22300cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org } 22310f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_twobyte.Else(); 22320cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org { 22330f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Copy characters from the left string. 2234f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org BuildCopySeqStringChars( 22350f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org left, graph()->GetConstant0(), String::ONE_BYTE_ENCODING, 22360f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org result, graph()->GetConstant0(), String::ONE_BYTE_ENCODING, 2237f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org left_length); 2238f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 22390f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Copy characters from the right string. 2240f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org BuildCopySeqStringChars( 22410f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org right, graph()->GetConstant0(), String::ONE_BYTE_ENCODING, 22420f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org result, left_length, String::ONE_BYTE_ENCODING, 2243f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org right_length); 22440cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org } 22450f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_twobyte.End(); 22460cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 2247f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // Count the native string addition. 2248f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org AddIncrementCounter(isolate()->counters()->string_add_native()); 2249f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 22500f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Return the sequential string. 22510f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Push(result); 22520cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org } 2253f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if_sameencodingandsequential.Else(); 22540cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org { 2255f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // Fallback to the runtime to add the two strings. 22568d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Add<HPushArguments>(left, right); 22579b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org Push(Add<HCallRuntime>( 22589b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org isolate()->factory()->empty_string(), 22599b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org Runtime::FunctionForId(Runtime::kHiddenStringAdd), 22609b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org 2)); 22610cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org } 2262f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if_sameencodingandsequential.End(); 22630cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org } 2264f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if_createcons.End(); 22650cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 22660cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org return Pop(); 22670cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org} 22680cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 22690cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 22700f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgHValue* HGraphBuilder::BuildStringAdd( 22710f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* left, 22720f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* right, 22730f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HAllocationMode allocation_mode) { 22740f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org NoObservableSideEffectsScope no_effects(this); 22750f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 22760f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Determine string lengths. 22770f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* left_length = AddLoadStringLength(left); 22780f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HValue* right_length = AddLoadStringLength(right); 22790cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 22800cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org // Check if left string is empty. 22810f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org IfBuilder if_leftempty(this); 22820f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_leftempty.If<HCompareNumericAndBranch>( 22830cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org left_length, graph()->GetConstant0(), Token::EQ); 22840f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_leftempty.Then(); 22850cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org { 22860cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org // Count the native string addition. 22870cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org AddIncrementCounter(isolate()->counters()->string_add_native()); 22880cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 22890cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org // Just return the right string. 22900cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Push(right); 22910cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org } 22920f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_leftempty.Else(); 22930cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org { 22940cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org // Check if right string is empty. 22950f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org IfBuilder if_rightempty(this); 22960f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_rightempty.If<HCompareNumericAndBranch>( 22970cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org right_length, graph()->GetConstant0(), Token::EQ); 22980f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_rightempty.Then(); 22990cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org { 23000cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org // Count the native string addition. 23010cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org AddIncrementCounter(isolate()->counters()->string_add_native()); 23020cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 23030cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org // Just return the left string. 23040cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Push(left); 23050cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org } 23060f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_rightempty.Else(); 23070cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org { 23080f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Add the two non-empty strings. 23090f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Push(BuildUncheckedStringAdd(left, right, allocation_mode)); 23100cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org } 23110f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_rightempty.End(); 23120cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org } 23130f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if_leftempty.End(); 23140cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 23150cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org return Pop(); 23160cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org} 23170cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 23180cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 2319a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( 23201e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org HValue* checked_object, 2321a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* key, 2322a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* val, 2323a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool is_js_array, 2324a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ElementsKind elements_kind, 2325f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PropertyAccessType access_type, 2326906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org LoadKeyedHoleMode load_mode, 232753ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org KeyedAccessStoreMode store_mode) { 23285c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org ASSERT((!IsExternalArrayElementsKind(elements_kind) && 23295c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org !IsFixedTypedArrayElementsKind(elements_kind)) || 23305c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org !is_js_array); 2331a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // No GVNFlag is necessary for ElementsKind if there is an explicit dependency 2332a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // on a HElementsTransition instruction. The flag can also be removed if the 2333a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // map to check has FAST_HOLEY_ELEMENTS, since there can be no further 2334a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // ElementsKind transitions. Finally, the dependency can be removed for stores 2335a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the 2336a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // generated store code. 2337a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if ((elements_kind == FAST_HOLEY_ELEMENTS) || 2338f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org (elements_kind == FAST_ELEMENTS && access_type == STORE)) { 2339f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org checked_object->ClearDependsOnFlag(kElementsKind); 2340a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 23411e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 2342a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); 2343a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool fast_elements = IsFastObjectElementsKind(elements_kind); 23441e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org HValue* elements = AddLoadElements(checked_object); 2345f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (access_type == STORE && (fast_elements || fast_smi_only_elements) && 23467bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 2347d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HCheckMaps* check_cow_map = Add<HCheckMaps>( 2348af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org elements, isolate()->factory()->fixed_array_map()); 2349f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org check_cow_map->ClearDependsOnFlag(kElementsKind); 2350a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 2351a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HInstruction* length = NULL; 23527bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org if (is_js_array) { 2353ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org length = Add<HLoadNamedField>( 23545924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org checked_object->ActualValue(), checked_object, 235509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HObjectAccess::ForArrayLength(elements_kind)); 23567bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org } else { 2357c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org length = AddLoadFixedArrayLength(elements); 23587bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org } 2359c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org length->set_type(HType::Smi()); 23607bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org HValue* checked_key = NULL; 23615c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org if (IsExternalArrayElementsKind(elements_kind) || 23625c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org IsFixedTypedArrayElementsKind(elements_kind)) { 23635c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org HValue* backing_store; 23645c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org if (IsExternalArrayElementsKind(elements_kind)) { 236505150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org backing_store = Add<HLoadNamedField>( 236609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org elements, static_cast<HValue*>(NULL), 236709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HObjectAccess::ForExternalArrayExternalPointer()); 23685c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org } else { 23695c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org backing_store = elements; 23705c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org } 23717bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 2372b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org NoObservableSideEffectsScope no_effects(this); 23732d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org IfBuilder length_checker(this); 2374e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); 2375b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org length_checker.Then(); 237677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org IfBuilder negative_checker(this); 2377e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( 2378b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org key, graph()->GetConstant0(), Token::GTE); 237977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org negative_checker.Then(); 2380b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org HInstruction* result = AddElementAccess( 2381f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org backing_store, key, val, bounds_check, elements_kind, access_type); 2382594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org negative_checker.ElseDeopt("Negative key encountered"); 2383ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org negative_checker.End(); 23847bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org length_checker.End(); 23857bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org return result; 23867bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org } else { 23877bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org ASSERT(store_mode == STANDARD_STORE); 23881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org checked_key = Add<HBoundsCheck>(key, length); 2389b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org return AddElementAccess( 23905c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org backing_store, checked_key, val, 2391f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org checked_object, elements_kind, access_type); 23927bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org } 2393a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 2394a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(fast_smi_only_elements || 2395a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org fast_elements || 2396a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org IsFastDoubleElementsKind(elements_kind)); 23977bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 239853ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org // In case val is stored into a fast smi array, assure that the value is a smi 239953ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org // before manipulating the backing store. Otherwise the actual store may 240053ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org // deopt, leaving the backing store in an invalid state. 2401f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (access_type == STORE && IsFastSmiElementsKind(elements_kind) && 24027bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org !val->type().IsSmi()) { 24039af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org val = AddUncasted<HForceRepresentation>(val, Representation::Smi()); 24047bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org } 24057bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 24067bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org if (IsGrowStoreMode(store_mode)) { 2407e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org NoObservableSideEffectsScope no_effects(this); 2408804712e3d40723ca745704121c814fe52e8e6158verwaest@chromium.org Representation representation = HStoreKeyed::RequiredValueRepresentation( 2409804712e3d40723ca745704121c814fe52e8e6158verwaest@chromium.org elements_kind, STORE_TO_INITIALIZED_ENTRY); 2410804712e3d40723ca745704121c814fe52e8e6158verwaest@chromium.org val = AddUncasted<HForceRepresentation>(val, representation); 24111e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org elements = BuildCheckForCapacityGrow(checked_object, elements, 24121e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org elements_kind, length, key, 2413f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org is_js_array, access_type); 2414a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org checked_key = key; 2415a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 24161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org checked_key = Add<HBoundsCheck>(key, length); 24177bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 2418f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (access_type == STORE && (fast_elements || fast_smi_only_elements)) { 24197bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { 2420e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org NoObservableSideEffectsScope no_effects(this); 24211e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org elements = BuildCopyElementsOnWrite(checked_object, elements, 24221e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org elements_kind, length); 24237bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org } else { 2424d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HCheckMaps* check_cow_map = Add<HCheckMaps>( 2425af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org elements, isolate()->factory()->fixed_array_map()); 2426f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org check_cow_map->ClearDependsOnFlag(kElementsKind); 24277bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org } 24287bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org } 2429a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 2430b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org return AddElementAccess(elements, checked_key, val, checked_object, 2431f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org elements_kind, access_type, load_mode); 2432a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 2433a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 2434a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 2435b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgHValue* HGraphBuilder::BuildAllocateArrayFromLength( 2436b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org JSArrayBuilder* array_builder, 2437b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HValue* length_argument) { 2438b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (length_argument->IsConstant() && 2439b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HConstant::cast(length_argument)->HasSmiValue()) { 2440b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org int array_length = HConstant::cast(length_argument)->Integer32Value(); 244138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org if (array_length == 0) { 244238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org return array_builder->AllocateEmptyArray(); 244338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org } else { 244438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org return array_builder->AllocateArray(length_argument, 244538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org array_length, 244638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org length_argument); 244738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org } 2448b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 2449b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 2450b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HValue* constant_zero = graph()->GetConstant0(); 2451b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HConstant* max_alloc_length = 2452b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Add<HConstant>(JSObject::kInitialMaxFastElementArray); 2453b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HInstruction* checked_length = Add<HBoundsCheck>(length_argument, 2454b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org max_alloc_length); 2455b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org IfBuilder if_builder(this); 2456b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if_builder.If<HCompareNumericAndBranch>(checked_length, constant_zero, 2457b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Token::EQ); 2458b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if_builder.Then(); 2459b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org const int initial_capacity = JSArray::kPreallocatedArrayElements; 2460b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HConstant* initial_capacity_node = Add<HConstant>(initial_capacity); 2461b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Push(initial_capacity_node); // capacity 2462b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Push(constant_zero); // length 2463b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if_builder.Else(); 2464b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (!(top_info()->IsStub()) && 2465b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org IsFastPackedElementsKind(array_builder->kind())) { 2466b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // We'll come back later with better (holey) feedback. 2467b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if_builder.Deopt("Holey array despite packed elements_kind feedback"); 2468ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } else { 2469ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Push(checked_length); // capacity 2470ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Push(checked_length); // length 2471b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 2472b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if_builder.End(); 2473b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 2474b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // Figure out total size 2475b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HValue* length = Pop(); 2476b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HValue* capacity = Pop(); 247738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org return array_builder->AllocateArray(capacity, max_alloc_length, length); 2478b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org} 2479b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 24806a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org 248138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHValue* HGraphBuilder::BuildCalculateElementsSize(ElementsKind kind, 248238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* capacity) { 248338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org int elements_size = IsFastDoubleElementsKind(kind) 248438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org ? kDoubleSize 248538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org : kPointerSize; 248694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 24871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HConstant* elements_size_value = Add<HConstant>(elements_size); 248838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HInstruction* mul = HMul::NewImul(zone(), context(), 248938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org capacity->ActualValue(), 249038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org elements_size_value); 249138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org AddInstruction(mul); 249294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org mul->ClearFlag(HValue::kCanOverflow); 249394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 249438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize); 249538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 24961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); 24977ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HValue* total_size = AddUncasted<HAdd>(mul, header_size); 249894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org total_size->ClearFlag(HValue::kCanOverflow); 249938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org return total_size; 250038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org} 250138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 250238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 250338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHAllocate* HGraphBuilder::AllocateJSArrayObject(AllocationSiteMode mode) { 250438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org int base_size = JSArray::kSize; 250538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org if (mode == TRACK_ALLOCATION_SITE) { 250638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org base_size += AllocationMemento::kSize; 250738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org } 250838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HConstant* size_in_bytes = Add<HConstant>(base_size); 250938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org return Add<HAllocate>( 251038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org size_in_bytes, HType::JSArray(), NOT_TENURED, JS_OBJECT_TYPE); 251138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org} 251238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 251338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 251438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHConstant* HGraphBuilder::EstablishElementsAllocationSize( 251538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org ElementsKind kind, 251638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org int capacity) { 251738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org int base_size = IsFastDoubleElementsKind(kind) 251838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org ? FixedDoubleArray::SizeFor(capacity) 251938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org : FixedArray::SizeFor(capacity); 252094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 252138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org return Add<HConstant>(base_size); 252238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org} 252338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 252438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 252538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHAllocate* HGraphBuilder::BuildAllocateElements(ElementsKind kind, 252638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* size_in_bytes) { 252738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org InstanceType instance_type = IsFastDoubleElementsKind(kind) 252838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org ? FIXED_DOUBLE_ARRAY_TYPE 252938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org : FIXED_ARRAY_TYPE; 253038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 253138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org return Add<HAllocate>(size_in_bytes, HType::HeapObject(), NOT_TENURED, 2532d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org instance_type); 2533e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 2534e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 253594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 2536c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgvoid HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, 2537c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org ElementsKind kind, 2538c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org HValue* capacity) { 2539750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Factory* factory = isolate()->factory(); 254094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Handle<Map> map = IsFastDoubleElementsKind(kind) 254194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ? factory->fixed_double_array_map() 254294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org : factory->fixed_array_map(); 254394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 25446a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Add<HStoreNamedField>(elements, HObjectAccess::ForMap(), Add<HConstant>(map)); 2545d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), 25460a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org capacity); 2547e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 254894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 2549e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 2550c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgHValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( 2551c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org ElementsKind kind, 2552c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org HValue* capacity) { 2553d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org // The HForceRepresentation is to prevent possible deopt on int-smi 2554d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org // conversion after allocation but before the new object fields are set. 25559af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi()); 255638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* size_in_bytes = BuildCalculateElementsSize(kind, capacity); 255738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* new_elements = BuildAllocateElements(kind, size_in_bytes); 2558c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org BuildInitializeElementsHeader(new_elements, kind, capacity); 2559e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return new_elements; 256094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 256194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 256294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 256338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgvoid HGraphBuilder::BuildJSArrayHeader(HValue* array, 256438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* array_map, 256538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* elements, 256638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org AllocationSiteMode mode, 256738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org ElementsKind elements_kind, 256838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* allocation_site_payload, 256938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* length_field) { 25700a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map); 2571ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2572ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org HConstant* empty_fixed_array = 2573d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Add<HConstant>(isolate()->factory()->empty_fixed_array()); 2574ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 257538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Add<HStoreNamedField>( 257638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org array, HObjectAccess::ForPropertiesPointer(), empty_fixed_array); 257738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 257838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Add<HStoreNamedField>( 257938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org array, HObjectAccess::ForElementsPointer(), 258038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org elements != NULL ? elements : empty_fixed_array); 258138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 258238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Add<HStoreNamedField>( 258338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org array, HObjectAccess::ForArrayLength(elements_kind), length_field); 2584ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2585ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if (mode == TRACK_ALLOCATION_SITE) { 2586ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org BuildCreateAllocationMemento( 2587ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org array, Add<HConstant>(JSArray::kSize), allocation_site_payload); 2588ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 2589ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 2590ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2591ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2592b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.orgHInstruction* HGraphBuilder::AddElementAccess( 2593b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org HValue* elements, 2594ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HValue* checked_key, 2595ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HValue* val, 2596ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HValue* dependency, 2597ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ElementsKind elements_kind, 2598f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PropertyAccessType access_type, 2599b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org LoadKeyedHoleMode load_mode) { 2600f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (access_type == STORE) { 2601ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ASSERT(val != NULL); 2602af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org if (elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS || 26035c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org elements_kind == UINT8_CLAMPED_ELEMENTS) { 2604b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org val = Add<HClampToUint8>(val); 2605ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 260671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org return Add<HStoreKeyed>(elements, checked_key, val, elements_kind, 2607804712e3d40723ca745704121c814fe52e8e6158verwaest@chromium.org STORE_TO_INITIALIZED_ENTRY); 2608ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 2609ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 2610f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ASSERT(access_type == LOAD); 2611b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org ASSERT(val == NULL); 2612b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org HLoadKeyed* load = Add<HLoadKeyed>( 2613b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org elements, checked_key, dependency, elements_kind, load_mode); 2614b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org if (FLAG_opt_safe_uint32_operations && 2615af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org (elements_kind == EXTERNAL_UINT32_ELEMENTS || 26165c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org elements_kind == UINT32_ELEMENTS)) { 2617b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org graph()->RecordUint32Instruction(load); 2618ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 2619b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org return load; 2620ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org} 2621ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 2622ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 262338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHLoadNamedField* HGraphBuilder::AddLoadMap(HValue* object, 262438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* dependency) { 262538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org return Add<HLoadNamedField>(object, dependency, HObjectAccess::ForMap()); 262638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org} 262738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 262838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 2629a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.orgHLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, 2630a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HValue* dependency) { 263109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org return Add<HLoadNamedField>( 2632a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org object, dependency, HObjectAccess::ForElementsPointer()); 263357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org} 263457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 263557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 2636a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.orgHLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength( 2637a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HValue* array, 2638a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HValue* dependency) { 263909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org return Add<HLoadNamedField>( 2640a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org array, dependency, HObjectAccess::ForFixedArrayLength()); 2641a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org} 2642a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 2643a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 2644a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.orgHLoadNamedField* HGraphBuilder::AddLoadArrayLength(HValue* array, 2645a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org ElementsKind kind, 2646a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HValue* dependency) { 2647a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org return Add<HLoadNamedField>( 2648a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org array, dependency, HObjectAccess::ForArrayLength(kind)); 2649c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org} 2650c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 2651c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 2652d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgHValue* HGraphBuilder::BuildNewElementsCapacity(HValue* old_capacity) { 2653dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org HValue* half_old_capacity = AddUncasted<HShr>(old_capacity, 2654dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org graph_->GetConstant1()); 26557bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 2656dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org HValue* new_capacity = AddUncasted<HAdd>(half_old_capacity, old_capacity); 26577bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org new_capacity->ClearFlag(HValue::kCanOverflow); 26587bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 26591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HValue* min_growth = Add<HConstant>(16); 26607bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 2661dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org new_capacity = AddUncasted<HAdd>(new_capacity, min_growth); 26627bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org new_capacity->ClearFlag(HValue::kCanOverflow); 26637bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 26647bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org return new_capacity; 26657bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org} 26667bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 26677bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 26687bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgHValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, 26697bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org HValue* elements, 26707bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org ElementsKind kind, 2671bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org ElementsKind new_kind, 26727bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org HValue* length, 26732d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org HValue* new_capacity) { 26743c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Add<HBoundsCheck>(new_capacity, Add<HConstant>( 26753c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org (Page::kMaxRegularHeapObjectSize - FixedArray::kHeaderSize) >> 26763c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org ElementsKindToShiftSize(kind))); 26777bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 2678c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org HValue* new_elements = BuildAllocateElementsAndInitializeElementsHeader( 2679d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org new_kind, new_capacity); 26807bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 268138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org BuildCopyElements(elements, kind, new_elements, 2682a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org new_kind, length, new_capacity); 26837bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 2684d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 26850a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org new_elements); 26867bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 26877bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org return new_elements; 26887bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org} 26897bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 26907bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 269138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgvoid HGraphBuilder::BuildFillElementsWithValue(HValue* elements, 269238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org ElementsKind elements_kind, 269338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* from, 269438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* to, 269538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* value) { 2696a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org if (to == NULL) { 2697a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org to = AddLoadFixedArrayLength(elements); 2698a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org } 2699a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 2700ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Special loop unfolding case 27017e6132b924829c353864933f29124419916db550machenbach@chromium.org STATIC_ASSERT(JSArray::kPreallocatedArrayElements <= 27027e6132b924829c353864933f29124419916db550machenbach@chromium.org kElementLoopUnrollThreshold); 2703b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org int initial_capacity = -1; 2704ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (from->IsInteger32Constant() && to->IsInteger32Constant()) { 2705ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org int constant_from = from->GetInteger32Constant(); 2706ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org int constant_to = to->GetInteger32Constant(); 27077bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 27087e6132b924829c353864933f29124419916db550machenbach@chromium.org if (constant_from == 0 && constant_to <= kElementLoopUnrollThreshold) { 2709ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org initial_capacity = constant_to; 2710ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 2711ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 27127bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 271353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org // Since we're about to store a hole value, the store instruction below must 271453ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org // assume an elements kind that supports heap object values. 271553ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org if (IsFastSmiOrObjectElementsKind(elements_kind)) { 271653ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org elements_kind = FAST_HOLEY_ELEMENTS; 271753ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org } 271853ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org 2719b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (initial_capacity >= 0) { 2720ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org for (int i = 0; i < initial_capacity; i++) { 27211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* key = Add<HConstant>(i); 272238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Add<HStoreKeyed>(elements, key, value, elements_kind); 2723ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 2724ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } else { 2725a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org // Carefully loop backwards so that the "from" remains live through the loop 2726a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org // rather than the to. This often corresponds to keeping length live rather 2727a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org // then capacity, which helps register allocation, since length is used more 2728a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org // other than capacity after filling with holes. 2729a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); 2730a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 2731a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HValue* key = builder.BeginBody(to, from, Token::GT); 27327bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 2733a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HValue* adjusted_key = AddUncasted<HSub>(key, graph()->GetConstant1()); 2734a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org adjusted_key->ClearFlag(HValue::kCanOverflow); 2735ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 273638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Add<HStoreKeyed>(elements, adjusted_key, value, elements_kind); 2737ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2738ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org builder.EndBody(); 2739ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 27407bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org} 27417bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 27427bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 274338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgvoid HGraphBuilder::BuildFillElementsWithHole(HValue* elements, 274438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org ElementsKind elements_kind, 274538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* from, 274638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* to) { 274738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // Fast elements kinds need to be initialized in case statements below cause a 274838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // garbage collection. 274938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Factory* factory = isolate()->factory(); 275038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 275138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org double nan_double = FixedDoubleArray::hole_nan_as_double(); 275238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) 275338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org ? Add<HConstant>(factory->the_hole_value()) 275438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org : Add<HConstant>(nan_double); 275538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 275638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org BuildFillElementsWithValue(elements, elements_kind, from, to, hole); 275738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org} 275838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 275938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 276038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgvoid HGraphBuilder::BuildCopyElements(HValue* from_elements, 276194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ElementsKind from_elements_kind, 276294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org HValue* to_elements, 276394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org ElementsKind to_elements_kind, 27647bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org HValue* length, 27652d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org HValue* capacity) { 2766a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org int constant_capacity = -1; 2767a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org if (capacity != NULL && 2768a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org capacity->IsConstant() && 2769a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HConstant::cast(capacity)->HasInteger32Value()) { 2770a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org int constant_candidate = HConstant::cast(capacity)->Integer32Value(); 2771e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org if (constant_candidate <= kElementLoopUnrollThreshold) { 2772a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org constant_capacity = constant_candidate; 2773a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org } 2774a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org } 2775a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 2776e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org bool pre_fill_with_holes = 2777e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org IsFastDoubleElementsKind(from_elements_kind) && 2778e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org IsFastObjectElementsKind(to_elements_kind); 2779e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (pre_fill_with_holes) { 2780e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // If the copy might trigger a GC, make sure that the FixedArray is 2781e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // pre-initialized with holes to make sure that it's always in a 2782e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // consistent state. 2783e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org BuildFillElementsWithHole(to_elements, to_elements_kind, 2784e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org graph()->GetConstant0(), NULL); 2785e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 2786e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org 2787a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org if (constant_capacity != -1) { 2788a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org // Unroll the loop for small elements kinds. 2789a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org for (int i = 0; i < constant_capacity; i++) { 2790a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HValue* key_constant = Add<HConstant>(i); 2791a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HInstruction* value = Add<HLoadKeyed>(from_elements, key_constant, 2792a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org static_cast<HValue*>(NULL), 2793a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org from_elements_kind); 2794a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org Add<HStoreKeyed>(to_elements, key_constant, value, to_elements_kind); 2795a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org } 2796a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org } else { 2797e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (!pre_fill_with_holes && 2798e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org (capacity == NULL || !length->Equals(capacity))) { 2799a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org BuildFillElementsWithHole(to_elements, to_elements_kind, 2800a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org length, NULL); 2801a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org } 280294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 2803a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org if (capacity == NULL) { 2804a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org capacity = AddLoadFixedArrayLength(to_elements); 2805a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org } 2806a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 2807a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); 2808a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org 2809a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HValue* key = builder.BeginBody(length, graph()->GetConstant0(), 2810a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org Token::GT); 281194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 2812a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org key = AddUncasted<HSub>(key, graph()->GetConstant1()); 2813a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org key->ClearFlag(HValue::kCanOverflow); 2814a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 2815a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HValue* element = Add<HLoadKeyed>(from_elements, key, 2816a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org static_cast<HValue*>(NULL), 2817a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org from_elements_kind, 2818a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org ALLOW_RETURN_HOLE); 2819a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org 2820a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org ElementsKind kind = (IsHoleyElementsKind(from_elements_kind) && 2821a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org IsFastSmiElementsKind(to_elements_kind)) 282253ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org ? FAST_HOLEY_ELEMENTS : to_elements_kind; 2823c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 2824a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org if (IsHoleyElementsKind(from_elements_kind) && 2825a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org from_elements_kind != to_elements_kind) { 2826a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org IfBuilder if_hole(this); 2827a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org if_hole.If<HCompareHoleAndBranch>(element); 2828a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org if_hole.Then(); 2829a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HConstant* hole_constant = IsFastDoubleElementsKind(to_elements_kind) 2830c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org ? Add<HConstant>(FixedDoubleArray::hole_nan_as_double()) 2831c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org : graph()->GetConstantHole(); 2832a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org Add<HStoreKeyed>(to_elements, key, hole_constant, kind); 2833a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org if_hole.Else(); 2834a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind); 2835a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org store->SetFlag(HValue::kAllowUndefinedAsNaN); 2836a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org if_hole.End(); 2837a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org } else { 2838a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind); 2839a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org store->SetFlag(HValue::kAllowUndefinedAsNaN); 2840a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org } 28417bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 2842a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org builder.EndBody(); 28437bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org } 2844a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org 2845a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org Counters* counters = isolate()->counters(); 2846a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org AddIncrementCounter(counters->inlined_copied_elements()); 2847a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org} 2848a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org 2849865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org 2850a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.orgHValue* HGraphBuilder::BuildCloneShallowArrayCow(HValue* boilerplate, 2851a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HValue* allocation_site, 2852a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org AllocationSiteMode mode, 2853a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org ElementsKind kind) { 285438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HAllocate* array = AllocateJSArrayObject(mode); 2855a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 285638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* map = AddLoadMap(boilerplate); 2857a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HValue* elements = AddLoadElements(boilerplate); 2858a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HValue* length = AddLoadArrayLength(boilerplate, kind); 2859a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 286038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org BuildJSArrayHeader(array, 286138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org map, 286238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org elements, 286338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org mode, 286438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org FAST_ELEMENTS, 286538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org allocation_site, 286638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org length); 286738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org return array; 2868a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org} 2869a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 2870a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 2871a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.orgHValue* HGraphBuilder::BuildCloneShallowArrayEmpty(HValue* boilerplate, 2872a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HValue* allocation_site, 2873a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org AllocationSiteMode mode) { 287438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HAllocate* array = AllocateJSArrayObject(mode); 2875a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 287638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* map = AddLoadMap(boilerplate); 2877a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 287838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org BuildJSArrayHeader(array, 287938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org map, 288038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org NULL, // set elements to empty fixed array 288138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org mode, 288238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org FAST_ELEMENTS, 288338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org allocation_site, 288438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org graph()->GetConstant0()); 288538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org return array; 2886a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org} 2887a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 2888a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 2889a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.orgHValue* HGraphBuilder::BuildCloneShallowArrayNonEmpty(HValue* boilerplate, 2890a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HValue* allocation_site, 2891a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org AllocationSiteMode mode, 2892a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org ElementsKind kind) { 2893a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HValue* boilerplate_elements = AddLoadElements(boilerplate); 2894a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HValue* capacity = AddLoadFixedArrayLength(boilerplate_elements); 289538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 289638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // Generate size calculation code here in order to make it dominate 289738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // the JSArray allocation. 289838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* elements_size = BuildCalculateElementsSize(kind, capacity); 289938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 290038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // Create empty JSArray object for now, store elimination should remove 290138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // redundant initialization of elements and length fields and at the same 290238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // time the object will be fully prepared for GC if it happens during 290338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // elements allocation. 290438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* result = BuildCloneShallowArrayEmpty( 290538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org boilerplate, allocation_site, mode); 290638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 290738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HAllocate* elements = BuildAllocateElements(kind, elements_size); 290838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 2909e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org // This function implicitly relies on the fact that the 2910e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org // FastCloneShallowArrayStub is called only for literals shorter than 291138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // JSObject::kInitialMaxFastElementArray. 2912e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org // Can't add HBoundsCheck here because otherwise the stub will eager a frame. 291338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HConstant* size_upper_bound = EstablishElementsAllocationSize( 291438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org kind, JSObject::kInitialMaxFastElementArray); 291538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org elements->set_size_upper_bound(size_upper_bound); 2916e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 291738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Add<HStoreNamedField>(result, HObjectAccess::ForElementsPointer(), elements); 2918a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 2919a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org // The allocation for the cloned array above causes register pressure on 2920a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org // machines with low register counts. Force a reload of the boilerplate 2921a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org // elements here to free up a register for the allocation to avoid unnecessary 2922a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org // spillage. 2923a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org boilerplate_elements = AddLoadElements(boilerplate); 2924a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org boilerplate_elements->SetFlag(HValue::kCantBeReplaced); 2925a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 2926a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org // Copy the elements array header. 2927a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { 2928a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); 2929a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org Add<HStoreNamedField>(elements, access, 2930a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org Add<HLoadNamedField>(boilerplate_elements, 293138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org static_cast<HValue*>(NULL), access)); 2932a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org } 2933a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 2934a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org // And the result of the length 293538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* length = AddLoadArrayLength(boilerplate, kind); 293638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Add<HStoreNamedField>(result, HObjectAccess::ForArrayLength(kind), length); 2937a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 293838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org BuildCopyElements(boilerplate_elements, kind, elements, 2939a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org kind, length, NULL); 2940a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org return result; 2941a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org} 2942a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 2943a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org 2944ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvoid HGraphBuilder::BuildCompareNil( 2945ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org HValue* value, 29466d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* type, 2947ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org HIfContinuation* continuation) { 294871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org IfBuilder if_nil(this); 2949ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org bool some_case_handled = false; 2950ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org bool some_case_missing = false; 2951ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org 295241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (type->Maybe(Type::Null())) { 2953ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org if (some_case_handled) if_nil.Or(); 2954ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull()); 2955ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org some_case_handled = true; 2956ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org } else { 2957ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org some_case_missing = true; 2958ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 2959ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org 296041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (type->Maybe(Type::Undefined())) { 2961ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org if (some_case_handled) if_nil.Or(); 2962ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if_nil.If<HCompareObjectEqAndBranch>(value, 2963ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org graph()->GetConstantUndefined()); 2964ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org some_case_handled = true; 2965ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org } else { 2966ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org some_case_missing = true; 2967ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 2968ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org 296941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (type->Maybe(Type::Undetectable())) { 2970ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org if (some_case_handled) if_nil.Or(); 2971ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if_nil.If<HIsUndetectableAndBranch>(value); 2972ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org some_case_handled = true; 2973ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } else { 2974ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org some_case_missing = true; 2975ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org } 2976ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org 2977ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org if (some_case_missing) { 2978ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if_nil.Then(); 2979ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if_nil.Else(); 298041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (type->NumClasses() == 1) { 29811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org BuildCheckHeapObject(value); 2982ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // For ICs, the map checked below is a sentinel map that gets replaced by 2983ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // the monomorphic map when the code is used as a template to generate a 2984ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // new IC. For optimized functions, there is no sentinel map, the map 2985ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // emitted below is the actual monomorphic map. 2986af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org Add<HCheckMaps>(value, type->Classes().Current()); 2987ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } else { 2988594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if_nil.Deopt("Too many undetectable types"); 2989ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 2990ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 2991ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2992ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if_nil.CaptureContinuation(continuation); 2993ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 2994ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2995ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2996ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.orgvoid HGraphBuilder::BuildCreateAllocationMemento( 2997ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org HValue* previous_object, 2998ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org HValue* previous_object_size, 2999ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org HValue* allocation_site) { 3000ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org ASSERT(allocation_site != NULL); 3001ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org HInnerAllocatedObject* allocation_memento = Add<HInnerAllocatedObject>( 3002eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org previous_object, previous_object_size, HType::HeapObject()); 3003ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org AddStoreMapConstant( 3004ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org allocation_memento, isolate()->factory()->allocation_memento_map()); 3005ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Add<HStoreNamedField>( 30060a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org allocation_memento, 30070a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HObjectAccess::ForAllocationMementoSite(), 30080a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org allocation_site); 3009ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (FLAG_allocation_site_pretenuring) { 3010ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org HValue* memento_create_count = Add<HLoadNamedField>( 301109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org allocation_site, static_cast<HValue*>(NULL), 301209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HObjectAccess::ForAllocationSiteOffset( 30134ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org AllocationSite::kPretenureCreateCountOffset)); 3014ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org memento_create_count = AddUncasted<HAdd>( 3015ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org memento_create_count, graph()->GetConstant1()); 3016afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org // This smi value is reset to zero after every gc, overflow isn't a problem 3017afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org // since the counter is bounded by the new space size. 3018afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org memento_create_count->ClearFlag(HValue::kCanOverflow); 30196a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Add<HStoreNamedField>( 3020ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org allocation_site, HObjectAccess::ForAllocationSiteOffset( 30210a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org AllocationSite::kPretenureCreateCountOffset), memento_create_count); 3022ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 3023ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 3024ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3025ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3026034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.orgHInstruction* HGraphBuilder::BuildGetNativeContext(HValue* closure) { 3027034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org // Get the global context, then the native context 3028034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org HInstruction* context = 302909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org Add<HLoadNamedField>(closure, static_cast<HValue*>(NULL), 303009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HObjectAccess::ForFunctionContextPointer()); 303109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HInstruction* global_object = Add<HLoadNamedField>( 303209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org context, static_cast<HValue*>(NULL), 3033034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 30340a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( 3035034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org GlobalObject::kNativeContextOffset); 303609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org return Add<HLoadNamedField>( 303709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org global_object, static_cast<HValue*>(NULL), access); 3038034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org} 3039034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org 3040034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org 3041d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgHInstruction* HGraphBuilder::BuildGetNativeContext() { 3042a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org // Get the global context, then the native context 304305150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org HValue* global_object = Add<HLoadNamedField>( 304409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org context(), static_cast<HValue*>(NULL), 304509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 304605150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org return Add<HLoadNamedField>( 304709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org global_object, static_cast<HValue*>(NULL), 30480a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HObjectAccess::ForObservableJSObjectOffset( 30490a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org GlobalObject::kNativeContextOffset)); 305057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org} 305157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 305257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 3053d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgHInstruction* HGraphBuilder::BuildGetArrayFunction() { 3054d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HInstruction* native_context = BuildGetNativeContext(); 30551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* index = 30561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX)); 30571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return Add<HLoadKeyed>( 30581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 305957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org} 306057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 306157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 3062ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgHGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, 30631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ElementsKind kind, 30641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HValue* allocation_site_payload, 30651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HValue* constructor_function, 30661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org AllocationSiteOverrideMode override_mode) : 3067ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org builder_(builder), 3068ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org kind_(kind), 3069d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org allocation_site_payload_(allocation_site_payload), 30701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org constructor_function_(constructor_function) { 307143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org ASSERT(!allocation_site_payload->IsConstant() || 307243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org HConstant::cast(allocation_site_payload)->handle( 307343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org builder_->isolate())->IsAllocationSite()); 30741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org mode_ = override_mode == DISABLE_ALLOCATION_SITES 3075d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org ? DONT_TRACK_ALLOCATION_SITE 3076bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org : AllocationSite::GetMode(kind); 3077d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org} 3078d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 3079d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 3080d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgHGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, 3081d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org ElementsKind kind, 3082d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org HValue* constructor_function) : 3083d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org builder_(builder), 3084d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org kind_(kind), 3085d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org mode_(DONT_TRACK_ALLOCATION_SITE), 3086d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org allocation_site_payload_(NULL), 3087d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org constructor_function_(constructor_function) { 3088ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 3089ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3090ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3091d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgHValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() { 3092b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (!builder()->top_info()->IsStub()) { 3093b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // A constant map is fine. 3094b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<Map> map(builder()->isolate()->get_initial_js_array_map(kind_), 3095b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org builder()->isolate()); 3096b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org return builder()->Add<HConstant>(map); 3097b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 3098b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 3099ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (constructor_function_ != NULL && kind_ == GetInitialFastElementsKind()) { 31001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // No need for a context lookup if the kind_ matches the initial 31011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // map, because we can just load the map in that case. 31021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 3103f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return builder()->Add<HLoadNamedField>( 3104f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org constructor_function_, static_cast<HValue*>(NULL), access); 31051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 3106a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 3107034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org // TODO(mvstanton): we should always have a constructor function if we 3108034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org // are creating a stub. 3109034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org HInstruction* native_context = constructor_function_ != NULL 3110034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org ? builder()->BuildGetNativeContext(constructor_function_) 3111034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org : builder()->BuildGetNativeContext(); 3112034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org 31131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* index = builder()->Add<HConstant>( 31141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); 3115a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 31161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* map_array = builder()->Add<HLoadKeyed>( 31171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 3118a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 31191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* kind_index = builder()->Add<HConstant>(kind_); 3120a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 31211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return builder()->Add<HLoadKeyed>( 31221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 3123ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 3124ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3125ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3126d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgHValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { 3127d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org // Find the map near the constructor function 3128d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 3129f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return builder()->Add<HLoadNamedField>( 3130f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org constructor_function_, static_cast<HValue*>(NULL), access); 3131d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org} 3132d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 3133d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 313438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHAllocate* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { 313538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); 313638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org return AllocateArray(capacity, 313738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org capacity, 313838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org builder()->graph()->GetConstant0()); 3139ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 3140ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3141ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 314238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( 314338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* capacity, 314438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HConstant* capacity_upper_bound, 314538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* length_field, 314638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org FillMode fill_mode) { 314738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org return AllocateArray(capacity, 314838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org capacity_upper_bound->GetInteger32Constant(), 314938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org length_field, 315038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org fill_mode); 3151ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 3152ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3153ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 315438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( 315538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* capacity, 315638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org int capacity_upper_bound, 315738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* length_field, 315838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org FillMode fill_mode) { 315938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HConstant* elememts_size_upper_bound = capacity->IsInteger32Constant() 316038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org ? HConstant::cast(capacity) 316138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org : builder()->EstablishElementsAllocationSize(kind_, capacity_upper_bound); 3162ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 316338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HAllocate* array = AllocateArray(capacity, length_field, fill_mode); 316438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org if (!elements_location_->has_size_upper_bound()) { 316538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org elements_location_->set_size_upper_bound(elememts_size_upper_bound); 316638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org } 316738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org return array; 3168ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 3169ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3170ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 317138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( 317238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* capacity, 317338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* length_field, 317438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org FillMode fill_mode) { 3175d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org // These HForceRepresentations are because we store these as fields in the 3176d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org // objects we construct, and an int32-to-smi HChange could deopt. Accept 3177d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org // the deopt possibility now, before allocation occurs. 31789af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org capacity = 31799af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org builder()->AddUncasted<HForceRepresentation>(capacity, 31809af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Representation::Smi()); 31819af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org length_field = 31829af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org builder()->AddUncasted<HForceRepresentation>(length_field, 31839af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Representation::Smi()); 3184ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 318538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // Generate size calculation code here in order to make it dominate 318638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // the JSArray allocation. 318738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HValue* elements_size = 318838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org builder()->BuildCalculateElementsSize(kind_, capacity); 318938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 319038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // Allocate (dealing with failure appropriately) 319138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org HAllocate* array_object = builder()->AllocateJSArrayObject(mode_); 3192e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org 3193ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Fill in the fields: map, properties, length 3194d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org HValue* map; 31951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (allocation_site_payload_ == NULL) { 3196d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org map = EmitInternalMapCode(); 3197d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org } else { 3198d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org map = EmitMapCode(); 3199d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org } 3200ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 320138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org builder()->BuildJSArrayHeader(array_object, 320238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org map, 320338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org NULL, // set elements to empty fixed array 320438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org mode_, 320538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org kind_, 320638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org allocation_site_payload_, 320738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org length_field); 320838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 320938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // Allocate and initialize the elements 321038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org elements_location_ = builder()->BuildAllocateElements(kind_, elements_size); 321138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 3212c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity); 3213ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 321438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // Set the elements 321538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org builder()->Add<HStoreNamedField>( 321638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org array_object, HObjectAccess::ForElementsPointer(), elements_location_); 321738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 3218b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (fill_mode == FILL_WITH_HOLE) { 3219d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org builder()->BuildFillElementsWithHole(elements_location_, kind_, 3220ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org graph()->GetConstant0(), capacity); 3221ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 3222ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 322338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org return array_object; 3224ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 3225ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3226ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3227d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgHValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin) { 322805150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org HValue* global_object = Add<HLoadNamedField>( 322909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org context(), static_cast<HValue*>(NULL), 323009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 32310a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( 3232e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org GlobalObject::kBuiltinsOffset); 323309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* builtins = Add<HLoadNamedField>( 323409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org global_object, static_cast<HValue*>(NULL), access); 32350a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HObjectAccess function_access = HObjectAccess::ForObservableJSObjectOffset( 32360a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org JSBuiltinsObject::OffsetOfFunctionWithId(builtin)); 323709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org return Add<HLoadNamedField>( 323809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org builtins, static_cast<HValue*>(NULL), function_access); 3239e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org} 3240e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 3241e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 3242c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgHOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) 3243a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org : HGraphBuilder(info), 3244a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org function_state_(NULL), 3245f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org initial_function_state_(this, info, NORMAL_RETURN, 0), 3246ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org ast_context_(NULL), 3247ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org break_scope_(NULL), 3248ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org inlined_count_(0), 32495a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org globals_(10, info->zone()), 3250c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org inline_bailout_(false), 3251c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org osr_(new(info->zone()) HOsrBuilder(this)) { 3252ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // This is not initialized in the initializer list because the 3253ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // constructor for the initial state relies on function_state_ == NULL 3254ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // to know it's the initial state. 3255ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org function_state_= &initial_function_state_; 32566d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org InitializeAstVisitor(info->zone()); 3257f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (FLAG_hydrogen_track_positions) { 325871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org SetSourcePosition(info->shared_info()->start_position()); 325971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org } 3260ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 3261a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3262a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 3263a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHBasicBlock* HOptimizedGraphBuilder::CreateJoin(HBasicBlock* first, 3264a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HBasicBlock* second, 3265a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org BailoutId join_id) { 32663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (first == NULL) { 32675d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org return second; 32683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else if (second == NULL) { 32695d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org return first; 32703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else { 3271a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HBasicBlock* join_block = graph()->CreateBasicBlock(); 327271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(first, join_block); 327371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(second, join_block); 32743a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org join_block->SetJoinId(join_id); 32755d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org return join_block; 3276a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 3277a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3278a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3280a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHBasicBlock* HOptimizedGraphBuilder::JoinContinue(IterationStatement* statement, 3281a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HBasicBlock* exit_block, 3282a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HBasicBlock* continue_block) { 3283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (continue_block != NULL) { 328471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org if (exit_block != NULL) Goto(exit_block, continue_block); 32853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org continue_block->SetJoinId(statement->ContinueId()); 32868f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org return continue_block; 3287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 32888f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org return exit_block; 3289a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3290a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3292a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHBasicBlock* HOptimizedGraphBuilder::CreateLoop(IterationStatement* statement, 3293a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HBasicBlock* loop_entry, 3294a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HBasicBlock* body_exit, 3295a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HBasicBlock* loop_successor, 3296a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HBasicBlock* break_block) { 329771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org if (body_exit != NULL) Goto(body_exit, loop_entry); 32989ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org loop_entry->PostProcessLoopHeader(statement); 32998f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org if (break_block != NULL) { 330071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org if (loop_successor != NULL) Goto(loop_successor, break_block); 33018f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org break_block->SetJoinId(statement->ExitId()); 33028f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org return break_block; 33038f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 33048f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org return loop_successor; 3305a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3306a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3308c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org// Build a new loop header block and set it as the current block. 3309c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgHBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry() { 3310c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org HBasicBlock* loop_entry = CreateLoopHeaderBlock(); 331171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(loop_entry); 3312c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org set_current_block(loop_entry); 3313c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org return loop_entry; 3314c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org} 3315c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org 3316c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org 3317c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgHBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry( 3318c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org IterationStatement* statement) { 3319c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org HBasicBlock* loop_entry = osr()->HasOsrEntryAt(statement) 3320c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org ? osr()->BuildOsrLoopEntry(statement) 3321c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org : BuildLoopEntry(); 3322c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org return loop_entry; 3323c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org} 3324c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org 3325c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org 3326f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid HBasicBlock::FinishExit(HControlInstruction* instruction, 3327f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HSourcePosition position) { 332871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Finish(instruction, position); 33295d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org ClearEnvironment(); 3330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 33335a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgHGraph::HGraph(CompilationInfo* info) 3334ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org : isolate_(info->isolate()), 3335ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org next_block_id_(0), 33364d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org entry_block_(NULL), 33375a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org blocks_(8, info->zone()), 33385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org values_(16, info->zone()), 33397028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org phi_list_(NULL), 334046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org uint32_instructions_(NULL), 3341c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org osr_(NULL), 33425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org info_(info), 33435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org zone_(info->zone()), 334446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org is_recursive_(false), 334546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org use_optimistic_licm_(false), 3346906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org depends_on_empty_array_proto_elements_(false), 3347d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org type_change_checksum_(0), 3348ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org maximum_environment_size_(0), 3349935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org no_side_effects_scope_count_(0), 3350f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org disallow_adding_new_values_(false), 3351f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org next_inline_id_(0), 3352f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org inlined_functions_(5, info->zone()) { 3353a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (info->IsStub()) { 335409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org HydrogenCodeStub* stub = info->code_stub(); 3355f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CodeStubInterfaceDescriptor* descriptor = stub->GetInterfaceDescriptor(); 3356a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org start_environment_ = 33576e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org new(zone_) HEnvironment(zone_, descriptor->environment_length()); 3358a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 3359f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org TraceInlinedFunction(info->shared_info(), HSourcePosition::Unknown()); 3360a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org start_environment_ = 3361a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); 3362a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 3363b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org start_environment_->set_ast_id(BailoutId::FunctionEntry()); 33644d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org entry_block_ = CreateBasicBlock(); 3365b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org entry_block_->SetInitialEnvironment(start_environment_); 3366a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3367a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3368a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3369a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHBasicBlock* HGraph::CreateBasicBlock() { 337074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org HBasicBlock* result = new(zone()) HBasicBlock(this); 33717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org blocks_.Add(result, zone()); 3372a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return result; 3373a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3374a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3375a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 33763d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.orgvoid HGraph::FinalizeUniqueness() { 337779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_gc; 33789af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate())); 3379e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org for (int i = 0; i < blocks()->length(); ++i) { 338093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { 33813d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org it.Current()->FinalizeUniqueness(); 3382e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 3383e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 3384e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 3385e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 3386e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 3387f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgint HGraph::TraceInlinedFunction( 3388f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Handle<SharedFunctionInfo> shared, 3389f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HSourcePosition position) { 3390f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!FLAG_hydrogen_track_positions) { 3391f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return 0; 3392f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 3393f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3394f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int id = 0; 3395f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org for (; id < inlined_functions_.length(); id++) { 3396f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (inlined_functions_[id].shared().is_identical_to(shared)) { 3397f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org break; 3398f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 3399f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 3400f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3401f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (id == inlined_functions_.length()) { 3402f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org inlined_functions_.Add(InlinedFunctionInfo(shared), zone()); 3403f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3404f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!shared->script()->IsUndefined()) { 3405f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Handle<Script> script(Script::cast(shared->script())); 3406f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!script->source()->IsUndefined()) { 3407f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); 3408f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PrintF(tracing_scope.file(), 3409f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org "--- FUNCTION SOURCE (%s) id{%d,%d} ---\n", 3410f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org shared->DebugName()->ToCString().get(), 3411f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org info()->optimization_id(), 3412f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org id); 3413f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3414f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org { 3415f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ConsStringIteratorOp op; 3416f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org StringCharacterStream stream(String::cast(script->source()), 3417f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org &op, 3418f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org shared->start_position()); 3419f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // fun->end_position() points to the last character in the stream. We 3420f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // need to compensate by adding one to calculate the length. 3421f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int source_len = 3422f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org shared->end_position() - shared->start_position() + 1; 3423f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org for (int i = 0; i < source_len; i++) { 3424f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (stream.HasMore()) { 3425f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PrintF(tracing_scope.file(), "%c", stream.GetNext()); 3426f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 3427f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 3428f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 3429f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3430f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PrintF(tracing_scope.file(), "\n--- END ---\n"); 3431f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 3432f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 3433f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 3434f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3435f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int inline_id = next_inline_id_++; 3436f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3437f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (inline_id != 0) { 3438f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); 3439f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PrintF(tracing_scope.file(), "INLINE (%s) id{%d,%d} AS %d AT ", 3440f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org shared->DebugName()->ToCString().get(), 3441f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org info()->optimization_id(), 3442f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org id, 3443f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org inline_id); 3444f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org position.PrintTo(tracing_scope.file()); 3445f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PrintF(tracing_scope.file(), "\n"); 3446f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 3447f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3448f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return inline_id; 3449f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 3450f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3451f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3452f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgint HGraph::SourcePositionToScriptPosition(HSourcePosition pos) { 3453f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!FLAG_hydrogen_track_positions || pos.IsUnknown()) { 3454f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return pos.raw(); 3455f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 3456f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3457f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return inlined_functions_[pos.inlining_id()].start_position() + 3458f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org pos.position(); 3459f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 3460f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3461f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 34625a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Block ordering was implemented with two mutually recursive methods, 34635a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// HGraph::Postorder and HGraph::PostorderLoopBlocks. 34645a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// The recursion could lead to stack overflow so the algorithm has been 34655a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// implemented iteratively. 34665a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// At a high level the algorithm looks like this: 34675a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// 34685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Postorder(block, loop_header) : { 34695a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// if (block has already been visited or is of another loop) return; 34705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// mark block as visited; 34715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// if (block is a loop header) { 34725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// VisitLoopMembers(block, loop_header); 34735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// VisitSuccessorsOfLoopHeader(block); 34745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// } else { 34755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// VisitSuccessors(block) 34765a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// } 34775a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// put block in result list; 34785a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// } 34795a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// 34805a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// VisitLoopMembers(block, outer_loop_header) { 34815a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// foreach (block b in block loop members) { 34825a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// VisitSuccessorsOfLoopMember(b, outer_loop_header); 34835a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// if (b is loop header) VisitLoopMembers(b); 34845a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// } 34855a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// } 34865a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// 34875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// VisitSuccessorsOfLoopMember(block, outer_loop_header) { 34885a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// foreach (block b in block successors) Postorder(b, outer_loop_header) 34895a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// } 34905a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// 34915a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// VisitSuccessorsOfLoopHeader(block) { 34925a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// foreach (block b in block successors) Postorder(b, block) 34935a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// } 34945a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// 34955a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// VisitSuccessors(block, loop_header) { 34965a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// foreach (block b in block successors) Postorder(b, loop_header) 34975a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// } 34985a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// 34995a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// The ordering is started calling Postorder(entry, NULL). 35005a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// 35015a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Each instance of PostorderProcessor represents the "stack frame" of the 35025a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// recursion, and particularly keeps the state of the loop (iteration) of the 35035a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// "Visit..." function it represents. 35045a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// To recycle memory we keep all the frames in a double linked list but 35055a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// this means that we cannot use constructors to initialize the frames. 35065a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// 35075a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgclass PostorderProcessor : public ZoneObject { 35085a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org public: 35095a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Back link (towards the stack bottom). 35105a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* parent() {return father_; } 35115a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Forward link (towards the stack top). 35125a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* child() {return child_; } 35135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HBasicBlock* block() { return block_; } 35145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HLoopInformation* loop() { return loop_; } 35155a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HBasicBlock* loop_header() { return loop_header_; } 3516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 35175a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org static PostorderProcessor* CreateEntryProcessor(Zone* zone, 351854ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org HBasicBlock* block) { 35195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* result = new(zone) PostorderProcessor(NULL); 352054ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org return result->SetupSuccessors(zone, block, NULL); 35215a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 3522a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 35235a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* PerformStep(Zone* zone, 35245a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ZoneList<HBasicBlock*>* order) { 35255a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* next = 352654ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org PerformNonBacktrackingStep(zone, order); 35275a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (next != NULL) { 35285a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return next; 35295a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } else { 353054ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org return Backtrack(zone, order); 35315a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 35325a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 3533a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 35345a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org private: 35355a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org explicit PostorderProcessor(PostorderProcessor* father) 35365a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org : father_(father), child_(NULL), successor_iterator(NULL) { } 35375a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 35385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Each enum value states the cycle whose state is kept by this instance. 35395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org enum LoopKind { 35405a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org NONE, 35415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org SUCCESSORS, 35425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org SUCCESSORS_OF_LOOP_HEADER, 35435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org LOOP_MEMBERS, 35445a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org SUCCESSORS_OF_LOOP_MEMBER 35455a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org }; 35465a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 35475a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Each "Setup..." method is like a constructor for a cycle state. 35485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* SetupSuccessors(Zone* zone, 35495a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HBasicBlock* block, 355054ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org HBasicBlock* loop_header) { 355154ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org if (block == NULL || block->IsOrdered() || 35525a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org block->parent_loop_header() != loop_header) { 35535a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org kind_ = NONE; 35545a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org block_ = NULL; 35555a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org loop_ = NULL; 35565a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org loop_header_ = NULL; 35575a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return this; 35585a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } else { 35595a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org block_ = block; 35605a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org loop_ = NULL; 356154ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org block->MarkAsOrdered(); 35625a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 35635a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (block->IsLoopHeader()) { 35645a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org kind_ = SUCCESSORS_OF_LOOP_HEADER; 35655a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org loop_header_ = block; 35665a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org InitializeSuccessors(); 35675a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* result = Push(zone); 35685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return result->SetupLoopMembers(zone, block, block->loop_information(), 35695a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org loop_header); 35705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } else { 35715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ASSERT(block->IsFinished()); 35725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org kind_ = SUCCESSORS; 35735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org loop_header_ = loop_header; 35745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org InitializeSuccessors(); 35755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return this; 35765a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 35775a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 3578a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 3579a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 35805a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* SetupLoopMembers(Zone* zone, 35815a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HBasicBlock* block, 35825a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HLoopInformation* loop, 35835a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HBasicBlock* loop_header) { 35845a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org kind_ = LOOP_MEMBERS; 35855a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org block_ = block; 35865a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org loop_ = loop; 35875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org loop_header_ = loop_header; 35885a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org InitializeLoopMembers(); 35895a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return this; 35905a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 3591a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 35925a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* SetupSuccessorsOfLoopMember( 35935a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HBasicBlock* block, 35945a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HLoopInformation* loop, 35955a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HBasicBlock* loop_header) { 35965a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org kind_ = SUCCESSORS_OF_LOOP_MEMBER; 35975a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org block_ = block; 35985a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org loop_ = loop; 35995a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org loop_header_ = loop_header; 36005a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org InitializeSuccessors(); 36015a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return this; 36025a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 36035a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 36045a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // This method "allocates" a new stack frame. 36055a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* Push(Zone* zone) { 36065a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (child_ == NULL) { 36075a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org child_ = new(zone) PostorderProcessor(this); 36085a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 36095a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return child_; 36105a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 36115a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 36125a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org void ClosePostorder(ZoneList<HBasicBlock*>* order, Zone* zone) { 36135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ASSERT(block_->end()->FirstSuccessor() == NULL || 36145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org order->Contains(block_->end()->FirstSuccessor()) || 36155a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org block_->end()->FirstSuccessor()->IsLoopHeader()); 36165a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ASSERT(block_->end()->SecondSuccessor() == NULL || 36175a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org order->Contains(block_->end()->SecondSuccessor()) || 36185a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org block_->end()->SecondSuccessor()->IsLoopHeader()); 36195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org order->Add(block_, zone); 36205a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 36215a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 36225a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // This method is the basic block to walk up the stack. 36235a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* Pop(Zone* zone, 36245a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ZoneList<HBasicBlock*>* order) { 36255a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org switch (kind_) { 36265a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org case SUCCESSORS: 36275a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org case SUCCESSORS_OF_LOOP_HEADER: 36285a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ClosePostorder(order, zone); 36295a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return father_; 36305a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org case LOOP_MEMBERS: 36315a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return father_; 36325a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org case SUCCESSORS_OF_LOOP_MEMBER: 36335a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (block()->IsLoopHeader() && block() != loop_->loop_header()) { 36345a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // In this case we need to perform a LOOP_MEMBERS cycle so we 36355a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // initialize it and return this instead of father. 36365a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return SetupLoopMembers(zone, block(), 36375a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org block()->loop_information(), loop_header_); 36385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } else { 36395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return father_; 36405a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 36415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org case NONE: 36425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return father_; 36436d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org } 36445a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org UNREACHABLE(); 36455a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return NULL; 36465a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 36475a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 36485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Walks up the stack. 36495a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* Backtrack(Zone* zone, 36505a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ZoneList<HBasicBlock*>* order) { 365154ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org PostorderProcessor* parent = Pop(zone, order); 36525a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org while (parent != NULL) { 36535a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* next = 365454ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org parent->PerformNonBacktrackingStep(zone, order); 36555a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (next != NULL) { 36565a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return next; 36575a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } else { 365854ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org parent = parent->Pop(zone, order); 36595a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 3660a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 36615a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return NULL; 36625a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 36635a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 36645a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* PerformNonBacktrackingStep( 36655a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org Zone* zone, 36665a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org ZoneList<HBasicBlock*>* order) { 36675a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HBasicBlock* next_block; 36685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org switch (kind_) { 36695a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org case SUCCESSORS: 36705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org next_block = AdvanceSuccessors(); 36715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (next_block != NULL) { 36725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* result = Push(zone); 367354ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org return result->SetupSuccessors(zone, next_block, loop_header_); 36745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 36755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org break; 36765a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org case SUCCESSORS_OF_LOOP_HEADER: 36775a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org next_block = AdvanceSuccessors(); 36785a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (next_block != NULL) { 36795a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* result = Push(zone); 368054ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org return result->SetupSuccessors(zone, next_block, block()); 36815a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 36825a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org break; 36835a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org case LOOP_MEMBERS: 36845a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org next_block = AdvanceLoopMembers(); 36855a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (next_block != NULL) { 36865a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* result = Push(zone); 36875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return result->SetupSuccessorsOfLoopMember(next_block, 36885a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org loop_, loop_header_); 36895a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 36905a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org break; 36915a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org case SUCCESSORS_OF_LOOP_MEMBER: 36925a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org next_block = AdvanceSuccessors(); 36935a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (next_block != NULL) { 36945a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* result = Push(zone); 369554ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org return result->SetupSuccessors(zone, next_block, loop_header_); 36965a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 36975a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org break; 36985a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org case NONE: 36995a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return NULL; 37005a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 37015a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return NULL; 3702a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 3703a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 37045a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // The following two methods implement a "foreach b in successors" cycle. 37055a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org void InitializeSuccessors() { 37065a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org loop_index = 0; 37075a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org loop_length = 0; 37085a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org successor_iterator = HSuccessorIterator(block_->end()); 37095a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 3710a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 37115a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HBasicBlock* AdvanceSuccessors() { 37125a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (!successor_iterator.Done()) { 37135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HBasicBlock* result = successor_iterator.Current(); 37145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org successor_iterator.Advance(); 37155a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return result; 37166d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org } 37175a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return NULL; 37185a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 37195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 37205a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // The following two methods implement a "foreach b in loop members" cycle. 37215a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org void InitializeLoopMembers() { 37225a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org loop_index = 0; 37235a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org loop_length = loop_->blocks()->length(); 37245a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 37255a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 37265a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HBasicBlock* AdvanceLoopMembers() { 37275a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (loop_index < loop_length) { 37285a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HBasicBlock* result = loop_->blocks()->at(loop_index); 37295a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org loop_index++; 37305a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return result; 37315a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } else { 37325a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return NULL; 37336d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org } 3734a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 37355a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 37365a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org LoopKind kind_; 37375a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* father_; 37385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org PostorderProcessor* child_; 37395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HLoopInformation* loop_; 37405a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HBasicBlock* block_; 37415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HBasicBlock* loop_header_; 37425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org int loop_index; 37435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org int loop_length; 37445a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HSuccessorIterator successor_iterator; 37455a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org}; 37465a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 37475a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 37485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgvoid HGraph::OrderBlocks() { 37491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org CompilationPhase phase("H_Block ordering", info()); 37505a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 375154ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org#ifdef DEBUG 375254ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org // Initially the blocks must not be ordered. 375354ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org for (int i = 0; i < blocks_.length(); ++i) { 375454ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org ASSERT(!blocks_[i]->IsOrdered()); 37555a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 375654ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org#endif 375754ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org 375854ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org PostorderProcessor* postorder = 375954ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org PostorderProcessor::CreateEntryProcessor(zone(), blocks_[0]); 37605a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org blocks_.Rewind(0); 376154ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org while (postorder) { 376254ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org postorder = postorder->PerformStep(zone(), &blocks_); 376354ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org } 376454ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org 376554ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org#ifdef DEBUG 376654ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org // Now all blocks must be marked as ordered. 376754ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org for (int i = 0; i < blocks_.length(); ++i) { 376854ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org ASSERT(blocks_[i]->IsOrdered()); 376954ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org } 377054ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org#endif 377154ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org 377254ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org // Reverse block list and assign block IDs. 377354ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org for (int i = 0, j = blocks_.length(); --j >= i; ++i) { 377454ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org HBasicBlock* bi = blocks_[i]; 377554ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org HBasicBlock* bj = blocks_[j]; 377654ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org bi->set_block_id(j); 377754ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org bj->set_block_id(i); 377854ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org blocks_[i] = bj; 377954ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org blocks_[j] = bi; 37805a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 3781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3782a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3783a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3784a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HGraph::AssignDominators() { 37859a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org HPhase phase("H_Assign dominators", this); 3786a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < blocks_.length(); ++i) { 378778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org HBasicBlock* block = blocks_[i]; 378878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (block->IsLoopHeader()) { 37892c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org // Only the first predecessor of a loop header is from outside the loop. 37902c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org // All others are back edges, and thus cannot dominate the loop header. 379178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org block->AssignCommonDominator(block->predecessors()->first()); 379278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org block->AssignLoopSuccessorDominators(); 3793a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 3794c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org for (int j = blocks_[i]->predecessors()->length() - 1; j >= 0; --j) { 3795a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j)); 3796a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 3797a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 3798a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 37992c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org} 38006d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org 380146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 3802c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool HGraph::CheckArgumentsPhiUses() { 3803d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org int block_count = blocks_.length(); 3804d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org for (int i = 0; i < block_count; ++i) { 3805d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org for (int j = 0; j < blocks_[i]->phis()->length(); ++j) { 3806d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org HPhi* phi = blocks_[i]->phis()->at(j); 3807d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org // We don't support phi uses of arguments for now. 3808d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org if (phi->CheckFlag(HValue::kIsArguments)) return false; 3809d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } 3810d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } 3811d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org return true; 3812d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org} 3813d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org 3814d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org 3815c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool HGraph::CheckConstPhiUses() { 38164d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org int block_count = blocks_.length(); 38174d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org for (int i = 0; i < block_count; ++i) { 38184d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org for (int j = 0; j < blocks_[i]->phis()->length(); ++j) { 38194d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org HPhi* phi = blocks_[i]->phis()->at(j); 3820d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // Check for the hole value (from an uninitialized const). 3821d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org for (int k = 0; k < phi->OperandCount(); k++) { 3822d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org if (phi->OperandAt(k) == GetConstantHole()) return false; 3823d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } 3824a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 3825a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 3826a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return true; 3827a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3828a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3830c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid HGraph::CollectPhis() { 3831c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int block_count = blocks_.length(); 38327028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org phi_list_ = new(zone()) ZoneList<HPhi*>(block_count, zone()); 3833c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = 0; i < block_count; ++i) { 3834c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int j = 0; j < blocks_[i]->phis()->length(); ++j) { 3835c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HPhi* phi = blocks_[i]->phis()->at(j); 38367028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org phi_list_->Add(phi, zone()); 3837c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3838c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3839c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3840c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3841c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 38428f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org// Implementation of utility class to encapsulate the translation state for 38438f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org// a (possibly inlined) function. 3844a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgFunctionState::FunctionState(HOptimizedGraphBuilder* owner, 38458f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org CompilationInfo* info, 3846f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org InliningKind inlining_kind, 3847f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int inlining_id) 38488f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org : owner_(owner), 38498f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org compilation_info_(info), 38508f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org call_context_(NULL), 3851471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org inlining_kind_(inlining_kind), 38528f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org function_return_(NULL), 38538f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org test_context_(NULL), 385428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org entry_(NULL), 3855b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org arguments_object_(NULL), 385628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org arguments_elements_(NULL), 3857f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org inlining_id_(inlining_id), 3858f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org outer_source_position_(HSourcePosition::Unknown()), 38598f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org outer_(owner->function_state()) { 38608f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org if (outer_ != NULL) { 38618f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // State for an inline function. 38628f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org if (owner->ast_context()->IsTest()) { 38638f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); 38648f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); 3865d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org if_true->MarkAsInlineReturnTarget(owner->current_block()); 3866d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org if_false->MarkAsInlineReturnTarget(owner->current_block()); 3867471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org TestContext* outer_test_context = TestContext::cast(owner->ast_context()); 3868471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org Expression* cond = outer_test_context->condition(); 38698f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // The AstContext constructor pushed on the context stack. This newed 38708f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // instance is the reason that AstContext can't be BASE_EMBEDDED. 3871c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org test_context_ = new TestContext(owner, cond, if_true, if_false); 38728f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } else { 38738f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org function_return_ = owner->graph()->CreateBasicBlock(); 3874d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org function_return()->MarkAsInlineReturnTarget(owner->current_block()); 38758f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 38768f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // Set this after possibly allocating a new TestContext above. 38778f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org call_context_ = owner->ast_context(); 38788f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 38798f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 38808f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // Push on the state stack. 38818f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org owner->set_function_state(this); 3882f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3883f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (FLAG_hydrogen_track_positions) { 3884f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org outer_source_position_ = owner->source_position(); 3885f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org owner->EnterInlinedSource( 3886f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org info->shared_info()->start_position(), 3887f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org inlining_id); 3888f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org owner->SetSourcePosition(info->shared_info()->start_position()); 3889f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 38908f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org} 38918f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 38928f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 38938f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.orgFunctionState::~FunctionState() { 38948f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org delete test_context_; 38958f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org owner_->set_function_state(outer_); 3896f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3897f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (FLAG_hydrogen_track_positions) { 3898f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org owner_->set_source_position(outer_source_position_); 3899f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org owner_->EnterInlinedSource( 3900f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org outer_->compilation_info()->shared_info()->start_position(), 3901f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org outer_->inlining_id()); 3902f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 39038f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org} 39048f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 39058f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 3906a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Implementation of utility classes to represent an expression's context in 3907a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// the AST. 3908a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgAstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) 3909c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org : owner_(owner), 3910c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org kind_(kind), 3911c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org outer_(owner->ast_context()), 3912c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org for_typeof_(false) { 3913a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org owner->set_ast_context(this); // Push. 39145f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org#ifdef DEBUG 3915967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org ASSERT(owner->environment()->frame_type() == JS_FUNCTION); 39165d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org original_length_ = owner->environment()->length(); 39175f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org#endif 3918a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3919a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3920a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3921a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgAstContext::~AstContext() { 3922a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org owner_->set_ast_context(outer_); // Pop. 3923a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3924a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3925a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 39265f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgEffectContext::~EffectContext() { 39275f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org ASSERT(owner()->HasStackOverflow() || 39283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org owner()->current_block() == NULL || 3929659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org (owner()->environment()->length() == original_length_ && 3930967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org owner()->environment()->frame_type() == JS_FUNCTION)); 39315f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 39325f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 39335f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 39345f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgValueContext::~ValueContext() { 39355f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org ASSERT(owner()->HasStackOverflow() || 39363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org owner()->current_block() == NULL || 3937659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org (owner()->environment()->length() == original_length_ + 1 && 3938967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org owner()->environment()->frame_type() == JS_FUNCTION)); 39395f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 39405f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 39415f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 39425f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid EffectContext::ReturnValue(HValue* value) { 39435f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // The value is simply ignored. 39445f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 39455f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 39465f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 39475f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid ValueContext::ReturnValue(HValue* value) { 39485f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // The value is tracked in the bailout environment, and communicated 39495f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // through the environment as the result of the expression. 39508e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org if (!arguments_allowed() && value->CheckFlag(HValue::kIsArguments)) { 3951594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org owner()->Bailout(kBadValueContextForArgumentsValue); 39528e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org } 39535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org owner()->Push(value); 39545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 39555f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 39565f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 39575f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid TestContext::ReturnValue(HValue* value) { 39585f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org BuildBranch(value); 39595f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 39605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 39615f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 3962471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid EffectContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 39634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(!instr->IsControlInstruction()); 39645f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org owner()->AddInstruction(instr); 3965fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (instr->HasObservableSideEffects()) { 3966c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 3967fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 39685f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 39695f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 39705f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 3971471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid EffectContext::ReturnControl(HControlInstruction* instr, 3972471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org BailoutId ast_id) { 3973c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!instr->HasObservableSideEffects()); 39744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); 39754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); 39764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org instr->SetSuccessorAt(0, empty_true); 39774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org instr->SetSuccessorAt(1, empty_false); 397871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org owner()->FinishCurrentBlock(instr); 39794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id); 39804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org owner()->set_current_block(join); 39814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org} 39824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 39834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 3984b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid EffectContext::ReturnContinuation(HIfContinuation* continuation, 3985b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org BailoutId ast_id) { 3986b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HBasicBlock* true_branch = NULL; 3987b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HBasicBlock* false_branch = NULL; 398871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org continuation->Continue(&true_branch, &false_branch); 3989b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org if (!continuation->IsTrueReachable()) { 3990b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org owner()->set_current_block(false_branch); 3991b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } else if (!continuation->IsFalseReachable()) { 3992b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org owner()->set_current_block(true_branch); 3993b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } else { 3994b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HBasicBlock* join = owner()->CreateJoin(true_branch, false_branch, ast_id); 3995b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org owner()->set_current_block(join); 3996b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 3997b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org} 3998b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 3999b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 4000471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 40014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(!instr->IsControlInstruction()); 40028e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 4003594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return owner()->Bailout(kBadValueContextForArgumentsObjectValue); 40048e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org } 40055f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org owner()->AddInstruction(instr); 40065f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org owner()->Push(instr); 4007fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (instr->HasObservableSideEffects()) { 4008c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 4009fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 40105f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 40115f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 40125f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 4013471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { 4014c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!instr->HasObservableSideEffects()); 40154f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 4016594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return owner()->Bailout(kBadValueContextForArgumentsObjectValue); 40174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 40184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock(); 40194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock(); 40204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org instr->SetSuccessorAt(0, materialize_true); 40214f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org instr->SetSuccessorAt(1, materialize_false); 402271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org owner()->FinishCurrentBlock(instr); 40234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org owner()->set_current_block(materialize_true); 40244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org owner()->Push(owner()->graph()->GetConstantTrue()); 40254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org owner()->set_current_block(materialize_false); 40264f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org owner()->Push(owner()->graph()->GetConstantFalse()); 40274f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HBasicBlock* join = 40284f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org owner()->CreateJoin(materialize_true, materialize_false, ast_id); 40294f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org owner()->set_current_block(join); 40304f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org} 40314f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 40324f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 4033b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid ValueContext::ReturnContinuation(HIfContinuation* continuation, 4034b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org BailoutId ast_id) { 4035b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HBasicBlock* materialize_true = NULL; 4036b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HBasicBlock* materialize_false = NULL; 403771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org continuation->Continue(&materialize_true, &materialize_false); 4038b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org if (continuation->IsTrueReachable()) { 4039b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org owner()->set_current_block(materialize_true); 4040b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org owner()->Push(owner()->graph()->GetConstantTrue()); 4041b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org owner()->set_current_block(materialize_true); 4042b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 4043b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org if (continuation->IsFalseReachable()) { 4044b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org owner()->set_current_block(materialize_false); 4045b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org owner()->Push(owner()->graph()->GetConstantFalse()); 4046b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org owner()->set_current_block(materialize_false); 4047b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 4048b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org if (continuation->TrueAndFalseReachable()) { 4049b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HBasicBlock* join = 4050b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org owner()->CreateJoin(materialize_true, materialize_false, ast_id); 4051b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org owner()->set_current_block(join); 4052b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 4053b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org} 4054b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 4055b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 4056471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 40574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(!instr->IsControlInstruction()); 4058a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HOptimizedGraphBuilder* builder = owner(); 40595f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org builder->AddInstruction(instr); 40605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // We expect a simulate after every expression with side effects, though 40615f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // this one isn't actually needed (and wouldn't work if it were targeted). 4062c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->HasObservableSideEffects()) { 40635f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org builder->Push(instr); 4064c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org builder->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 40655f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org builder->Pop(); 40665f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 40675f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org BuildBranch(instr); 40685f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 40695f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 40705f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 4071471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { 4072c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!instr->HasObservableSideEffects()); 40734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); 40744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); 40754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org instr->SetSuccessorAt(0, empty_true); 40764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org instr->SetSuccessorAt(1, empty_false); 407771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org owner()->FinishCurrentBlock(instr); 407871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org owner()->Goto(empty_true, if_true(), owner()->function_state()); 407971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org owner()->Goto(empty_false, if_false(), owner()->function_state()); 40804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org owner()->set_current_block(NULL); 40814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org} 40824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 40834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 4084b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid TestContext::ReturnContinuation(HIfContinuation* continuation, 4085b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org BailoutId ast_id) { 4086b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HBasicBlock* true_branch = NULL; 4087b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HBasicBlock* false_branch = NULL; 408871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org continuation->Continue(&true_branch, &false_branch); 4089b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org if (continuation->IsTrueReachable()) { 409071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org owner()->Goto(true_branch, if_true(), owner()->function_state()); 4091b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 4092b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org if (continuation->IsFalseReachable()) { 409371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org owner()->Goto(false_branch, if_false(), owner()->function_state()); 4094b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 4095b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org owner()->set_current_block(NULL); 4096b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org} 4097b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 4098b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org 40995f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid TestContext::BuildBranch(HValue* value) { 41005f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // We expect the graph to be in edge-split form: there is no edge that 41015f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // connects a branch node to a join node. We conservatively ensure that 41025f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // property by always adding an empty block on the outgoing edges of this 41035f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // branch. 4104a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HOptimizedGraphBuilder* builder = owner(); 41054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { 4106594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org builder->Bailout(kArgumentsObjectValueInATestContext); 41078e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org } 4108c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org ToBooleanStub::Types expected(condition()->to_boolean_types()); 4109cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org ReturnControl(owner()->New<HBranch>(value, expected), BailoutId::None()); 41105f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 41115f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 4112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4113a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// HOptimizedGraphBuilder infrastructure for bailing out and checking bailouts. 4114160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org#define CHECK_BAILOUT(call) \ 4115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org do { \ 4116160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org call; \ 4117a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (HasStackOverflow()) return; \ 4118a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } while (false) 4119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4120a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4121160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org#define CHECK_ALIVE(call) \ 41225f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org do { \ 4123160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org call; \ 4124160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (HasStackOverflow() || current_block() == NULL) return; \ 41255f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } while (false) 41265f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 41275f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 4128b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org#define CHECK_ALIVE_OR_RETURN(call, value) \ 4129b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org do { \ 4130b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org call; \ 4131b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (HasStackOverflow() || current_block() == NULL) return value; \ 4132b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } while (false) 4133b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 4134b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 4135594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid HOptimizedGraphBuilder::Bailout(BailoutReason reason) { 413641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org current_info()->set_bailout_reason(reason); 4137a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org SetStackOverflow(); 4138a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4139a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4140a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4141a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitForEffect(Expression* expr) { 41425f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org EffectContext for_effect(this); 41435f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Visit(expr); 4144a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4146a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4147a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitForValue(Expression* expr, 4148a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ArgumentsAllowedFlag flag) { 41498e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org ValueContext for_value(this, flag); 41505f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Visit(expr); 41515f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 41525f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 41535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 4154a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitForTypeOf(Expression* expr) { 41558e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); 4156c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org for_value.set_for_typeof(true); 4157c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org Visit(expr); 4158c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org} 4159c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 4160c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 4161a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitForControl(Expression* expr, 4162a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HBasicBlock* true_block, 4163a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HBasicBlock* false_block) { 4164c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org TestContext for_test(this, expr, true_block, false_block); 41655f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Visit(expr); 4166a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4167a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4168a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4169a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitExpressions( 4170a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ZoneList<Expression*>* exprs) { 41713a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org for (int i = 0; i < exprs->length(); ++i) { 4172160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(exprs->at(i))); 4173a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4174a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4175a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4176a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4177a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgbool HOptimizedGraphBuilder::BuildGraph() { 417841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (current_info()->function()->is_generator()) { 4179594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Bailout(kFunctionIsAGenerator); 4180f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org return false; 4181f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } 418241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Scope* scope = current_info()->scope(); 4183a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (scope->HasIllegalRedeclaration()) { 4184594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Bailout(kFunctionWithIllegalRedeclaration); 4185a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return false; 4186a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 4187a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (scope->calls_eval()) { 4188594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Bailout(kFunctionCallsEval); 4189a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return false; 4190a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 4191a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org SetUpScope(scope); 4192a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 4193a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Add an edge to the body entry. This is warty: the graph's start 4194a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // environment will be used by the Lithium translation as the initial 4195a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // environment on graph entry, but it has now been mutated by the 4196a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Hydrogen translation of the instructions in the start block. This 4197a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // environment uses values which have not been defined yet. These 4198a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Hydrogen instructions will then be replayed by the Lithium 4199a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // translation, so they cannot have an environment effect. The edge to 4200a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // the body's entry block (along with some special logic for the start 4201a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // block in HInstruction::InsertAfter) seals the start block from 4202a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // getting unwanted instructions inserted. 4203a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // 4204a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // TODO(kmillikin): Fix this. Stop mutating the initial environment. 4205a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Make the Hydrogen instructions in the initial block into Hydrogen 4206a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // values (but not instructions), present in the initial environment and 4207a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // not replayed by the Lithium translation. 4208a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HEnvironment* initial_env = environment()->CopyWithoutHistory(); 4209b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HBasicBlock* body_entry = CreateBasicBlock(initial_env); 421071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(body_entry); 4211a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org body_entry->SetJoinId(BailoutId::FunctionEntry()); 4212a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org set_current_block(body_entry); 4213a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 4214a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Handle implicit declaration of the function name in named function 4215a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // expressions before other declarations. 4216a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (scope->is_function_scope() && scope->function() != NULL) { 4217a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org VisitVariableDeclaration(scope->function()); 4218a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 4219a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org VisitDeclarations(scope->declarations()); 4220c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HSimulate>(BailoutId::Declarations()); 4221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 42228e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org Add<HStackCheck>(HStackCheck::kFunctionEntry); 422332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 422441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org VisitStatements(current_info()->function()->body()); 4225a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (HasStackOverflow()) return false; 422628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org 4227a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (current_block() != NULL) { 4228c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HReturn>(graph()->GetConstantUndefined()); 4229a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org set_current_block(NULL); 42305323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org } 42315323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org 4232a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // If the checksum of the number of type info changes is the same as the 4233a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // last time this function was compiled, then this recompile is likely not 4234a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // due to missing/inadequate type feedback, but rather too aggressive 4235a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // optimization. Disable optimistic LICM in that case. 423641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Code> unoptimized_code(current_info()->shared_info()->code()); 4237a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ASSERT(unoptimized_code->kind() == Code::FUNCTION); 4238a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<TypeFeedbackInfo> type_info( 4239a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); 4240a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int checksum = type_info->own_type_change_checksum(); 4241a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int composite_checksum = graph()->update_type_change_checksum(checksum); 4242a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org graph()->set_use_optimistic_licm( 4243a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org !type_info->matches_inlined_type_change_checksum(composite_checksum)); 4244a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org type_info->set_inlined_type_change_checksum(composite_checksum); 4245a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 4246c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // Perform any necessary OSR-specific cleanups or changes to the graph. 4247c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org osr()->FinishGraph(); 4248c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 4249a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return true; 42505323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org} 425132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 4252a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 4253594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgbool HGraph::Optimize(BailoutReason* bailout_reason) { 425428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org OrderBlocks(); 425528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org AssignDominators(); 4256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 42577c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // We need to create a HConstant "zero" now so that GVN will fold every 42587c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // zero-valued constant in the graph together. 42597c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // The constant is needed to make idef-based bounds check work: the pass 42607c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // evaluates relations with "zero" and that zero cannot be created after GVN. 42617c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org GetConstant0(); 42627c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 4263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef DEBUG 4264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Do a full verify after building the graph and computing dominators. 426528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org Verify(true); 4266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 4267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 42681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (FLAG_analyze_environment_liveness && maximum_environment_size() != 0) { 42691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Run<HEnvironmentLivenessAnalysisPhase>(); 4270d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org } 4271d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 427228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org if (!CheckConstPhiUses()) { 4273594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org *bailout_reason = kUnsupportedPhiUseOfConstVariable; 427428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org return false; 4275d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org } 4276e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org Run<HRedundantPhiEliminationPhase>(); 427728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org if (!CheckArgumentsPhiUses()) { 4278594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org *bailout_reason = kUnsupportedPhiUseOfArguments; 427928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org return false; 4280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 42814e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 4282d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // Find and mark unreachable code to simplify optimizations, especially gvn, 4283d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // where unreachable code could unnecessarily defeat LICM. 4284d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Run<HMarkUnreachableBlocksPhase>(); 4285d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 4286e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>(); 4287594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (FLAG_use_escape_analysis) Run<HEscapeAnalysisPhase>(); 4288594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 4289528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (FLAG_load_elimination) Run<HLoadEliminationPhase>(); 4290528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 429128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org CollectPhis(); 4292a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4293c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (has_osr()) osr()->FinishOsrValues(); 42942c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org 42951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Run<HInferRepresentationPhase>(); 4296a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4297fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Remove HSimulate instructions that have turned out not to be needed 4298fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // after all by folding them into the following HSimulate. 4299fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // This must happen after inferring representations. 4300169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org Run<HMergeRemovableSimulatesPhase>(); 4301fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 4302d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Run<HMarkDeoptimizeOnUndefinedPhase>(); 4303bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Run<HRepresentationChangesPhase>(); 4304a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4305e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org Run<HInferTypesPhase>(); 430646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 430746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Must be performed before canonicalization to ensure that Canonicalize 430846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with 430946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // zero. 431093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org if (FLAG_opt_safe_uint32_operations) Run<HUint32AnalysisPhase>(); 431146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 4312169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (FLAG_use_canonicalizing) Run<HCanonicalizePhase>(); 4313a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 43141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (FLAG_use_gvn) Run<HGlobalValueNumberingPhase>(); 4315a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4316cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org if (FLAG_check_elimination) Run<HCheckEliminationPhase>(); 4317cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org 4318b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org if (FLAG_store_elimination) Run<HStoreEliminationPhase>(); 4319b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org 4320bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org Run<HRangeAnalysisPhase>(); 4321c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 4322c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org Run<HComputeChangeUndefinedToNaN>(); 4323ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org 4324ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org // Eliminate redundant stack checks on backwards branches. 4325e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org Run<HStackCheckEliminationPhase>(); 4326ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org 4327cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org if (FLAG_array_bounds_checks_elimination) Run<HBoundsCheckEliminationPhase>(); 4328cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org if (FLAG_array_bounds_checks_hoisting) Run<HBoundsCheckHoistingPhase>(); 4329169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (FLAG_array_index_dehoisting) Run<HDehoistIndexComputationsPhase>(); 4330e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>(); 43316d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org 4332068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org RestoreActualValues(); 4333068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org 4334d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // Find unreachable code a second time, GVN and other optimizations may have 4335d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // made blocks unreachable that were previously reachable. 4336d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Run<HMarkUnreachableBlocksPhase>(); 4337d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 433828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org return true; 4339a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4340a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4341a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4342068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.orgvoid HGraph::RestoreActualValues() { 4343068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org HPhase phase("H_Restore actual values", this); 4344068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org 4345068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org for (int block_index = 0; block_index < blocks()->length(); block_index++) { 4346068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org HBasicBlock* block = blocks()->at(block_index); 4347068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org 4348068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org#ifdef DEBUG 4349068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org for (int i = 0; i < block->phis()->length(); i++) { 4350068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org HPhi* phi = block->phis()->at(i); 4351068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org ASSERT(phi->ActualValue() == phi); 4352068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org } 4353068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org#endif 4354068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org 435593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org for (HInstructionIterator it(block); !it.Done(); it.Advance()) { 435693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org HInstruction* instruction = it.Current(); 435705150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org if (instruction->ActualValue() == instruction) continue; 435805150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org if (instruction->CheckFlag(HValue::kIsDead)) { 435905150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org // The instruction was marked as deleted but left in the graph 436005150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org // as a control flow dependency point for subsequent 436105150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org // instructions. 436205150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org instruction->DeleteAndReplaceWith(instruction->ActualValue()); 436305150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org } else { 43642e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org ASSERT(instruction->IsInformativeDefinition()); 43652e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org if (instruction->IsPurelyInformativeDefinition()) { 43662e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); 43672e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org } else { 43682e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org instruction->ReplaceAllUsesWith(instruction->ActualValue()); 43692e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org } 4370068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org } 4371068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org } 4372068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org } 4373068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org} 4374068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org 4375068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org 437626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgvoid HOptimizedGraphBuilder::PushArgumentsFromEnvironment(int count) { 43777028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<HValue*> arguments(count, zone()); 4378496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org for (int i = 0; i < count; ++i) { 43797028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org arguments.Add(Pop(), zone()); 4380a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4381a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 43828d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org HPushArguments* push_args = New<HPushArguments>(); 4383496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org while (!arguments.is_empty()) { 43848d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org push_args->AddInput(arguments.RemoveLast()); 4385a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4386011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org AddInstruction(push_args); 438726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org} 438826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 438926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 439026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgtemplate <class Instruction> 439126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgHInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { 439226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org PushArgumentsFromEnvironment(call->argument_count()); 43933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return call; 4394a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4395a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4396a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4397a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::SetUpScope(Scope* scope) { 4398d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org // First special is HContext. 4399d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HInstruction* context = Add<HContext>(); 4400d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org environment()->BindContext(context); 4401d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 4402b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Create an arguments object containing the initial parameters. Set the 4403b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // initial values of parameters including "this" having parameter index 0. 440483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); 4405b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org HArgumentsObject* arguments_object = 4406d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org New<HArgumentsObject>(environment()->parameter_count()); 440783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org for (int i = 0; i < environment()->parameter_count(); ++i) { 44081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* parameter = Add<HParameter>(i); 4409b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org arguments_object->AddArgument(parameter, zone()); 4410a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org environment()->Bind(i, parameter); 4411a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4412b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org AddInstruction(arguments_object); 4413b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org graph()->SetArgumentsObject(arguments_object); 4414a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 441571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org HConstant* undefined_constant = graph()->GetConstantUndefined(); 441683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Initialize specials and locals to undefined. 441783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org for (int i = environment()->parameter_count() + 1; 441883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org i < environment()->length(); 441983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ++i) { 4420a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org environment()->Bind(i, undefined_constant); 4421a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4422a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4423a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Handle the arguments and arguments shadow variables specially (they do 4424a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // not have declarations). 4425a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (scope->arguments() != NULL) { 44267b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org if (!scope->arguments()->IsStackAllocated()) { 4427594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kContextAllocatedArguments); 44283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 4429154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 4430154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org environment()->Bind(scope->arguments(), 4431154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org graph()->GetArgumentsObject()); 4432a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4433a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4434a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4435a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4436a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { 4437a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < statements->length(); i++) { 4438dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org Statement* stmt = statements->at(i); 4439dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org CHECK_ALIVE(Visit(stmt)); 4440dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org if (stmt->IsJump()) break; 4441a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4442a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4443a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4444a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4445a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitBlock(Block* stmt) { 4446160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 4447160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 4448160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 44491e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org 44501e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org Scope* outer_scope = scope(); 44511e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org Scope* scope = stmt->scope(); 44521e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org BreakAndContinueInfo break_info(stmt, outer_scope); 44531e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org 44548f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org { BreakAndContinueScope push(&break_info, this); 44551e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org if (scope != NULL) { 44561e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org // Load the function object. 44571e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org Scope* declaration_scope = scope->DeclarationScope(); 44581e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HInstruction* function; 44591e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HValue* outer_context = environment()->context(); 44601e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org if (declaration_scope->is_global_scope() || 44611e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org declaration_scope->is_eval_scope()) { 44621e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org function = new(zone()) HLoadContextSlot( 44631e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org outer_context, Context::CLOSURE_INDEX, HLoadContextSlot::kNoCheck); 44641e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } else { 44651e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org function = New<HThisFunction>(); 44661e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 44671e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org AddInstruction(function); 44681e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org // Allocate a block context and store it to the stack frame. 44691e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HInstruction* inner_context = Add<HAllocateBlockContext>( 44701e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org outer_context, function, scope->GetScopeInfo()); 44711e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HInstruction* instr = Add<HStoreFrameContext>(inner_context); 44721e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org if (instr->HasObservableSideEffects()) { 44731e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org AddSimulate(stmt->EntryId(), REMOVABLE_SIMULATE); 44741e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 44751e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org set_scope(scope); 44761e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org environment()->BindContext(inner_context); 44771e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org VisitDeclarations(scope->declarations()); 44781e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org AddSimulate(stmt->DeclsId(), REMOVABLE_SIMULATE); 44791e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 4480160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_BAILOUT(VisitStatements(stmt->statements())); 44818f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 44821e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org set_scope(outer_scope); 44831e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org if (scope != NULL && current_block() != NULL) { 44841e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HValue* inner_context = environment()->context(); 44851e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HValue* outer_context = Add<HLoadNamedField>( 44861e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org inner_context, static_cast<HValue*>(NULL), 44871e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 44881e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org 44891e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HInstruction* instr = Add<HStoreFrameContext>(outer_context); 44901e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org if (instr->HasObservableSideEffects()) { 44911e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org AddSimulate(stmt->ExitId(), REMOVABLE_SIMULATE); 44921e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 44931e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org environment()->BindContext(outer_context); 44941e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 44958f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* break_block = break_info.break_block(); 44968f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org if (break_block != NULL) { 449771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org if (current_block() != NULL) Goto(break_block); 44988f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org break_block->SetJoinId(stmt->ExitId()); 44998f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org set_current_block(break_block); 4500a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4501a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4504a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitExpressionStatement( 4505a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ExpressionStatement* stmt) { 4506160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 4507160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 4508160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 4509a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org VisitForEffect(stmt->expression()); 4510a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4511a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4512a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4513a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) { 4514160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 4515160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 4516160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 4517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4518a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4519a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4520a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) { 4521160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 4522160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 4523160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 4524a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (stmt->condition()->ToBooleanIsTrue()) { 4525c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HSimulate>(stmt->ThenId()); 4526a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Visit(stmt->then_statement()); 4527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (stmt->condition()->ToBooleanIsFalse()) { 4528c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HSimulate>(stmt->ElseId()); 4529a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Visit(stmt->else_statement()); 4530a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 45318f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* cond_true = graph()->CreateBasicBlock(); 45328f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* cond_false = graph()->CreateBasicBlock(); 4533160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_BAILOUT(VisitForControl(stmt->condition(), cond_true, cond_false)); 45345f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 4535160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (cond_true->HasPredecessor()) { 4536160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org cond_true->SetJoinId(stmt->ThenId()); 4537160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org set_current_block(cond_true); 4538160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_BAILOUT(Visit(stmt->then_statement())); 4539160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org cond_true = current_block(); 4540160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else { 4541160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org cond_true = NULL; 4542160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 45435f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 4544160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (cond_false->HasPredecessor()) { 4545160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org cond_false->SetJoinId(stmt->ElseId()); 4546160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org set_current_block(cond_false); 4547160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_BAILOUT(Visit(stmt->else_statement())); 4548160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org cond_false = current_block(); 4549160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else { 4550160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org cond_false = NULL; 4551160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 45525f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 4553d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId()); 45548f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org set_current_block(join); 45553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 45563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 45573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 45583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 4559a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get( 45603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org BreakableStatement* stmt, 4561be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org BreakType type, 45621e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org Scope** scope, 4563be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org int* drop_extra) { 4564be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org *drop_extra = 0; 45653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org BreakAndContinueScope* current = this; 45663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org while (current != NULL && current->info()->target() != stmt) { 4567be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org *drop_extra += current->info()->drop_extra(); 45683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org current = current->next(); 45693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 45703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(current != NULL); // Always found (unless stack is malformed). 45711e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org *scope = current->info()->scope(); 4572be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 4573be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org if (type == BREAK) { 4574be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org *drop_extra += current->info()->drop_extra(); 4575be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org } 4576be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 45773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org HBasicBlock* block = NULL; 45783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org switch (type) { 45793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org case BREAK: 45803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org block = current->info()->break_block(); 45813a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (block == NULL) { 45823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org block = current->owner()->graph()->CreateBasicBlock(); 45833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org current->info()->set_break_block(block); 45843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 45853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org break; 45863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 45873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org case CONTINUE: 45883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org block = current->info()->continue_block(); 45893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (block == NULL) { 45903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org block = current->owner()->graph()->CreateBasicBlock(); 45913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org current->info()->set_continue_block(block); 45923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 45933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org break; 4594a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 45953a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 45963a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return block; 4597a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4598a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4599a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4600a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitContinueStatement( 4601a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ContinueStatement* stmt) { 4602160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 4603160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 4604160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 46051e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org Scope* outer_scope = NULL; 46061e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org Scope* inner_scope = scope(); 4607be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org int drop_extra = 0; 4608c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org HBasicBlock* continue_block = break_scope()->Get( 46091e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org stmt->target(), BreakAndContinueScope::CONTINUE, 46101e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org &outer_scope, &drop_extra); 46111e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HValue* context = environment()->context(); 4612be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Drop(drop_extra); 46131e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org int context_pop_count = inner_scope->ContextChainLength(outer_scope); 46141e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org if (context_pop_count > 0) { 46151e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org while (context_pop_count-- > 0) { 46161e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HInstruction* context_instruction = Add<HLoadNamedField>( 46171e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org context, static_cast<HValue*>(NULL), 46181e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 46191e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org context = context_instruction; 46201e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 46211e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HInstruction* instr = Add<HStoreFrameContext>(context); 46221e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org if (instr->HasObservableSideEffects()) { 46231e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org AddSimulate(stmt->target()->EntryId(), REMOVABLE_SIMULATE); 46241e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 46251e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org environment()->BindContext(context); 46261e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 46271e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org 462871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(continue_block); 46293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org set_current_block(NULL); 4630a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4631a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4632a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4633a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { 4634160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 4635160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 4636160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 46371e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org Scope* outer_scope = NULL; 46381e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org Scope* inner_scope = scope(); 4639be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org int drop_extra = 0; 4640c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org HBasicBlock* break_block = break_scope()->Get( 46411e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org stmt->target(), BreakAndContinueScope::BREAK, 46421e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org &outer_scope, &drop_extra); 46431e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HValue* context = environment()->context(); 4644be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Drop(drop_extra); 46451e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org int context_pop_count = inner_scope->ContextChainLength(outer_scope); 46461e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org if (context_pop_count > 0) { 46471e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org while (context_pop_count-- > 0) { 46481e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HInstruction* context_instruction = Add<HLoadNamedField>( 46491e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org context, static_cast<HValue*>(NULL), 46501e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 46511e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org context = context_instruction; 46521e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 46531e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HInstruction* instr = Add<HStoreFrameContext>(context); 46541e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org if (instr->HasObservableSideEffects()) { 46551e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org AddSimulate(stmt->target()->ExitId(), REMOVABLE_SIMULATE); 46561e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 46571e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org environment()->BindContext(context); 46581e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 465971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(break_block); 46603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org set_current_block(NULL); 4661a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4662a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4663a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4664a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { 4665160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 4666160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 4667160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 4668471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org FunctionState* state = function_state(); 4669a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org AstContext* context = call_context(); 4670a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (context == NULL) { 4671a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Not an inlined return, so an actual one. 4672160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(stmt->expression())); 4673a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* result = environment()->Pop(); 4674c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HReturn>(result); 4675471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { 4676471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // Return from an inlined construct call. In a test context the return value 4677471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // will always evaluate to true, in a value context the return value needs 4678471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // to be a JSObject. 4679967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org if (context->IsTest()) { 4680967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org TestContext* test = TestContext::cast(context); 4681967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org CHECK_ALIVE(VisitForEffect(stmt->expression())); 468271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(test->if_true(), state); 4683967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org } else if (context->IsEffect()) { 4684967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org CHECK_ALIVE(VisitForEffect(stmt->expression())); 468571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(function_return(), state); 4686967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org } else { 4687967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org ASSERT(context->IsValue()); 4688967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org CHECK_ALIVE(VisitForValue(stmt->expression())); 4689967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org HValue* return_value = Pop(); 4690471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org HValue* receiver = environment()->arguments_environment()->Lookup(0); 4691967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org HHasInstanceTypeAndBranch* typecheck = 4692dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org New<HHasInstanceTypeAndBranch>(return_value, 4693dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org FIRST_SPEC_OBJECT_TYPE, 4694dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org LAST_SPEC_OBJECT_TYPE); 4695967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org HBasicBlock* if_spec_object = graph()->CreateBasicBlock(); 4696967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org HBasicBlock* not_spec_object = graph()->CreateBasicBlock(); 4697967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org typecheck->SetSuccessorAt(0, if_spec_object); 4698967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org typecheck->SetSuccessorAt(1, not_spec_object); 469971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org FinishCurrentBlock(typecheck); 470071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org AddLeaveInlined(if_spec_object, return_value, state); 470171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org AddLeaveInlined(not_spec_object, receiver, state); 4702471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 4703471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else if (state->inlining_kind() == SETTER_CALL_RETURN) { 4704471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // Return from an inlined setter call. The returned value is never used, the 4705471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // value of an assignment is always the value of the RHS of the assignment. 4706471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org CHECK_ALIVE(VisitForEffect(stmt->expression())); 4707471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (context->IsTest()) { 4708471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org HValue* rhs = environment()->arguments_environment()->Lookup(1); 4709471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org context->ReturnValue(rhs); 4710471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else if (context->IsEffect()) { 471171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(function_return(), state); 4712471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 4713471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ASSERT(context->IsValue()); 4714471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org HValue* rhs = environment()->arguments_environment()->Lookup(1); 471571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org AddLeaveInlined(rhs, state); 4716967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org } 4717a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 4718471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // Return from a normal inlined function. Visit the subexpression in the 4719a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // expression context of the call. 4720a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (context->IsTest()) { 4721a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org TestContext* test = TestContext::cast(context); 4722471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org VisitForControl(stmt->expression(), test->if_true(), test->if_false()); 47234d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org } else if (context->IsEffect()) { 4724fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // Visit in value context and ignore the result. This is needed to keep 4725fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // environment in sync with full-codegen since some visitors (e.g. 4726fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // VisitCountOperation) use the operand stack differently depending on 4727fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org // context. 4728fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org CHECK_ALIVE(VisitForValue(stmt->expression())); 4729fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Pop(); 473071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(function_return(), state); 4731a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 47324d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org ASSERT(context->IsValue()); 4733160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(stmt->expression())); 473471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org AddLeaveInlined(Pop(), state); 4735a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4736a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4737967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org set_current_block(NULL); 4738a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4739a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4740a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4741a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitWithStatement(WithStatement* stmt) { 4742160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 4743160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 4744160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 4745594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kWithStatement); 4746a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4747a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4748a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4749a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { 4750160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 4751160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 4752160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 4753c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 47544f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org // We only optimize switch statements with a bounded number of clauses. 47554d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org const int kCaseClauseLimit = 128; 4756a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ZoneList<CaseClause*>* clauses = stmt->cases(); 47574d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org int clause_count = clauses->length(); 47584f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org ZoneList<HBasicBlock*> body_blocks(clause_count, zone()); 47594d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org if (clause_count > kCaseClauseLimit) { 4760594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kSwitchStatementTooManyClauses); 47614d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org } 47624d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org 4763160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(stmt->tag())); 4764c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HSimulate>(stmt->EntryId()); 47654f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org HValue* tag_value = Top(); 47666d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* tag_type = stmt->tag()->bounds().lower; 47670ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 4768c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org // 1. Build all the tests, with dangling true branches 4769471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org BailoutId default_id = BailoutId::None(); 47700ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry for (int i = 0; i < clause_count; ++i) { 47710ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry CaseClause* clause = clauses->at(i); 477264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (clause->is_default()) { 47734f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org body_blocks.Add(NULL, zone()); 47744f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org if (default_id.IsNone()) default_id = clause->EntryId(); 477564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org continue; 477664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 4777a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 47780ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry // Generate a compare and branch. 4779160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(clause->label())); 47804d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org HValue* label_value = Pop(); 47810ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 47826d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* label_type = clause->label()->bounds().lower; 47836d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* combined_type = clause->compare_type(); 47844f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org HControlInstruction* compare = BuildCompareInstruction( 47854f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org Token::EQ_STRICT, tag_value, label_value, tag_type, label_type, 4786f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org combined_type, 4787f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ScriptPositionToSourcePosition(stmt->tag()->position()), 4788f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ScriptPositionToSourcePosition(clause->label()->position()), 4789f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PUSH_BEFORE_SIMULATE, clause->id()); 47904f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org 47914d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org HBasicBlock* next_test_block = graph()->CreateBasicBlock(); 47920ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry HBasicBlock* body_block = graph()->CreateBasicBlock(); 47934f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org body_blocks.Add(body_block, zone()); 47944f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org compare->SetSuccessorAt(0, body_block); 47954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org compare->SetSuccessorAt(1, next_test_block); 479671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org FinishCurrentBlock(compare); 47970ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 47984f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org set_current_block(body_block); 47994f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org Drop(1); // tag_value 48004f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org 48014d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org set_current_block(next_test_block); 48024d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org } 48034d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org 48044d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // Save the current block to use for the default or to join with the 4805d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org // exit. 48064d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org HBasicBlock* last_block = current_block(); 48074f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org Drop(1); // tag_value 48080ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 4809c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org // 2. Loop over the clauses and the linked list of tests in lockstep, 48104d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // translating the clause bodies. 48114d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org HBasicBlock* fall_through_block = NULL; 48120ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry 48131e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org BreakAndContinueInfo break_info(stmt, scope()); 48144d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org { BreakAndContinueScope push(&break_info, this); 48154d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org for (int i = 0; i < clause_count; ++i) { 48164d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org CaseClause* clause = clauses->at(i); 48174d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org 48184d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // Identify the block where normal (non-fall-through) control flow 48194d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // goes to. 48204d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org HBasicBlock* normal_block = NULL; 482113da64d34f16ec991f0926be7747eb17ad34a05dfschneider@chromium.org if (clause->is_default()) { 48224f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org if (last_block == NULL) continue; 48234f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org normal_block = last_block; 48244f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org last_block = NULL; // Cleared to indicate we've handled it. 4825c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } else { 48264f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org normal_block = body_blocks[i]; 48274d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org } 48285f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 48294f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org if (fall_through_block == NULL) { 48304d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org set_current_block(normal_block); 48315f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else { 48324d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org HBasicBlock* join = CreateJoin(fall_through_block, 48334d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org normal_block, 48344d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org clause->EntryId()); 48354d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org set_current_block(join); 48365f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 4837a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4838160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_BAILOUT(VisitStatements(clause->statements())); 48394d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org fall_through_block = current_block(); 4840a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4841a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4842a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 48434d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // Create an up-to-3-way join. Use the break block if it exists since 48444d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // it's already a join block. 48454d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org HBasicBlock* break_block = break_info.break_block(); 48464d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org if (break_block == NULL) { 48474d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org set_current_block(CreateJoin(fall_through_block, 48484d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org last_block, 48494d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org stmt->ExitId())); 4850a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 485171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org if (fall_through_block != NULL) Goto(fall_through_block, break_block); 485271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org if (last_block != NULL) Goto(last_block, break_block); 48534d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org break_block->SetJoinId(stmt->ExitId()); 48544d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org set_current_block(break_block); 4855a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4856a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4857a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 48584d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org 4859a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, 48601e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HBasicBlock* loop_entry) { 4861c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HSimulate>(stmt->StackCheckId()); 48628e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org HStackCheck* stack_check = 48638e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org HStackCheck::cast(Add<HStackCheck>(HStackCheck::kBackwardsBranch)); 486404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org ASSERT(loop_entry->IsLoopHeader()); 486504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org loop_entry->loop_information()->set_stack_check(stack_check); 4866ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org CHECK_BAILOUT(Visit(stmt->body())); 486704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org} 486804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org 486904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org 4870a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 4871160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 4872160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 4873160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 48743a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(current_block() != NULL); 4875c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org HBasicBlock* loop_entry = BuildLoopEntry(stmt); 4876a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 48771e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org BreakAndContinueInfo break_info(stmt, scope()); 48781e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org { 48791e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org BreakAndContinueScope push(&break_info, this); 48801e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); 48811e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 48829ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org HBasicBlock* body_exit = 48839ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org JoinContinue(stmt, current_block(), break_info.continue_block()); 48848f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* loop_successor = NULL; 48858f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { 48869ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org set_current_block(body_exit); 48878f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org loop_successor = graph()->CreateBasicBlock(); 4888034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org if (stmt->cond()->ToBooleanIsFalse()) { 4889285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org loop_entry->loop_information()->stack_check()->Eliminate(); 4890034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org Goto(loop_successor); 4891034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org body_exit = NULL; 4892034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org } else { 4893034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org // The block for a true condition, the actual predecessor block of the 4894034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org // back edge. 4895034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org body_exit = graph()->CreateBasicBlock(); 4896034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org CHECK_BAILOUT(VisitForControl(stmt->cond(), body_exit, loop_successor)); 4897034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org } 4898034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org if (body_exit != NULL && body_exit->HasPredecessor()) { 4899160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org body_exit->SetJoinId(stmt->BackEdgeId()); 4900160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else { 4901160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org body_exit = NULL; 4902160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 4903160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (loop_successor->HasPredecessor()) { 4904160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org loop_successor->SetJoinId(stmt->ExitId()); 4905160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else { 4906160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org loop_successor = NULL; 4907160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 49088f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 49098f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* loop_exit = CreateLoop(stmt, 49108f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org loop_entry, 49118f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org body_exit, 49128f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org loop_successor, 49138f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org break_info.break_block()); 49149ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org set_current_block(loop_exit); 4915a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4916a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4917a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4918a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { 4919160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 4920160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 4921160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 49223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(current_block() != NULL); 4923c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org HBasicBlock* loop_entry = BuildLoopEntry(stmt); 4924a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 49259ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // If the condition is constant true, do not generate a branch. 49268f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* loop_successor = NULL; 49279ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org if (!stmt->cond()->ToBooleanIsTrue()) { 49288f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* body_entry = graph()->CreateBasicBlock(); 49298f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org loop_successor = graph()->CreateBasicBlock(); 4930160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); 4931160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (body_entry->HasPredecessor()) { 4932160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org body_entry->SetJoinId(stmt->BodyId()); 4933160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org set_current_block(body_entry); 4934160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 4935160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (loop_successor->HasPredecessor()) { 4936160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org loop_successor->SetJoinId(stmt->ExitId()); 4937160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else { 4938160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org loop_successor = NULL; 4939160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 4940a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 4941a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 49421e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org BreakAndContinueInfo break_info(stmt, scope()); 4943160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (current_block() != NULL) { 49441e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org BreakAndContinueScope push(&break_info, this); 49451e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); 4946a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 49479ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org HBasicBlock* body_exit = 49489ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org JoinContinue(stmt, current_block(), break_info.continue_block()); 49498f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* loop_exit = CreateLoop(stmt, 49508f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org loop_entry, 49518f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org body_exit, 49528f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org loop_successor, 49538f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org break_info.break_block()); 49549ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org set_current_block(loop_exit); 4955a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 4956a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4957a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4958a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) { 4959160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 4960160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 4961160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 49628f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org if (stmt->init() != NULL) { 4963160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(Visit(stmt->init())); 4964a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 49653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(current_block() != NULL); 4966c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org HBasicBlock* loop_entry = BuildLoopEntry(stmt); 4967a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 49688f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* loop_successor = NULL; 4969a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (stmt->cond() != NULL) { 49708f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* body_entry = graph()->CreateBasicBlock(); 49718f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org loop_successor = graph()->CreateBasicBlock(); 4972160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); 4973160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (body_entry->HasPredecessor()) { 4974160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org body_entry->SetJoinId(stmt->BodyId()); 4975160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org set_current_block(body_entry); 4976160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 4977160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (loop_successor->HasPredecessor()) { 4978160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org loop_successor->SetJoinId(stmt->ExitId()); 4979160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else { 4980160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org loop_successor = NULL; 4981160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 4982a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 49839ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 49841e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org BreakAndContinueInfo break_info(stmt, scope()); 4985160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (current_block() != NULL) { 49861e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org BreakAndContinueScope push(&break_info, this); 49871e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); 49889ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 49899ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org HBasicBlock* body_exit = 49909ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org JoinContinue(stmt, current_block(), break_info.continue_block()); 49919ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 49929ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org if (stmt->next() != NULL && body_exit != NULL) { 49939ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org set_current_block(body_exit); 4994160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_BAILOUT(Visit(stmt->next())); 49959ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org body_exit = current_block(); 49969ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 49979ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 49988f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* loop_exit = CreateLoop(stmt, 49998f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org loop_entry, 50008f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org body_exit, 50018f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org loop_successor, 50028f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org break_info.break_block()); 50039ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org set_current_block(loop_exit); 5004a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5005a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5006a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5007a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { 5008160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 5009160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 5010160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 5011be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5012a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org if (!FLAG_optimize_for_in) { 5013594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kForInStatementOptimizationIsDisabled); 5014a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org } 5015a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org 5016c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org if (stmt->for_in_type() != ForInStatement::FAST_FOR_IN) { 5017594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kForInStatementIsNotFastCase); 50189a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org } 50199a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 5020be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org if (!stmt->each()->IsVariableProxy() || 5021be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) { 5022594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kForInStatementWithNonLocalEachVariable); 5023be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org } 5024be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5025be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Variable* each_var = stmt->each()->AsVariableProxy()->var(); 5026be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5027be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org CHECK_ALIVE(VisitForValue(stmt->enumerable())); 5028be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org HValue* enumerable = Top(); // Leave enumerable at the top. 5029be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5030d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HInstruction* map = Add<HForInPrepareMap>(enumerable); 5031c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HSimulate>(stmt->PrepareId()); 5032be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 50331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* array = Add<HForInCacheArray>( 50341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex); 5035be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 50361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* enum_length = Add<HMapEnumLength>(map); 5037be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 50381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* start_index = Add<HConstant>(0); 5039be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5040be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Push(map); 5041be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Push(array); 5042355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Push(enum_length); 5043be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Push(start_index); 5044be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 50451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* index_cache = Add<HForInCacheArray>( 50461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org enumerable, map, DescriptorArray::kEnumCacheBridgeIndicesCacheIndex); 5047be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org HForInCacheArray::cast(array)->set_index_cache( 5048be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org HForInCacheArray::cast(index_cache)); 5049be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5050c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org HBasicBlock* loop_entry = BuildLoopEntry(stmt); 5051be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5052be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org HValue* index = environment()->ExpressionStackAt(0); 5053be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org HValue* limit = environment()->ExpressionStackAt(1); 5054be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5055be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Check that we still have more keys. 5056e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org HCompareNumericAndBranch* compare_index = 5057528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org New<HCompareNumericAndBranch>(index, limit, Token::LT); 5058fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org compare_index->set_observed_input_representation( 5059b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Representation::Smi(), Representation::Smi()); 5060be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5061be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org HBasicBlock* loop_body = graph()->CreateBasicBlock(); 5062be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org HBasicBlock* loop_successor = graph()->CreateBasicBlock(); 5063be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5064be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org compare_index->SetSuccessorAt(0, loop_body); 5065be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org compare_index->SetSuccessorAt(1, loop_successor); 506671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org FinishCurrentBlock(compare_index); 5067be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5068be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org set_current_block(loop_successor); 5069be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Drop(5); 5070be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5071be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org set_current_block(loop_body); 5072be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 50731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HValue* key = Add<HLoadKeyed>( 50741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org environment()->ExpressionStackAt(2), // Enum cache. 50751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org environment()->ExpressionStackAt(0), // Iteration index. 50761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org environment()->ExpressionStackAt(0), 50771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org FAST_ELEMENTS); 5078be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5079be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Check if the expected map still matches that of the enumerable. 5080be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // If not just deoptimize. 50811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Add<HCheckMapValue>(environment()->ExpressionStackAt(4), 50821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org environment()->ExpressionStackAt(3)); 5083be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5084be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Bind(each_var, key); 5085be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 50861e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org BreakAndContinueInfo break_info(stmt, scope(), 5); 50871e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org { 50881e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org BreakAndContinueScope push(&break_info, this); 50891e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); 50901e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 5091be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5092be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org HBasicBlock* body_exit = 5093be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org JoinContinue(stmt, current_block(), break_info.continue_block()); 5094be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5095be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org if (body_exit != NULL) { 5096be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org set_current_block(body_exit); 5097be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5098be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org HValue* current_index = Pop(); 50997ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org Push(AddUncasted<HAdd>(current_index, graph()->GetConstant1())); 5100be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org body_exit = current_block(); 5101be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org } 5102be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5103be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org HBasicBlock* loop_exit = CreateLoop(stmt, 5104be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org loop_entry, 5105be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org body_exit, 5106be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org loop_successor, 5107be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org break_info.break_block()); 5108be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5109be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org set_current_block(loop_exit); 5110a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 51131fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgvoid HOptimizedGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { 51141fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ASSERT(!HasStackOverflow()); 51151fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ASSERT(current_block() != NULL); 51161fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org ASSERT(current_block()->HasPredecessor()); 5117594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kForOfStatement); 51181fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org} 51191fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 51201fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 5121a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { 5122160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 5123160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 5124160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 5125594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kTryCatchStatement); 5126a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5127a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5128a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5129a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitTryFinallyStatement( 5130a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org TryFinallyStatement* stmt) { 5131160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 5132160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 5133160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 5134594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kTryFinallyStatement); 5135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5136a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5137a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5138a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { 5139160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 5140160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 5141160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 5142594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kDebuggerStatement); 5143a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5144a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5146a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.orgvoid HOptimizedGraphBuilder::VisitCaseClause(CaseClause* clause) { 5147a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org UNREACHABLE(); 5148a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org} 5149a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org 5150a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org 5151a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { 5152160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 5153160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 5154160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 51554610c28af9f4355485f8115a725f320b80632804machenbach@chromium.org Handle<SharedFunctionInfo> shared_info = expr->shared_info(); 5156c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (shared_info.is_null()) { 515741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org shared_info = Compiler::BuildFunctionInfo(expr, current_info()->script()); 5158c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } 5159160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // We also have a stack overflow if the recursive compilation did. 5160160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (HasStackOverflow()) return; 51615f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org HFunctionLiteral* instr = 51628e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org New<HFunctionLiteral>(shared_info, expr->pretenure()); 51634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(instr, expr->id()); 5164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5165a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5166a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5167fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.orgvoid HOptimizedGraphBuilder::VisitNativeFunctionLiteral( 5168fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org NativeFunctionLiteral* expr) { 5169160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 5170160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 5171160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 5172fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org return Bailout(kNativeFunctionLiteral); 5173a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5174a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5175a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5176a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitConditional(Conditional* expr) { 5177160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 5178160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 5179160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 51808f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* cond_true = graph()->CreateBasicBlock(); 51818f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* cond_false = graph()->CreateBasicBlock(); 5182160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_BAILOUT(VisitForControl(expr->condition(), cond_true, cond_false)); 51838f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 51844d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // Visit the true and false subexpressions in the same AST context as the 51854d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // whole expression. 5186160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (cond_true->HasPredecessor()) { 5187160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org cond_true->SetJoinId(expr->ThenId()); 5188160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org set_current_block(cond_true); 5189160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_BAILOUT(Visit(expr->then_expression())); 5190160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org cond_true = current_block(); 5191160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else { 5192160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org cond_true = NULL; 5193160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 51948f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 5195160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (cond_false->HasPredecessor()) { 5196160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org cond_false->SetJoinId(expr->ElseId()); 5197160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org set_current_block(cond_false); 5198160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_BAILOUT(Visit(expr->else_expression())); 5199160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org cond_false = current_block(); 5200160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else { 5201160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org cond_false = NULL; 5202160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 52038f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 52044d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org if (!ast_context()->IsTest()) { 5205160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id()); 52064d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org set_current_block(join); 5207160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (join != NULL && !ast_context()->IsEffect()) { 52084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnValue(Pop()); 5209160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 52104d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org } 5211a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5214a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHOptimizedGraphBuilder::GlobalPropertyAccess 5215a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HOptimizedGraphBuilder::LookupGlobalProperty( 5216f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Variable* var, LookupResult* lookup, PropertyAccessType access_type) { 521741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (var->is_this() || !current_info()->has_global_object()) { 5218c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org return kUseGeneric; 5219a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 522041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<GlobalObject> global(current_info()->global_object()); 52213484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org global->Lookup(var->name(), lookup); 5222de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org if (!lookup->IsNormal() || 5223f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org (access_type == STORE && lookup->IsReadOnly()) || 5224c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org lookup->holder() != *global) { 5225c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org return kUseGeneric; 5226d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 5227c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 5228c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org return kUseCell; 5229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5232a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { 523383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ASSERT(var->IsContextSlot()); 5234d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HValue* context = environment()->context(); 52351e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org int length = scope()->ContextChainLength(var->scope()); 523683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org while (length-- > 0) { 5237f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org context = Add<HLoadNamedField>( 5238f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org context, static_cast<HValue*>(NULL), 5239f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 524083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 524183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org return context; 524283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org} 524383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 524483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 5245a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 5246e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org if (expr->is_this()) { 5247e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org current_info()->set_this_has_uses(true); 5248e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org } 5249e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 5250160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 5251160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 5252160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 5253486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Variable* variable = expr->var(); 5254486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org switch (variable->location()) { 5255486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::UNALLOCATED: { 5256355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org if (IsLexicalVariableMode(variable->mode())) { 5257355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // TODO(rossberg): should this be an ASSERT? 5258594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kReferenceToGlobalLexicalVariable); 525964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 5260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Handle known global constants like 'undefined' specially to avoid a 5261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // load from a global cell for them. 5262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Handle<Object> constant_value = 5263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com isolate()->factory()->GlobalConstantFor(variable->name()); 5264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!constant_value.is_null()) { 5265d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HConstant* instr = New<HConstant>(constant_value); 5266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return ast_context()->ReturnInstruction(instr, expr->id()); 5267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 5268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5269394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com LookupResult lookup(isolate()); 5270f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, LOAD); 5271486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 5272486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (type == kUseCell && 527341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org current_info()->global_object()->IsAccessCheckNeeded()) { 5274486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org type = kUseGeneric; 5275486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 5276badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 5277486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (type == kUseCell) { 527841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<GlobalObject> global(current_info()->global_object()); 5279b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); 5280e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org if (cell->type()->IsConstant()) { 5281e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org PropertyCell::AddDependentCompilationInfo(cell, top_info()); 52829fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<Object> constant_object = cell->type()->AsConstant()->Value(); 5283e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org if (constant_object->IsConsString()) { 5284e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org constant_object = 52859e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org String::Flatten(Handle<String>::cast(constant_object)); 5286e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } 5287d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HConstant* constant = New<HConstant>(constant_object); 5288e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org return ast_context()->ReturnInstruction(constant, expr->id()); 5289e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } else { 5290e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org HLoadGlobalCell* instr = 5291db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org New<HLoadGlobalCell>(cell, lookup.GetPropertyDetails()); 5292e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org return ast_context()->ReturnInstruction(instr, expr->id()); 5293e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } 5294486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } else { 529505150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org HValue* global_object = Add<HLoadNamedField>( 529609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org context(), static_cast<HValue*>(NULL), 529709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 5298486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org HLoadGlobalGeneric* instr = 5299db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org New<HLoadGlobalGeneric>(global_object, 5300db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org variable->name(), 5301db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org ast_context()->is_for_typeof()); 5302486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org return ast_context()->ReturnInstruction(instr, expr->id()); 5303486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 5304c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } 5305c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 5306486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::PARAMETER: 5307486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::LOCAL: { 5308d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org HValue* value = LookupAndMakeLive(variable); 530964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (value == graph()->GetConstantHole()) { 5310355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org ASSERT(IsDeclaredVariableMode(variable->mode()) && 5311355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org variable->mode() != VAR); 5312594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kReferenceToUninitializedVariable); 5313486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 5314486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org return ast_context()->ReturnValue(value); 5315486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 5316486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 5317486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::CONTEXT: { 5318486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org HValue* context = BuildContextChainWalk(variable); 53191e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HLoadContextSlot::Mode mode; 53201e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org switch (variable->mode()) { 53211e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org case LET: 53221e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org case CONST: 53231e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org mode = HLoadContextSlot::kCheckDeoptimize; 53241e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org break; 53251e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org case CONST_LEGACY: 53261e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org mode = HLoadContextSlot::kCheckReturnUndefined; 53271e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org break; 53281e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org default: 53291e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org mode = HLoadContextSlot::kNoCheck; 53301e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org break; 53311e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org } 53321e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org HLoadContextSlot* instr = 53331e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org new(zone()) HLoadContextSlot(context, variable->index(), mode); 53344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(instr, expr->id()); 53355f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 5336486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 5337486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::LOOKUP: 5338594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kReferenceToAVariableWhichRequiresDynamicLookup); 5339a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5340a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5341a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5342a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5343a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitLiteral(Literal* expr) { 5344160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 5345160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 5346160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 5347d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HConstant* instr = New<HConstant>(expr->value()); 53484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(instr, expr->id()); 5349a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5352a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 5353160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 5354160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 5355160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 53569c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 53579c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org Handle<FixedArray> literals(closure->literals()); 53588e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org HRegExpLiteral* instr = New<HRegExpLiteral>(literals, 53598e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org expr->pattern(), 53608e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org expr->flags(), 53618e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org expr->literal_index()); 53624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(instr, expr->id()); 5363a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5364a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5365a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 53660a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.orgstatic bool CanInlinePropertyAccess(Type* type) { 53670a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (type->Is(Type::NumberOrString())) return true; 536857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (!type->IsClass()) return false; 53699fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<Map> map = type->AsClass()->Map(); 537057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org return map->IsJSObjectMap() && 537157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org !map->is_dictionary_map() && 537257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org !map->has_named_interceptor(); 5373e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org} 5374e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org 5375e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org 5376f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org// Determines whether the given array or object literal boilerplate satisfies 5377f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org// all limits to be considered for fast deep-copying and computes the total 53781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org// size of all objects that are part of the graph. 5379f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgstatic bool IsFastLiteral(Handle<JSObject> boilerplate, 5380f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org int max_depth, 5381dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org int* max_properties) { 5382a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org if (boilerplate->map()->is_deprecated() && 5383a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org !JSObject::TryMigrateInstance(boilerplate)) { 5384a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org return false; 5385a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 5386a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5387f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org ASSERT(max_depth >= 0 && *max_properties >= 0); 5388f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org if (max_depth == 0) return false; 53891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 539009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Isolate* isolate = boilerplate->GetIsolate(); 539164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Handle<FixedArrayBase> elements(boilerplate->elements()); 53921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (elements->length() > 0 && 539309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org elements->map() != isolate->heap()->fixed_cow_array_map()) { 5394dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org if (boilerplate->HasFastObjectElements()) { 5395ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); 539688aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org int length = elements->length(); 539788aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org for (int i = 0; i < length; i++) { 539888aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org if ((*max_properties)-- == 0) return false; 539909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object> value(fast_elements->get(i), isolate); 540088aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org if (value->IsJSObject()) { 540188aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org Handle<JSObject> value_object = Handle<JSObject>::cast(value); 540288aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org if (!IsFastLiteral(value_object, 540388aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org max_depth - 1, 5404dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org max_properties)) { 540588aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org return false; 540688aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org } 5407f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 5408f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 5409dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org } else if (!boilerplate->HasFastDoubleElements()) { 541088aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org return false; 5411f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 54121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 54131b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 541464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Handle<FixedArray> properties(boilerplate->properties()); 54151b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (properties->length() > 0) { 54161b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return false; 54171b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } else { 541857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Handle<DescriptorArray> descriptors( 541957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org boilerplate->map()->instance_descriptors()); 542057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org int limit = boilerplate->map()->NumberOfOwnDescriptors(); 542157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org for (int i = 0; i < limit; i++) { 542257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org PropertyDetails details = descriptors->GetDetails(i); 542357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (details.type() != FIELD) continue; 542457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org int index = descriptors->GetFieldIndex(i); 5425f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org if ((*max_properties)-- == 0) return false; 542657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Handle<Object> value(boilerplate->InObjectPropertyAt(index), isolate); 54271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (value->IsJSObject()) { 54281b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Handle<JSObject> value_object = Handle<JSObject>::cast(value); 5429f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org if (!IsFastLiteral(value_object, 5430f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org max_depth - 1, 5431dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org max_properties)) { 54321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return false; 54331b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 54341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 54351b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 54361b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 54371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org return true; 54381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org} 54391b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 54401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 5441a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 5442160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 5443160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 5444160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 5445e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org expr->BuildConstantProperties(isolate()); 54461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 54471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org HInstruction* literal; 54481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 54491b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Check whether to use fast or slow deep-copying for boilerplate. 5450e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int max_properties = kMaxFastLiteralProperties; 5451dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org Handle<Object> literals_cell(closure->literals()->get(expr->literal_index()), 5452dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org isolate()); 5453dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org Handle<AllocationSite> site; 5454dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org Handle<JSObject> boilerplate; 5455dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org if (!literals_cell->IsUndefined()) { 5456dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org // Retrieve the boilerplate 5457dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org site = Handle<AllocationSite>::cast(literals_cell); 5458dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()), 5459dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org isolate()); 5460dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org } 5461e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5462dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org if (!boilerplate.is_null() && 5463dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) { 5464b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AllocationSiteUsageContext usage_context(isolate(), site, false); 5465b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org usage_context.EnterNewScope(); 5466b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org literal = BuildFastLiteral(boilerplate, &usage_context); 5467b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org usage_context.ExitScope(site, boilerplate); 54681b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } else { 5469906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org NoObservableSideEffectsScope no_effects(this); 547032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Handle<FixedArray> closure_literals(closure->literals(), isolate()); 5471906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org Handle<FixedArray> constant_properties = expr->constant_properties(); 5472906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org int literal_index = expr->literal_index(); 5473906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org int flags = expr->fast_elements() 5474906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; 5475906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org flags |= expr->has_function() 5476906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; 5477906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org 54788d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Add<HPushArguments>(Add<HConstant>(closure_literals), 5479011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org Add<HConstant>(literal_index), 5480011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org Add<HConstant>(constant_properties), 5481011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org Add<HConstant>(flags)); 5482906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org 5483b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org // TODO(mvstanton): Add a flag to turn off creation of any 5484b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org // AllocationMementos for this call: we are in crankshaft and should have 5485b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org // learned enough about transition behavior to stop emitting mementos. 5486895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Runtime::FunctionId function_id = Runtime::kHiddenCreateObjectLiteral; 5487d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), 54881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Runtime::FunctionForId(function_id), 54891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 4); 54901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 54911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 54925f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // The object is expected in the bailout environment during computation 54935f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // of the property values and is the value of the entire expression. 5494e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Push(literal); 5495a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 54967028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org expr->CalculateEmitStore(zone()); 5497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < expr->properties()->length(); i++) { 5499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ObjectLiteral::Property* property = expr->properties()->at(i); 5500a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (property->IsCompileTimeValue()) continue; 5501a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Literal* key = property->key(); 5503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Expression* value = property->value(); 5504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org switch (property->kind()) { 5506a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case ObjectLiteral::Property::MATERIALIZED_LITERAL: 5507a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 5508a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Fall through. 5509a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case ObjectLiteral::Property::COMPUTED: 55101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (key->value()->IsInternalizedString()) { 5511a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (property->emit_store()) { 5512160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(value)); 5513a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* value = Pop(); 5514b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org Handle<Map> map = property->GetReceiverType(); 5515b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org Handle<String> name = property->key()->AsPropertyName(); 55167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org HInstruction* store; 5517b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org if (map.is_null()) { 5518b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org // If we don't know the monomorphic type, do a generic store. 5519f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CHECK_ALIVE(store = BuildNamedGeneric( 5520f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org STORE, literal, name, value)); 5521b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org } else { 55220a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org PropertyAccessInfo info(this, STORE, ToType(map), name); 55230a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (info.CanAccessMonomorphic()) { 5524af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org HValue* checked_literal = Add<HCheckMaps>(literal, map); 55250a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org ASSERT(!info.lookup()->IsPropertyCallbacks()); 55268297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org store = BuildMonomorphicAccess( 55278297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org &info, literal, checked_literal, value, 55280a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org BailoutId::None(), BailoutId::None()); 55290a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org } else { 5530f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CHECK_ALIVE(store = BuildNamedGeneric( 5531f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org STORE, literal, name, value)); 55320a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org } 5533b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org } 5534496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org AddInstruction(store); 5535fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (store->HasObservableSideEffects()) { 5536c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HSimulate>(key->id(), REMOVABLE_SIMULATE); 5537fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 5538a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 5539160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForEffect(value)); 5540a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5541a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 5542a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5543a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Fall through. 5544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case ObjectLiteral::Property::PROTOTYPE: 5545a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case ObjectLiteral::Property::SETTER: 5546a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case ObjectLiteral::Property::GETTER: 5547594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kObjectLiteralWithComplexProperty); 5548a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org default: UNREACHABLE(); 5549a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5550a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5551ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 5552ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (expr->has_function()) { 5553ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Return the result of the transformation to fast properties 5554ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // instead of the original since this operation changes the map 5555ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // of the object. This makes sure that the original object won't 5556ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // be used by other optimized code before it is transformed 5557ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // (e.g. because of code motion). 55581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HToFastProperties* result = Add<HToFastProperties>(Pop()); 55594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnValue(result); 5560ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } else { 55614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnValue(Pop()); 5562ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 5563a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5564a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5565a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5566a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 5567160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 5568160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 5569160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 5570e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org expr->BuildConstantElements(isolate()); 5571a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ZoneList<Expression*>* subexprs = expr->values(); 5572a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int length = subexprs->length(); 5573f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org HInstruction* literal; 5574a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5575bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Handle<AllocationSite> site; 557632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Handle<FixedArray> literals(environment()->closure()->literals(), isolate()); 5577c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org bool uninitialized = false; 5578bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Handle<Object> literals_cell(literals->get(expr->literal_index()), 5579bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org isolate()); 5580b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Handle<JSObject> boilerplate_object; 5581bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (literals_cell->IsUndefined()) { 5582c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org uninitialized = true; 55838f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org Handle<Object> raw_boilerplate; 55848f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org ASSIGN_RETURN_ON_EXCEPTION_VALUE( 55858f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org isolate(), raw_boilerplate, 55868f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org Runtime::CreateArrayLiteralBoilerplate( 55878f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org isolate(), literals, expr->constant_elements()), 55888f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org Bailout(kArrayBoilerplateCreationFailed)); 5589bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 5590b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org boilerplate_object = Handle<JSObject>::cast(raw_boilerplate); 5591b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AllocationSiteCreationContext creation_context(isolate()); 5592b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org site = creation_context.EnterNewScope(); 5593b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org if (JSObject::DeepWalk(boilerplate_object, &creation_context).is_null()) { 5594b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org return Bailout(kArrayBoilerplateCreationFailed); 5595b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org } 5596b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org creation_context.ExitScope(site, boilerplate_object); 5597bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org literals->set(expr->literal_index(), *site); 5598bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 5599b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org if (boilerplate_object->elements()->map() == 56007ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org isolate()->heap()->fixed_cow_array_map()) { 56017ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org isolate()->counters()->cow_arrays_created_runtime()->Increment(); 56027ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } 5603bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } else { 5604bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org ASSERT(literals_cell->IsAllocationSite()); 5605bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org site = Handle<AllocationSite>::cast(literals_cell); 5606b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org boilerplate_object = Handle<JSObject>( 5607b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org JSObject::cast(site->transition_info()), isolate()); 560864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 560964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 5610b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org ASSERT(!boilerplate_object.is_null()); 5611b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org ASSERT(site->SitePointsToLiteral()); 5612bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 56137ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org ElementsKind boilerplate_elements_kind = 5614b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org boilerplate_object->GetElementsKind(); 561564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 5616f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Check whether to use fast or slow deep-copying for boilerplate. 5617e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int max_properties = kMaxFastLiteralProperties; 5618dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org if (IsFastLiteral(boilerplate_object, 5619e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org kMaxFastLiteralDepth, 5620dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org &max_properties)) { 5621b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AllocationSiteUsageContext usage_context(isolate(), site, false); 5622b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org usage_context.EnterNewScope(); 5623b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org literal = BuildFastLiteral(boilerplate_object, &usage_context); 5624b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org usage_context.ExitScope(site, boilerplate_object); 5625f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } else { 5626906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org NoObservableSideEffectsScope no_effects(this); 5627906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org // Boilerplate already exists and constant elements are never accessed, 5628906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org // pass an empty fixed array to the runtime function instead. 5629906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); 5630906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org int literal_index = expr->literal_index(); 563137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org int flags = expr->depth() == 1 563237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org ? ArrayLiteral::kShallowElements 563337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org : ArrayLiteral::kNoFlags; 563437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org flags |= ArrayLiteral::kDisableMementos; 5635906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org 56368d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Add<HPushArguments>(Add<HConstant>(literals), 5637011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org Add<HConstant>(literal_index), 5638011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org Add<HConstant>(constants), 5639011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org Add<HConstant>(flags)); 5640906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org 5641b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org // TODO(mvstanton): Consider a flag to turn off creation of any 5642b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org // AllocationMementos for this call: we are in crankshaft and should have 5643b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org // learned enough about transition behavior to stop emitting mementos. 5644895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Runtime::FunctionId function_id = Runtime::kHiddenCreateArrayLiteral; 5645d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), 56461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Runtime::FunctionForId(function_id), 564737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 4); 5648fee992bb82f8bc64bb35d7133567a2f6d2671b64jkummerow@chromium.org 5649fee992bb82f8bc64bb35d7133567a2f6d2671b64jkummerow@chromium.org // De-opt if elements kind changed from boilerplate_elements_kind. 5650dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate()); 5651af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org literal = Add<HCheckMaps>(literal, map); 5652f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 565364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 56545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // The array is expected in the bailout environment during computation 56555f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // of the property values and is the value of the entire expression. 5656e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Push(literal); 5657b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // The literal index is on the stack, too. 56581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Push(Add<HConstant>(expr->literal_index())); 56595f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 566057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org HInstruction* elements = NULL; 5661a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5662a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < length; i++) { 5663a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Expression* subexpr = subexprs->at(i); 5664a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // If the subexpression is a literal or a simple materialized literal it 5665a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // is already set in the cloned array. 5666a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 5667a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5668160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(subexpr)); 5669a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* value = Pop(); 5670594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (!Smi::IsValid(i)) return Bailout(kNonSmiKeyInArrayLiteral); 56715f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 5672ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org elements = AddLoadElements(literal); 56735f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 56741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HValue* key = Add<HConstant>(i); 5675a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org 567664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org switch (boilerplate_elements_kind) { 5677830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org case FAST_SMI_ELEMENTS: 5678830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org case FAST_HOLEY_SMI_ELEMENTS: 567964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org case FAST_ELEMENTS: 5680830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org case FAST_HOLEY_ELEMENTS: 5681e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org case FAST_DOUBLE_ELEMENTS: 5682c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org case FAST_HOLEY_DOUBLE_ELEMENTS: { 5683c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org HStoreKeyed* instr = Add<HStoreKeyed>(elements, key, value, 56840a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org boilerplate_elements_kind); 5685c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org instr->SetUninitialized(uninitialized); 568664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org break; 5687c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 568864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org default: 568964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org UNREACHABLE(); 569064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org break; 569164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 5692c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5693c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HSimulate>(expr->GetIdForElement(i)); 5694a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5695b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 5696b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Drop(1); // array literal index 56974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnValue(Pop()); 5698a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5699a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5700a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5701003a9255d4e3b18b610295c0de79b1dbedc021c7verwaest@chromium.orgHCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object, 5702003a9255d4e3b18b610295c0de79b1dbedc021c7verwaest@chromium.org Handle<Map> map) { 57031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org BuildCheckHeapObject(object); 5704af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org return Add<HCheckMaps>(object, map); 5705e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 5706e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 5707e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 5708f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildLoadNamedField( 5709f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PropertyAccessInfo* info, 5710f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HValue* checked_object) { 57112ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org // See if this is a load for an immutable property 57122ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (checked_object->ActualValue()->IsConstant() && 57132ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org info->lookup()->IsCacheable() && 57142ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org info->lookup()->IsReadOnly() && info->lookup()->IsDontDelete()) { 57152ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Handle<Object> object( 57162ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org HConstant::cast(checked_object->ActualValue())->handle(isolate())); 57172ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org 57182ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (object->IsJSObject()) { 57192ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org LookupResult lookup(isolate()); 57203484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org Handle<JSObject>::cast(object)->Lookup(info->name(), &lookup); 57212ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Handle<Object> value(lookup.GetLazyValue(), isolate()); 57222ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org 57232ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (!value->IsTheHole()) { 57242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org return New<HConstant>(value); 57252ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 57262ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 57272ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 57282ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org 5729f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HObjectAccess access = info->access(); 5730f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (access.representation().IsDouble()) { 5731f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Load the heap number. 5732f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org checked_object = Add<HLoadNamedField>( 5733f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org checked_object, static_cast<HValue*>(NULL), 5734f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org access.WithRepresentation(Representation::Tagged())); 5735f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Load the double value from it. 5736f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org access = HObjectAccess::ForHeapNumberValue(); 5737f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 57385924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org 57395924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org SmallMapList* map_list = info->field_maps(); 57405924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org if (map_list->length() == 0) { 57415924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org return New<HLoadNamedField>(checked_object, checked_object, access); 57425924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org } 57435924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org 57445924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org UniqueSet<Map>* maps = new(zone()) UniqueSet<Map>(map_list->length(), zone()); 57455924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org for (int i = 0; i < map_list->length(); ++i) { 5746a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org maps->Add(Unique<Map>::CreateImmovable(map_list->at(i)), zone()); 57475924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org } 5748f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return New<HLoadNamedField>( 57495924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org checked_object, checked_object, access, maps, info->field_type()); 5750f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 5751f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 5752f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 5753a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( 57540a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org PropertyAccessInfo* info, 57551e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org HValue* checked_object, 57560a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HValue* value) { 57570a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org bool transition_to_field = info->lookup()->IsTransition(); 57580a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org // TODO(verwaest): Move this logic into PropertyAccessInfo. 5759e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org HObjectAccess field_access = info->access(); 5760a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 5761a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org HStoreNamedField *instr; 5762f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (field_access.representation().IsDouble()) { 5763fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org HObjectAccess heap_number_access = 5764fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org field_access.WithRepresentation(Representation::Tagged()); 576557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (transition_to_field) { 5766a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org // The store requires a mutable HeapNumber to be allocated. 576757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org NoObservableSideEffectsScope no_side_effects(this); 57681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); 576905150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org 5770d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org // TODO(hpayer): Allocation site pretenuring support. 5771d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HInstruction* heap_number = Add<HAllocate>(heap_number_size, 5772eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org HType::HeapObject(), 5773d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org NOT_TENURED, 5774d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HEAP_NUMBER_TYPE); 5775fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map()); 5776d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), 57770a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org value); 57781e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org instr = New<HStoreNamedField>(checked_object->ActualValue(), 57791e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org heap_number_access, 57800a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org heap_number); 578157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 5782a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org // Already holds a HeapNumber; load the box and write its value field. 578309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HInstruction* heap_number = Add<HLoadNamedField>( 578409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org checked_object, static_cast<HValue*>(NULL), heap_number_access); 5785d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org instr = New<HStoreNamedField>(heap_number, 5786d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HObjectAccess::ForHeapNumberValue(), 578705150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org value, STORE_TO_INITIALIZED_ENTRY); 578857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 5789a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } else { 5790d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org if (field_access.representation().IsHeapObject()) { 5791d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org BuildCheckHeapObject(value); 5792d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org } 5793d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org 57949fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org if (!info->field_maps()->is_empty()) { 5795e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org ASSERT(field_access.representation().IsHeapObject()); 5796af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org value = Add<HCheckMaps>(value, info->field_maps()); 5797e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org } 5798e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org 5799fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org // This is a normal store. 580071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org instr = New<HStoreNamedField>( 580171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org checked_object->ActualValue(), field_access, value, 580271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org transition_to_field ? INITIALIZING_STORE : STORE_TO_INITIALIZED_ENTRY); 580357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 5804a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 580557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (transition_to_field) { 5806c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org Handle<Map> transition(info->transition()); 5807c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org ASSERT(!transition->is_deprecated()); 5808c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org instr->SetTransition(Add<HConstant>(transition)); 5809a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 5810a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return instr; 5811a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 5812a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 5813a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 58140a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.orgbool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible( 5815528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org PropertyAccessInfo* info) { 581657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (!CanInlinePropertyAccess(type_)) return false; 581757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 58180a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org // Currently only handle Type::Number as a polymorphic case. 581957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber 582057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // instruction. 58210a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (type_->Is(Type::Number())) return false; 582257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 582357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // Values are only compatible for monomorphic load if they all behave the same 582457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // regarding value wrappers. 58250a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (type_->Is(Type::NumberOrString())) { 58260a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (!info->type_->Is(Type::NumberOrString())) return false; 582757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } else { 58280a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (info->type_->Is(Type::NumberOrString())) return false; 582957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } 5830528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 5831528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (!LookupDescriptor()) return false; 5832528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 5833528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (!lookup_.IsFound()) { 5834d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return (!info->lookup_.IsFound() || info->has_holder()) && 583557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org map()->prototype() == info->map()->prototype(); 5836528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 5837528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 5838d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // Mismatch if the other access info found the property in the prototype 5839d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // chain. 5840d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (info->has_holder()) return false; 5841d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 5842528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (lookup_.IsPropertyCallbacks()) { 58438297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org return accessor_.is_identical_to(info->accessor_) && 58448297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org api_holder_.is_identical_to(info->api_holder_); 5845528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 5846528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 5847528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (lookup_.IsConstant()) { 5848528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return constant_.is_identical_to(info->constant_); 5849528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 5850528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 5851528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org ASSERT(lookup_.IsField()); 5852528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (!info->lookup_.IsField()) return false; 5853528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 5854528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Representation r = access_.representation(); 58550a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (IsLoad()) { 58560a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (!info->access_.representation().IsCompatibleForLoad(r)) return false; 58570a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org } else { 58580a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (!info->access_.representation().IsCompatibleForStore(r)) return false; 58590a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org } 5860528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (info->access_.offset() != access_.offset()) return false; 5861528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (info->access_.IsInobject() != access_.IsInobject()) return false; 58629fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org if (IsLoad()) { 58639fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org if (field_maps_.is_empty()) { 58649fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org info->field_maps_.Clear(); 58659fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org } else if (!info->field_maps_.is_empty()) { 58669fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org for (int i = 0; i < field_maps_.length(); ++i) { 58679fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org info->field_maps_.AddMapIfMissing(field_maps_.at(i), info->zone()); 58689fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org } 58699fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org info->field_maps_.Sort(); 58709fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org } 58719fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org } else { 58729fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org // We can only merge stores that agree on their field maps. The comparison 58739fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org // below is safe, since we keep the field maps sorted. 58749fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org if (field_maps_.length() != info->field_maps_.length()) return false; 58759fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org for (int i = 0; i < field_maps_.length(); ++i) { 58769fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org if (!field_maps_.at(i).is_identical_to(info->field_maps_.at(i))) { 58779fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org return false; 58789fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org } 58799fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org } 5880e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org } 5881528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org info->GeneralizeRepresentation(r); 58825924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org info->field_type_ = info->field_type_.Combine(field_type_); 5883bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org return true; 5884bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 5885bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 5886bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 5887528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgbool HOptimizedGraphBuilder::PropertyAccessInfo::LookupDescriptor() { 588857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (!type_->IsClass()) return true; 588957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org map()->LookupDescriptor(NULL, *name_, &lookup_); 589057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org return LoadResult(map()); 5891528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 5892fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org 5893fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org 5894528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgbool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) { 58950a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (!IsLoad() && lookup_.IsProperty() && 58960a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org (lookup_.IsReadOnly() || !lookup_.IsCacheable())) { 58970a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org return false; 58980a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org } 58990a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 5900528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (lookup_.IsField()) { 5901e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org // Construct the object field access. 5902528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org access_ = HObjectAccess::ForField(map, &lookup_, name_); 5903e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org 5904e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org // Load field map for heap objects. 59059fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org LoadFieldMaps(map); 5906528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } else if (lookup_.IsPropertyCallbacks()) { 5907528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Handle<Object> callback(lookup_.GetValueFromMap(*map), isolate()); 5908528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (!callback->IsAccessorPair()) return false; 59090a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Object* raw_accessor = IsLoad() 59100a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org ? Handle<AccessorPair>::cast(callback)->getter() 59110a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org : Handle<AccessorPair>::cast(callback)->setter(); 59120a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (!raw_accessor->IsJSFunction()) return false; 59130a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor)); 59148297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (accessor->shared()->IsApiFunction()) { 59158297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org CallOptimization call_optimization(accessor); 5916ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org if (call_optimization.is_simple_api_call()) { 5917ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org CallOptimization::HolderLookup holder_lookup; 5918ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Handle<Map> receiver_map = this->map(); 5919ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org api_holder_ = call_optimization.LookupHolderOfExpectedType( 5920ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org receiver_map, &holder_lookup); 59218297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org } 59228297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org } 5923c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org accessor_ = accessor; 5924528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } else if (lookup_.IsConstant()) { 5925528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org constant_ = handle(lookup_.GetConstantFromMap(*map), isolate()); 5926528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 5927fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org 5928528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return true; 5929528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 5930528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 5931528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 59329fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgvoid HOptimizedGraphBuilder::PropertyAccessInfo::LoadFieldMaps( 59339fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<Map> map) { 59345924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org // Clear any previously collected field maps/type. 5935a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org field_maps_.Clear(); 59365924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org field_type_ = HType::Tagged(); 5937a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org 5938e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org // Figure out the field type from the accessor map. 59399fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<HeapType> field_type(lookup_.GetFieldTypeFromMap(*map), isolate()); 5940e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org 59419fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org // Collect the (stable) maps from the field type. 59429fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org int num_field_maps = field_type->NumClasses(); 5943a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org if (num_field_maps == 0) return; 59449fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org ASSERT(access_.representation().IsHeapObject()); 59459fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org field_maps_.Reserve(num_field_maps, zone()); 59469fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org HeapType::Iterator<Map> it = field_type->Classes(); 59479fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org while (!it.Done()) { 59489fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<Map> field_map = it.Current(); 59499fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org if (!field_map->is_stable()) { 59509fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org field_maps_.Clear(); 59519fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org return; 5952e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org } 59539fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org field_maps_.Add(field_map, zone()); 59549fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org it.Advance(); 5955e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org } 59569fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org field_maps_.Sort(); 59579fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org ASSERT_EQ(num_field_maps, field_maps_.length()); 59589fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org 59595924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org // Determine field HType from field HeapType. 5960eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org field_type_ = HType::FromType<HeapType>(field_type); 5961eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org ASSERT(field_type_.IsHeapObject()); 59625924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org 59639fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org // Add dependency on the map that introduced the field. 59649fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Map::AddDependentCompilationInfo( 59659fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org handle(lookup_.GetFieldOwnerFromMap(*map), isolate()), 59669fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org DependentCode::kFieldTypeGroup, top_info()); 5967e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org} 5968e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org 5969e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org 5970528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgbool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { 597157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Handle<Map> map = this->map(); 597257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 5973528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org while (map->prototype()->IsJSObject()) { 5974528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org holder_ = handle(JSObject::cast(map->prototype())); 5975c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (holder_->map()->is_deprecated()) { 5976c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org JSObject::TryMigrateInstance(holder_); 5977c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } 5978528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org map = Handle<Map>(holder_->map()); 59790a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (!CanInlinePropertyAccess(ToType(map))) { 5980528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org lookup_.NotFound(); 5981528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return false; 5982b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 5983528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org map->LookupDescriptor(*holder_, *name_, &lookup_); 5984528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (lookup_.IsFound()) return LoadResult(map); 5985b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 5986528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org lookup_.NotFound(); 5987528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return true; 5988528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 5989fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org 5990bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 59910a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.orgbool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() { 599257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (!CanInlinePropertyAccess(type_)) return false; 59930a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (IsJSObjectFieldAccessor()) return IsLoad(); 5994528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (!LookupDescriptor()) return false; 59950a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (lookup_.IsFound()) { 59960a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (IsLoad()) return true; 59970a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org return !lookup_.IsReadOnly() && lookup_.IsCacheable(); 59980a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org } 59990a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (!LookupInPrototypes()) return false; 60000a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (IsLoad()) return true; 60010a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 60020a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (lookup_.IsPropertyCallbacks()) return true; 60030a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Handle<Map> map = this->map(); 60040a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org map->LookupTransition(NULL, *name_, &lookup_); 6005bfd1d202fb7cd6d54d956414bad9f75a995d0f65machenbach@chromium.org if (lookup_.IsTransitionToField() && map->unused_property_fields() > 0) { 6006e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org // Construct the object field access. 6007e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org access_ = HObjectAccess::ForField(map, &lookup_, name_); 6008e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org 6009e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org // Load field map for heap objects. 60109fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org LoadFieldMaps(transition()); 60110a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org return true; 60120a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org } 60130a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org return false; 6014528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 6015528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 6016bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 60170a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.orgbool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic( 6018528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org SmallMapList* types) { 60190a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org ASSERT(type_->Is(ToType(types->first()))); 60200a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (!CanAccessMonomorphic()) return false; 60210a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism); 6022528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (types->length() > kMaxLoadPolymorphism) return false; 6023bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 602457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HObjectAccess access = HObjectAccess::ForMap(); // bogus default 602557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (GetJSObjectFieldAccess(&access)) { 6026528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org for (int i = 1; i < types->length(); ++i) { 602757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org PropertyAccessInfo test_info( 60280a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org builder_, access_type_, ToType(types->at(i)), name_); 602957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HObjectAccess test_access = HObjectAccess::ForMap(); // bogus default 603057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (!test_info.GetJSObjectFieldAccess(&test_access)) return false; 603157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (!access.Equals(test_access)) return false; 6032528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 6033528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return true; 6034528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 6035fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 60360a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org // Currently only handle Type::Number as a polymorphic case. 603757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber 603857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // instruction. 60390a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (type_->Is(Type::Number())) return false; 60400a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 60410a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org // Multiple maps cannot transition to the same target map. 60420a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org ASSERT(!IsLoad() || !lookup_.IsTransition()); 60430a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (lookup_.IsTransition() && types->length() > 1) return false; 604457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 6045528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org for (int i = 1; i < types->length(); ++i) { 60460a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org PropertyAccessInfo test_info( 60470a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org builder_, access_type_, ToType(types->at(i)), name_); 60480a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (!test_info.IsCompatible(this)) return false; 6049528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 6050528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 6051528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return true; 6052fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org} 6053fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org 6054fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org 60550a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.orgstatic bool NeedsWrappingFor(Type* type, Handle<JSFunction> target) { 60560a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org return type->Is(Type::NumberOrString()) && 6057486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org target->shared()->strict_mode() == SLOPPY && 605857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org !target->shared()->native(); 605957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org} 606057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 606157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 60628297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess( 6063528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org PropertyAccessInfo* info, 6064528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org HValue* object, 606557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HValue* checked_object, 60668297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org HValue* value, 6067528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org BailoutId ast_id, 6068528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org BailoutId return_id, 6069528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bool can_inline_accessor) { 6070594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 60718e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org HObjectAccess access = HObjectAccess::ForMap(); // bogus default 60728e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org if (info->GetJSObjectFieldAccess(&access)) { 60738297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ASSERT(info->IsLoad()); 60748297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org return New<HLoadNamedField>(object, checked_object, access); 6075528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 6076528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 6077528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org HValue* checked_holder = checked_object; 6078528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (info->has_holder()) { 6079528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Handle<JSObject> prototype(JSObject::cast(info->map()->prototype())); 6080528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org checked_holder = BuildCheckPrototypeMaps(prototype, info->holder()); 6081528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 6082528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 60838297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (!info->lookup()->IsFound()) { 60848297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ASSERT(info->IsLoad()); 60858297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org return graph()->GetConstantUndefined(); 6086528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 6087528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 60888297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (info->lookup()->IsField()) { 60898297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (info->IsLoad()) { 6090f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return BuildLoadNamedField(info, checked_holder); 609157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } else { 60928297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org return BuildStoreNamedField(info, checked_object, value); 6093528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 6094528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 6095528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 60968297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (info->lookup()->IsTransition()) { 60978297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ASSERT(!info->IsLoad()); 60988297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org return BuildStoreNamedField(info, checked_object, value); 60990a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org } 61000a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 61010a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (info->lookup()->IsPropertyCallbacks()) { 61028297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org Push(checked_object); 61038297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org int argument_count = 1; 61048297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (!info->IsLoad()) { 61058297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org argument_count = 2; 61068297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org Push(value); 61078297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org } 61088297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org 61090a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (NeedsWrappingFor(info->type(), info->accessor())) { 61100a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HValue* function = Add<HConstant>(info->accessor()); 61118297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org PushArgumentsFromEnvironment(argument_count); 61128297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org return New<HCallFunction>(function, argument_count, WRAP_AND_CALL); 61138297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org } else if (FLAG_inline_accessors && can_inline_accessor) { 61148297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org bool success = info->IsLoad() 61158297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) 611625530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org : TryInlineSetter( 611725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org info->accessor(), info->map(), ast_id, return_id, value); 61185b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org if (success || HasStackOverflow()) return NULL; 61190a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org } 61208297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org 61218297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org PushArgumentsFromEnvironment(argument_count); 61228297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org return BuildCallConstantFunction(info->accessor(), argument_count); 61230a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org } 61240a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 61258297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ASSERT(info->lookup()->IsConstant()); 61268297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (info->IsLoad()) { 61278297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org return New<HConstant>(info->constant()); 61288297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org } else { 61290a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant())); 61300a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org } 61310a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org} 61320a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 61330a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 61348297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.orgvoid HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( 61358297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org PropertyAccessType access_type, 61363d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org BailoutId ast_id, 6137528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org BailoutId return_id, 6138fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org HValue* object, 61398297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org HValue* value, 6140fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org SmallMapList* types, 6141fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org Handle<String> name) { 6142594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // Something did not match; must use a polymorphic load. 6143594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org int count = 0; 6144594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org HBasicBlock* join = NULL; 614557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HBasicBlock* number_block = NULL; 614657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org bool handled_string = false; 614757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 614857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org bool handle_smi = false; 61498297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism); 6150594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { 61518297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org PropertyAccessInfo info(this, access_type, ToType(types->at(i)), name); 61520a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (info.type()->Is(Type::String())) { 615357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (handled_string) continue; 615457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org handled_string = true; 615557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } 61560a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (info.CanAccessMonomorphic()) { 615757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org count++; 61580a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (info.type()->Is(Type::Number())) { 615957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org handle_smi = true; 616057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org break; 6161594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 616257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } 616357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } 6164594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 616557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org count = 0; 616657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HControlInstruction* smi_check = NULL; 616757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org handled_string = false; 6168594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 616957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { 61708297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org PropertyAccessInfo info(this, access_type, ToType(types->at(i)), name); 61710a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (info.type()->Is(Type::String())) { 617257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (handled_string) continue; 617357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org handled_string = true; 617457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } 61750a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (!info.CanAccessMonomorphic()) continue; 617657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 617757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (count == 0) { 617857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org join = graph()->CreateBasicBlock(); 617957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (handle_smi) { 618057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); 618157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); 618257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org number_block = graph()->CreateBasicBlock(); 618357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org smi_check = New<HIsSmiAndBranch>( 618457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org object, empty_smi_block, not_smi_block); 618557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org FinishCurrentBlock(smi_check); 6186f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org GotoNoSimulate(empty_smi_block, number_block); 618757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org set_current_block(not_smi_block); 6188594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else { 618957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org BuildCheckHeapObject(object); 6190594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 619157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } 619257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org ++count; 619357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HBasicBlock* if_true = graph()->CreateBasicBlock(); 619457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HBasicBlock* if_false = graph()->CreateBasicBlock(); 619557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HUnaryControlInstruction* compare; 6196594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 619757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HValue* dependency; 61980a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (info.type()->Is(Type::Number())) { 619957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); 6200052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org compare = New<HCompareMap>(object, heap_number_map, if_true, if_false); 620157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org dependency = smi_check; 62020a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org } else if (info.type()->Is(Type::String())) { 620357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org compare = New<HIsStringAndBranch>(object, if_true, if_false); 620457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org dependency = compare; 620557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } else { 6206052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org compare = New<HCompareMap>(object, info.map(), if_true, if_false); 620757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org dependency = compare; 6208594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 620957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org FinishCurrentBlock(compare); 621057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 62110a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (info.type()->Is(Type::Number())) { 6212f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org GotoNoSimulate(if_true, number_block); 621357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if_true = number_block; 621457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } 621557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 621657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org set_current_block(if_true); 621757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 62188297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org HInstruction* access = BuildMonomorphicAccess( 62198297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org &info, object, dependency, value, ast_id, 622057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org return_id, FLAG_polymorphic_inlining); 62218297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org 62228297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org HValue* result = NULL; 62238297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org switch (access_type) { 62248297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org case LOAD: 62258297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org result = access; 62268297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org break; 62278297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org case STORE: 62288297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org result = value; 62298297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org break; 62308297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org } 62318297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org 62328297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (access == NULL) { 623357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (HasStackOverflow()) return; 623457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } else { 62358297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (!access->IsLinked()) AddInstruction(access); 62368297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (!ast_context()->IsEffect()) Push(result); 623757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } 623857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 623957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (current_block() != NULL) Goto(join); 624057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org set_current_block(if_false); 6241594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 6242594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 6243594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // Finish up. Unconditionally deoptimize if we've handled all the maps we 6244594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // know about and do not want to handle ones we've never seen. Otherwise 6245594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // use a generic IC. 6246594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 6247f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org FinishExitWithHardDeoptimization("Uknown map in polymorphic access"); 6248594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else { 6249f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HInstruction* instr = BuildNamedGeneric(access_type, object, name, value); 6250f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org AddInstruction(instr); 6251f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value); 6252594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 6253594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (join != NULL) { 625471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(join); 6255594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } else { 62563d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6257594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6258594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return; 6259594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 6260594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 6261594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 6262594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ASSERT(join != NULL); 6263f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (join->HasPredecessor()) { 6264f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org join->SetJoinId(ast_id); 6265f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org set_current_block(join); 6266f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6267f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 6268f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org set_current_block(NULL); 6269f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 6270b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org} 6271fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org 6272fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org 6273639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.orgstatic bool ComputeReceiverTypes(Expression* expr, 6274639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org HValue* receiver, 62750a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org SmallMapList** t, 62760a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Zone* zone) { 6277639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org SmallMapList* types = expr->GetReceiverTypes(); 6278639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org *t = types; 6279639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org bool monomorphic = expr->IsMonomorphic(); 6280639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (types != NULL && receiver->HasMonomorphicJSObjectType()) { 6281639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap(); 6282639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org types->FilterForPossibleTransitions(root_map); 6283639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org monomorphic = types->length() == 1; 6284639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org } 62850a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org return monomorphic && CanInlinePropertyAccess( 62860a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org IC::MapToType<Type>(types->first(), zone)); 62870a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org} 62880a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 62890a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 62900a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.orgstatic bool AreStringTypes(SmallMapList* types) { 62910a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org for (int i = 0; i < types->length(); i++) { 62920a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (types->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false; 62930a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org } 62940a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org return true; 6295639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org} 6296a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6297a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6298639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.orgvoid HOptimizedGraphBuilder::BuildStore(Expression* expr, 6299639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Property* prop, 6300639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org BailoutId ast_id, 6301639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org BailoutId return_id, 6302639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org bool is_uninitialized) { 6303639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (!prop->key()->IsPropertyName()) { 6304a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Keyed store. 63050a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HValue* value = environment()->ExpressionStackAt(0); 630657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org HValue* key = environment()->ExpressionStackAt(1); 630757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org HValue* object = environment()->ExpressionStackAt(2); 63087b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org bool has_side_effects = false; 630971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org HandleKeyedElementAccess(object, key, value, expr, 6310f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org STORE, &has_side_effects); 631157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Drop(3); 63127b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org Push(value); 6313639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Add<HSimulate>(return_id, REMOVABLE_SIMULATE); 63144f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnValue(Pop()); 6315a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 6316639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 6317639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org // Named store. 63180a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HValue* value = Pop(); 63190a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HValue* object = Pop(); 6320639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 6321639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Literal* key = prop->key()->AsLiteral(); 6322639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Handle<String> name = Handle<String>::cast(key->value()); 6323639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org ASSERT(!name.is_null()); 6324639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 63258297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org HInstruction* instr = BuildNamedAccess(STORE, ast_id, return_id, expr, 63268297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org object, name, value, is_uninitialized); 63278297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (instr == NULL) return; 6328639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 6329639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (!ast_context()->IsEffect()) Push(value); 6330639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org AddInstruction(instr); 6331639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (instr->HasObservableSideEffects()) { 6332639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6333639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org } 6334639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (!ast_context()->IsEffect()) Drop(1); 6335639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org return ast_context()->ReturnValue(value); 6336639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org} 6337639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 6338639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 6339639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.orgvoid HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 6340639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Property* prop = expr->target()->AsProperty(); 6341639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org ASSERT(prop != NULL); 6342639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org CHECK_ALIVE(VisitForValue(prop->obj())); 6343639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (!prop->key()->IsPropertyName()) { 6344639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org CHECK_ALIVE(VisitForValue(prop->key())); 6345639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org } 6346639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org CHECK_ALIVE(VisitForValue(expr->value())); 6347639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org BuildStore(expr, prop, expr->id(), 6348639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org expr->AssignmentId(), expr->IsUninitialized()); 6349a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 63525f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// Because not every expression has a position and there is not common 63535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// superclass of Assignment and CountOperation, we cannot just pass the 63545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// owning expression instead of position and ast_id separately. 6355a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::HandleGlobalVariableAssignment( 6356a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Variable* var, 6357a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* value, 6358a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org BailoutId ast_id) { 6359394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com LookupResult lookup(isolate()); 6360f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, STORE); 6361c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (type == kUseCell) { 636241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<GlobalObject> global(current_info()->global_object()); 6363b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); 6364e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org if (cell->type()->IsConstant()) { 63659fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<Object> constant = cell->type()->AsConstant()->Value(); 6366f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (value->IsConstant()) { 6367f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HConstant* c_value = HConstant::cast(value); 6368f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!constant.is_identical_to(c_value->handle(isolate()))) { 6369f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Add<HDeoptimize>("Constant global variable assignment", 6370f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Deoptimizer::EAGER); 6371f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 6372e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } else { 6373f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HValue* c_constant = Add<HConstant>(constant); 6374f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org IfBuilder builder(this); 6375f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (constant->IsNumber()) { 6376f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ); 6377f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 6378f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org builder.If<HCompareObjectEqAndBranch>(value, c_constant); 6379f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 6380f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org builder.Then(); 6381f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org builder.Else(); 6382f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Add<HDeoptimize>("Constant global variable assignment", 6383f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Deoptimizer::EAGER); 6384f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org builder.End(); 6385e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } 6386e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } 6387e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org HInstruction* instr = 6388e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails()); 6389fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (instr->HasObservableSideEffects()) { 6390c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6391fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 6392c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } else { 639305150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org HValue* global_object = Add<HLoadNamedField>( 639409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org context(), static_cast<HValue*>(NULL), 639509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 639643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org HStoreNamedGeneric* instr = 639743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org Add<HStoreNamedGeneric>(global_object, var->name(), 6398486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org value, function_strict_mode()); 639971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org USE(instr); 6400c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(instr->HasObservableSideEffects()); 6401c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6402c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } 6403a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6404a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6405a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6406a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 6407a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Expression* target = expr->target(); 6408a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org VariableProxy* proxy = target->AsVariableProxy(); 6409a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Property* prop = target->AsProperty(); 6410486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ASSERT(proxy == NULL || prop == NULL); 6411a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6412a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // We have a second position recorded in the FullCodeGenerator to have 6413a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // type feedback for the binary operation. 6414a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org BinaryOperation* operation = expr->binary_operation(); 6415a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6416486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (proxy != NULL) { 6417486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Variable* var = proxy->var(); 64187ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org if (var->mode() == LET) { 6419594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kUnsupportedLetCompoundAssignment); 6420d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } 6421d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 6422160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(operation)); 6423a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6424486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org switch (var->location()) { 6425486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::UNALLOCATED: 6426486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org HandleGlobalVariableAssignment(var, 6427486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Top(), 6428486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org expr->AssignmentId()); 6429486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org break; 6430486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 6431486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::PARAMETER: 6432486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::LOCAL: 6433486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (var->mode() == CONST_LEGACY) { 6434594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kUnsupportedConstCompoundAssignment); 64357ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } 6436d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org BindIfLive(var, Top()); 6437486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org break; 6438486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 6439486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::CONTEXT: { 6440486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Bail out if we try to mutate a parameter value in a function 6441486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // using the arguments object. We do not (yet) correctly handle the 6442486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // arguments property of the function. 644341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (current_info()->scope()->arguments() != NULL) { 6444486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Parameters will be allocated to context slots. We have no 6445486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // direct way to detect that the variable is a parameter so we do 6446486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // a linear search of the parameter variables. 644741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org int count = current_info()->scope()->num_parameters(); 6448486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org for (int i = 0; i < count; ++i) { 644941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (var == current_info()->scope()->parameter(i)) { 6450594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Bailout(kAssignmentToParameterFunctionUsesArgumentsObject); 6451486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 64527b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 64537b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 6454486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 64557ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org HStoreContextSlot::Mode mode; 64567ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 64577ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org switch (var->mode()) { 64587ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org case LET: 64597ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org mode = HStoreContextSlot::kCheckDeoptimize; 64607ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org break; 64617ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org case CONST: 64627ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org // This case is checked statically so no need to 64637ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org // perform checks here 64647ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org UNREACHABLE(); 6465486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org case CONST_LEGACY: 6466486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org return ast_context()->ReturnValue(Pop()); 64677ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org default: 64687ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org mode = HStoreContextSlot::kNoCheck; 64697ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } 64707ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 6471486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org HValue* context = BuildContextChainWalk(var); 6472d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HStoreContextSlot* instr = Add<HStoreContextSlot>( 6473d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org context, var->index(), mode, Top()); 6474c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->HasObservableSideEffects()) { 6475c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 6476c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 6477486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org break; 64787b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 64797b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org 6480486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::LOOKUP: 6481594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kCompoundAssignmentToLookupSlot); 6482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 64834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnValue(Pop()); 64845f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 6485a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (prop != NULL) { 6486639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org CHECK_ALIVE(VisitForValue(prop->obj())); 6487639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org HValue* object = Top(); 6488639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org HValue* key = NULL; 6489528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if ((!prop->IsFunctionPrototype() && !prop->key()->IsPropertyName()) || 6490639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org prop->IsStringAccess()) { 6491160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(prop->key())); 6492639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org key = Top(); 6493639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org } 6494a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 649571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org CHECK_ALIVE(PushLoad(prop, object, key)); 64967b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org 6497639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org CHECK_ALIVE(VisitForValue(expr->value())); 6498639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org HValue* right = Pop(); 6499639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org HValue* left = Pop(); 65005f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 650125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org Push(BuildBinaryOperation(operation, left, right, PUSH_BEFORE_SIMULATE)); 650225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org 6503639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org BuildStore(expr, prop, expr->id(), 6504639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org expr->AssignmentId(), expr->IsUninitialized()); 6505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 6506594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kInvalidLhsInCompoundAssignment); 6507a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 6508a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6509a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6510a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6511a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { 6512160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 6513160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 6514160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 6515a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org VariableProxy* proxy = expr->target()->AsVariableProxy(); 6516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Property* prop = expr->target()->AsProperty(); 6517486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ASSERT(proxy == NULL || prop == NULL); 6518a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6519a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (expr->is_compound()) { 6520a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HandleCompoundAssignment(expr); 6521a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return; 6522a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 6523a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6524486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (prop != NULL) { 6525486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org HandlePropertyAssignment(expr); 6526486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } else if (proxy != NULL) { 6527486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Variable* var = proxy->var(); 65287ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 6529b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org if (var->mode() == CONST) { 6530d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org if (expr->op() != Token::INIT_CONST) { 6531486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org return Bailout(kNonInitializerAssignmentToConst); 6532486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org } 6533486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org } else if (var->mode() == CONST_LEGACY) { 6534486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (expr->op() != Token::INIT_CONST_LEGACY) { 65357ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org CHECK_ALIVE(VisitForValue(expr->value())); 65367ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org return ast_context()->ReturnValue(Pop()); 6537d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } 65387ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 65397ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org if (var->IsStackAllocated()) { 65407ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org // We insert a use of the old value to detect unsupported uses of const 65417ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org // variables (e.g. initialization inside a loop). 65427ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org HValue* old_value = environment()->Lookup(var); 65431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Add<HUseConst>(old_value); 6544d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com } 6545d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } 6546d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 6547594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (proxy->IsArguments()) return Bailout(kAssignmentToArguments); 65485f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 65495f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Handle the assignment. 6550486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org switch (var->location()) { 6551486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::UNALLOCATED: 6552486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org CHECK_ALIVE(VisitForValue(expr->value())); 6553486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org HandleGlobalVariableAssignment(var, 6554486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Top(), 6555486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org expr->AssignmentId()); 6556486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org return ast_context()->ReturnValue(Pop()); 6557486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 6558486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::PARAMETER: 6559486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::LOCAL: { 656064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Perform an initialization check for let declared variables 656164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // or parameters. 656264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (var->mode() == LET && expr->op() == Token::ASSIGN) { 656364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org HValue* env_value = environment()->Lookup(var); 656464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (env_value == graph()->GetConstantHole()) { 6565594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kAssignmentToLetVariableBeforeInitialization); 656664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 656764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 6568486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // We do not allow the arguments object to occur in a context where it 6569486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // may escape, but assignments to stack-allocated locals are 6570486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // permitted. 6571486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); 6572486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org HValue* value = Pop(); 6573d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org BindIfLive(var, value); 6574486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org return ast_context()->ReturnValue(value); 6575486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 657683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 6577486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::CONTEXT: { 6578486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Bail out if we try to mutate a parameter value in a function using 6579486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // the arguments object. We do not (yet) correctly handle the 6580486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // arguments property of the function. 658141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (current_info()->scope()->arguments() != NULL) { 6582486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Parameters will rewrite to context slots. We have no direct way 6583486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // to detect that the variable is a parameter. 658441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org int count = current_info()->scope()->num_parameters(); 6585486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org for (int i = 0; i < count; ++i) { 658641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (var == current_info()->scope()->parameter(i)) { 6587594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kAssignmentToParameterInArgumentsObject); 6588486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 65897b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 65907b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 65917b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org 6592486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org CHECK_ALIVE(VisitForValue(expr->value())); 659364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org HStoreContextSlot::Mode mode; 659464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (expr->op() == Token::ASSIGN) { 65957ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org switch (var->mode()) { 65967ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org case LET: 65977ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org mode = HStoreContextSlot::kCheckDeoptimize; 65987ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org break; 65997ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org case CONST: 66007ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org // This case is checked statically so no need to 66017ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org // perform checks here 66027ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org UNREACHABLE(); 6603486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org case CONST_LEGACY: 6604486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org return ast_context()->ReturnValue(Pop()); 66057ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org default: 66067ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org mode = HStoreContextSlot::kNoCheck; 66077ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } 66087ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org } else if (expr->op() == Token::INIT_VAR || 66097ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org expr->op() == Token::INIT_LET || 6610486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org expr->op() == Token::INIT_CONST) { 66117ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org mode = HStoreContextSlot::kNoCheck; 661264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 6613486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org ASSERT(expr->op() == Token::INIT_CONST_LEGACY); 66147ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 66157ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org mode = HStoreContextSlot::kCheckIgnoreAssignment; 661664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 66177ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 66187ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org HValue* context = BuildContextChainWalk(var); 6619d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HStoreContextSlot* instr = Add<HStoreContextSlot>( 6620d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org context, var->index(), mode, Top()); 6621c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->HasObservableSideEffects()) { 6622c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 6623c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 6624486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org return ast_context()->ReturnValue(Pop()); 6625486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 662683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 6627486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::LOOKUP: 6628594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kAssignmentToLOOKUPVariable); 6629a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 6630a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 6631594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kInvalidLeftHandSideInAssignment); 6632a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 6633a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6634a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6635a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6636f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgvoid HOptimizedGraphBuilder::VisitYield(Yield* expr) { 6637f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Generators are not optimized, so we should never get here. 6638f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org UNREACHABLE(); 6639f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org} 6640f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 6641f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 6642a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitThrow(Throw* expr) { 6643160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 6644160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 6645160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 66465f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // We don't optimize functions with invalid left-hand sides in 66475f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // assignments, count operations, or for-in. Consequently throw can 66485f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // currently only occur in an effect context. 66495f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org ASSERT(ast_context()->IsEffect()); 6650160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(expr->exception())); 6651a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6652a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* value = environment()->Pop(); 6653f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 66548d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Add<HPushArguments>(value); 665509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org Add<HCallRuntime>(isolate()->factory()->empty_string(), 6656895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Runtime::FunctionForId(Runtime::kHiddenThrow), 1); 6657c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HSimulate>(expr->id()); 6658c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org 6659c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org // If the throw definitely exits the function, we can finish with a dummy 6660c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org // control flow at this point. This is not the case if the throw is inside 6661c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org // an inlined function which may be replaced. 6662c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org if (call_context() == NULL) { 6663db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org FinishExitCurrentBlock(New<HAbnormalExit>()); 6664c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org } 6665a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6666a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6667a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 66680f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgHInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) { 66690f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if (string->IsConstant()) { 66700f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HConstant* c_string = HConstant::cast(string); 66710f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if (c_string->HasStringValue()) { 66720f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org return Add<HConstant>(c_string->StringValue()->map()->instance_type()); 6673d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 667457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 6675f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return Add<HLoadNamedField>( 6676f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Add<HLoadNamedField>(string, static_cast<HValue*>(NULL), 6677f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HObjectAccess::ForMap()), 6678f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static_cast<HValue*>(NULL), HObjectAccess::ForMapInstanceType()); 66790f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org} 66800f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 66810f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 66820f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgHInstruction* HGraphBuilder::AddLoadStringLength(HValue* string) { 66830f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if (string->IsConstant()) { 66840f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HConstant* c_string = HConstant::cast(string); 66850f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if (c_string->HasStringValue()) { 66860f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org return Add<HConstant>(c_string->StringValue()->length()); 66870f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } 66880f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } 6689f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return Add<HLoadNamedField>(string, static_cast<HValue*>(NULL), 6690f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HObjectAccess::ForStringLength()); 6691a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6692a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6693a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6694f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( 6695f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PropertyAccessType access_type, 6696a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* object, 6697a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> name, 6698f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HValue* value, 66998297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org bool is_uninitialized) { 67008297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (is_uninitialized) { 6701f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Add<HDeoptimize>("Insufficient type feedback for generic named access", 6702594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Deoptimizer::SOFT); 6703531dfe85209e15c3e292569c285a5be54910da7cjkummerow@chromium.org } 6704f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (access_type == LOAD) { 6705f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return New<HLoadNamedGeneric>(object, name); 6706f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 6707486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org return New<HStoreNamedGeneric>(object, name, value, function_strict_mode()); 6708f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 6709a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6710a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6711a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 671281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org 6713f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric( 6714f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PropertyAccessType access_type, 6715f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HValue* object, 6716f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HValue* key, 6717f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HValue* value) { 6718f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (access_type == LOAD) { 6719f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return New<HLoadKeyedGeneric>(object, key); 6720f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 6721486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org return New<HStoreKeyedGeneric>(object, key, value, function_strict_mode()); 6722f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 6723a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6724a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6725a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 67261e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.orgLoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) { 6727906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org // Loads from a "stock" fast holey double arrays can elide the hole check. 6728906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; 6729906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && 6730906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org isolate()->IsFastArrayConstructorPrototypeChainIntact()) { 6731906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); 6732906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); 6733594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org BuildCheckPrototypeMaps(prototype, object_prototype); 6734906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org load_mode = ALLOW_RETURN_HOLE; 6735906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org graph()->MarkDependsOnEmptyArrayProtoElements(); 6736906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } 6737906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org 67381e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org return load_mode; 67391e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org} 67401e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 67411e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 67421e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( 67431e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org HValue* object, 67441e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org HValue* key, 67451e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org HValue* val, 67461e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org HValue* dependency, 67471e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org Handle<Map> map, 6748f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PropertyAccessType access_type, 67491e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org KeyedAccessStoreMode store_mode) { 6750af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org HCheckMaps* checked_object = Add<HCheckMaps>(object, map, dependency); 67511e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (dependency) { 6752f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org checked_object->ClearDependsOnFlag(kElementsKind); 67531e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 67541e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 6755f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (access_type == STORE && map->prototype()->IsJSObject()) { 6756e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // monomorphic stores need a prototype chain check because shape 6757e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // changes could allow callbacks on elements in the chain that 6758e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // aren't compatible with monomorphic keyed stores. 6759e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Handle<JSObject> prototype(JSObject::cast(map->prototype())); 6760e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org JSObject* holder = JSObject::cast(map->prototype()); 6761e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org while (!holder->GetPrototype()->IsNull()) { 6762e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org holder = JSObject::cast(holder->GetPrototype()); 6763e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 6764e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 6765e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org BuildCheckPrototypeMaps(prototype, 6766e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Handle<JSObject>(JSObject::cast(holder))); 6767e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 6768e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 67691e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); 6770a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return BuildUncheckedMonomorphicElementAccess( 67711e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org checked_object, key, val, 67721e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org map->instance_type() == JS_ARRAY_TYPE, 6773f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org map->elements_kind(), access_type, 67741e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org load_mode, store_mode); 6775a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 6776a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6777a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6778a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( 6779c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org HValue* object, 6780c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org HValue* key, 6781c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org HValue* val, 6782c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org SmallMapList* maps) { 6783c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org // For polymorphic loads of similar elements kinds (i.e. all tagged or all 6784c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org // double), always use the "worst case" code without a transition. This is 6785c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org // much faster than transitioning the elements to the worst case, trading a 6786c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org // HTransitionElements for a HCheckMaps, and avoiding mutation of the array. 6787c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org bool has_double_maps = false; 6788c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org bool has_smi_or_object_maps = false; 6789c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org bool has_js_array_access = false; 6790c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org bool has_non_js_array_access = false; 6791ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org bool has_seen_holey_elements = false; 6792c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org Handle<Map> most_general_consolidated_map; 6793c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org for (int i = 0; i < maps->length(); ++i) { 6794c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org Handle<Map> map = maps->at(i); 67954a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org if (!map->IsJSObjectMap()) return NULL; 6796c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org // Don't allow mixing of JSArrays with JSObjects. 6797c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org if (map->instance_type() == JS_ARRAY_TYPE) { 6798c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org if (has_non_js_array_access) return NULL; 6799c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org has_js_array_access = true; 6800c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org } else if (has_js_array_access) { 6801c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org return NULL; 6802c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org } else { 6803c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org has_non_js_array_access = true; 6804c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org } 6805c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org // Don't allow mixed, incompatible elements kinds. 6806c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org if (map->has_fast_double_elements()) { 6807c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org if (has_smi_or_object_maps) return NULL; 6808c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org has_double_maps = true; 6809c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org } else if (map->has_fast_smi_or_object_elements()) { 6810c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org if (has_double_maps) return NULL; 6811c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org has_smi_or_object_maps = true; 6812c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org } else { 6813c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org return NULL; 6814c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org } 6815ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org // Remember if we've ever seen holey elements. 6816ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org if (IsHoleyElementsKind(map->elements_kind())) { 6817ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org has_seen_holey_elements = true; 6818ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org } 6819c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org // Remember the most general elements kind, the code for its load will 6820c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org // properly handle all of the more specific cases. 6821c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org if ((i == 0) || IsMoreGeneralElementsKindTransition( 6822c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org most_general_consolidated_map->elements_kind(), 6823c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org map->elements_kind())) { 6824c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org most_general_consolidated_map = map; 6825c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org } 6826c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org } 6827c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org if (!has_double_maps && !has_smi_or_object_maps) return NULL; 6828c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 6829052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org HCheckMaps* checked_object = Add<HCheckMaps>(object, maps); 6830ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org // FAST_ELEMENTS is considered more general than FAST_HOLEY_SMI_ELEMENTS. 6831ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org // If we've seen both, the consolidated load must use FAST_HOLEY_ELEMENTS. 6832ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org ElementsKind consolidated_elements_kind = has_seen_holey_elements 6833ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org ? GetHoleyElementsKind(most_general_consolidated_map->elements_kind()) 6834ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org : most_general_consolidated_map->elements_kind(); 6835c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org HInstruction* instr = BuildUncheckedMonomorphicElementAccess( 68361e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org checked_object, key, val, 6837a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, 6838ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org consolidated_elements_kind, 6839f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LOAD, NEVER_RETURN_HOLE, STANDARD_STORE); 6840c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org return instr; 6841c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org} 6842c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 6843c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 6844a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( 6845a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* object, 6846a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* key, 6847a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* val, 68484a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org SmallMapList* maps, 6849f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PropertyAccessType access_type, 68507bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org KeyedAccessStoreMode store_mode, 6851a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool* has_side_effects) { 68527b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org *has_side_effects = false; 68531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org BuildCheckHeapObject(object); 68547b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org 6855f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (access_type == LOAD) { 6856c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org HInstruction* consolidated_load = 6857c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org TryBuildConsolidatedElementLoad(object, key, val, maps); 6858c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org if (consolidated_load != NULL) { 6859c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org *has_side_effects |= consolidated_load->HasObservableSideEffects(); 6860c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org return consolidated_load; 6861c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org } 6862c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org } 6863c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 6864394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Elements_kind transition support. 6865394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com MapHandleList transition_target(maps->length()); 6866394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Collect possible transition targets. 6867394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com MapHandleList possible_transitioned_maps(maps->length()); 68687b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org for (int i = 0; i < maps->length(); ++i) { 6869394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Map> map = maps->at(i); 6870394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ElementsKind elements_kind = map->elements_kind(); 6871830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (IsFastElementsKind(elements_kind) && 6872830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org elements_kind != GetInitialFastElementsKind()) { 6873394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com possible_transitioned_maps.Add(map); 687444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 6875fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) { 6876fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org HInstruction* result = BuildKeyedGeneric(access_type, object, key, val); 6877fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org *has_side_effects = result->HasObservableSideEffects(); 6878fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org return AddInstruction(result); 6879fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org } 688044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 6881394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Get transition target for each map (NULL == no transition). 6882394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for (int i = 0; i < maps->length(); ++i) { 6883394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Map> map = maps->at(i); 6884394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Map> transitioned_map = 6885394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com map->FindTransitionedMap(&possible_transitioned_maps); 6886394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com transition_target.Add(transitioned_map); 6887394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 6888a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6889ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org MapHandleList untransitionable_maps(maps->length()); 6890830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org HTransitionElementsKind* transition = NULL; 6891394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for (int i = 0; i < maps->length(); ++i) { 6892394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Map> map = maps->at(i); 6893394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(map->IsMap()); 6894394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (!transition_target.at(i).is_null()) { 6895830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org ASSERT(Map::IsValidElementsTransition( 6896830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org map->elements_kind(), 6897830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org transition_target.at(i)->elements_kind())); 6898d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org transition = Add<HTransitionElementsKind>(object, map, 68991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org transition_target.at(i)); 6900394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 6901ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org untransitionable_maps.Add(map); 6902394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 6903394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 6904394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 6905394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // If only one map is left after transitioning, handle this case 6906394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // monomorphically. 6907ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ASSERT(untransitionable_maps.length() >= 1); 6908ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if (untransitionable_maps.length() == 1) { 6909ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<Map> untransitionable_map = untransitionable_maps[0]; 69102efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org HInstruction* instr = NULL; 69114a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org if (untransitionable_map->has_slow_elements_kind() || 69124a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org !untransitionable_map->IsJSObjectMap()) { 6913f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org instr = AddInstruction(BuildKeyedGeneric(access_type, object, key, val)); 69142efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } else { 69157bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org instr = BuildMonomorphicElementAccess( 6916f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org object, key, val, transition, untransitionable_map, access_type, 69177bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org store_mode); 69182efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 6919c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org *has_side_effects |= instr->HasObservableSideEffects(); 6920f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return access_type == STORE ? NULL : instr; 6921394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 6922394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 69237b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org HBasicBlock* join = graph()->CreateBasicBlock(); 6924a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 6925ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org for (int i = 0; i < untransitionable_maps.length(); ++i) { 6926ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<Map> map = untransitionable_maps[i]; 69274a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org if (!map->IsJSObjectMap()) continue; 6928ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ElementsKind elements_kind = map->elements_kind(); 6929ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HBasicBlock* this_map = graph()->CreateBasicBlock(); 6930ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HBasicBlock* other_map = graph()->CreateBasicBlock(); 6931ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HCompareMap* mapcompare = 6932052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org New<HCompareMap>(object, map, this_map, other_map); 693371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org FinishCurrentBlock(mapcompare); 6934ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 6935ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org set_current_block(this_map); 6936ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HInstruction* access = NULL; 69371e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (IsDictionaryElementsKind(elements_kind)) { 6938f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org access = AddInstruction(BuildKeyedGeneric(access_type, object, key, val)); 6939ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } else { 69401e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org ASSERT(IsFastElementsKind(elements_kind) || 6941895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org IsExternalArrayElementsKind(elements_kind) || 6942895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org IsFixedTypedArrayElementsKind(elements_kind)); 69431e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); 69441e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Happily, mapcompare is a checked object. 69451e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org access = BuildUncheckedMonomorphicElementAccess( 69461e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org mapcompare, key, val, 69471e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org map->instance_type() == JS_ARRAY_TYPE, 6948f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org elements_kind, access_type, 69491e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org load_mode, 69501e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org store_mode); 6951ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 6952ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org *has_side_effects |= access->HasObservableSideEffects(); 6953ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // The caller will use has_side_effects and add a correct Simulate. 6954ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org access->SetFlag(HValue::kHasNoObservableSideEffects); 6955f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (access_type == LOAD) { 6956ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Push(access); 69577b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 6958ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org NoObservableSideEffectsScope scope(this); 695971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org GotoNoSimulate(join); 6960ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org set_current_block(other_map); 6961c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 69627b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org 6963f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Ensure that we visited at least one map above that goes to join. This is 6964f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // necessary because FinishExitWithHardDeoptimization does an AbnormalExit 6965f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // rather than joining the join block. If this becomes an issue, insert a 6966f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // generic access in the case length() == 0. 6967f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ASSERT(join->predecessors()->length() > 0); 69687b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // Deopt if none of the cases matched. 6969c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org NoObservableSideEffectsScope scope(this); 6970f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org FinishExitWithHardDeoptimization("Unknown map in polymorphic element access"); 69717b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org set_current_block(join); 6972f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return access_type == STORE ? NULL : Pop(); 697344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org} 697444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 697544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 6976a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( 6977a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* obj, 6978a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* key, 6979a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* val, 6980a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Expression* expr, 6981f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PropertyAccessType access_type, 6982a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool* has_side_effects) { 69837b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org ASSERT(!expr->IsPropertyName()); 69847b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org HInstruction* instr = NULL; 6985639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 6986639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org SmallMapList* types; 69870a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone()); 6988639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 6989e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org bool force_generic = false; 6990f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (access_type == STORE && 6991f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org (monomorphic || (types != NULL && !types->is_empty()))) { 6992e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Stores can't be mono/polymorphic if their prototype chain has dictionary 6993e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // elements. However a receiver map that has dictionary elements itself 6994e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // should be left to normal mono/poly behavior (the other maps may benefit 6995e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // from highly optimized stores). 6996e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org for (int i = 0; i < types->length(); i++) { 6997e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Handle<Map> current_map = types->at(i); 6998e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (current_map->DictionaryElementsInPrototypeChainOnly()) { 6999e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org force_generic = true; 7000e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org monomorphic = false; 7001e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org break; 7002e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 7003e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 7004e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 7005e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 7006639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (monomorphic) { 7007639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Handle<Map> map = types->first(); 700857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (map->has_slow_elements_kind() || !map->IsJSObjectMap()) { 7009f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org instr = AddInstruction(BuildKeyedGeneric(access_type, obj, key, val)); 70102efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } else { 70111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org BuildCheckHeapObject(obj); 70127bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org instr = BuildMonomorphicElementAccess( 7013f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org obj, key, val, NULL, map, access_type, expr->GetStoreMode()); 70142efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 7015e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else if (!force_generic && (types != NULL && !types->is_empty())) { 70167b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org return HandlePolymorphicElementAccess( 7017f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org obj, key, val, types, access_type, 70187bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org expr->GetStoreMode(), has_side_effects); 70197b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } else { 7020f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (access_type == STORE) { 7021c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (expr->IsAssignment() && 7022c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org expr->AsAssignment()->HasNoTypeInformation()) { 70233d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Add<HDeoptimize>("Insufficient type feedback for keyed store", 7024594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Deoptimizer::SOFT); 7025169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 70267b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } else { 7027c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (expr->AsProperty()->HasNoTypeInformation()) { 70283d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Add<HDeoptimize>("Insufficient type feedback for keyed load", 7029594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Deoptimizer::SOFT); 7030169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 703144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 7032f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org instr = AddInstruction(BuildKeyedGeneric(access_type, obj, key, val)); 703344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 7034c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org *has_side_effects = instr->HasObservableSideEffects(); 70357b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org return instr; 70363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 70373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 70383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 7039a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { 704028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // Outermost function already has arguments on the stack. 704128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org if (function_state()->outer() == NULL) return; 704228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 704328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org if (function_state()->arguments_pushed()) return; 704428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 704528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // Push arguments when entering inlined function. 704628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org HEnterInlined* entry = function_state()->entry(); 704756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org entry->set_arguments_pushed(); 704828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 7049b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org HArgumentsObject* arguments = entry->arguments_object(); 7050b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org const ZoneList<HValue*>* arguments_values = arguments->arguments_values(); 705128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 705228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org HInstruction* insert_after = entry; 705328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org for (int i = 0; i < arguments_values->length(); i++) { 705428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org HValue* argument = arguments_values->at(i); 70558d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org HInstruction* push_argument = New<HPushArguments>(argument); 705628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org push_argument->InsertAfter(insert_after); 705728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org insert_after = push_argument; 705828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 705928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 7060d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HArgumentsElements* arguments_elements = New<HArgumentsElements>(true); 706128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org arguments_elements->ClearFlag(HValue::kUseGVN); 706228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org arguments_elements->InsertAfter(insert_after); 706328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org function_state()->set_arguments_elements(arguments_elements); 706428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org} 706528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 706628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 7067a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgbool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { 7068a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org VariableProxy* proxy = expr->obj()->AsVariableProxy(); 7069a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (proxy == NULL) return false; 7070a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (!proxy->var()->IsStackAllocated()) return false; 7071a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { 7072a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return false; 7073a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 7074a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 70755f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org HInstruction* result = NULL; 7076a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (expr->key()->IsPropertyName()) { 7077a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 707859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("length"))) return false; 707928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 708028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org if (function_state()->outer() == NULL) { 70811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* elements = Add<HArgumentsElements>(false); 7082d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org result = New<HArgumentsLength>(elements); 708328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } else { 708428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // Number of arguments without receiver. 708528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org int argument_count = environment()-> 708628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org arguments_environment()->parameter_count() - 1; 7087d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org result = New<HConstant>(argument_count); 708828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 7089a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 70909ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org Push(graph()->GetArgumentsObject()); 7091639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org CHECK_ALIVE_OR_RETURN(VisitForValue(expr->key()), true); 7092a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* key = Pop(); 70939ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org Drop(1); // Arguments object. 709428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org if (function_state()->outer() == NULL) { 70951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* elements = Add<HArgumentsElements>(false); 70961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* length = Add<HArgumentsLength>(elements); 70971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* checked_key = Add<HBoundsCheck>(key, length); 7098db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org result = New<HAccessArgumentsAt>(elements, length, checked_key); 709928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } else { 710028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org EnsureArgumentsArePushedForAccess(); 710128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 710228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // Number of arguments without receiver. 710328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org HInstruction* elements = function_state()->arguments_elements(); 710428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org int argument_count = environment()-> 710528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org arguments_environment()->parameter_count() - 1; 71061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* length = Add<HConstant>(argument_count); 71071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* checked_key = Add<HBoundsCheck>(key, length); 7108db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org result = New<HAccessArgumentsAt>(elements, length, checked_key); 710928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 7110a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 71115f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org ast_context()->ReturnInstruction(result, expr->id()); 7112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return true; 7113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 7114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 71168297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildNamedAccess( 71178297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org PropertyAccessType access, 71188297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org BailoutId ast_id, 71198297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org BailoutId return_id, 71208297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org Expression* expr, 71218297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org HValue* object, 71228297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org Handle<String> name, 71238297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org HValue* value, 71248297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org bool is_uninitialized) { 71258297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org SmallMapList* types; 71268297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ComputeReceiverTypes(expr, object, &types, zone()); 71278297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ASSERT(types != NULL); 71288297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org 71298297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (types->length() > 0) { 71308297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org PropertyAccessInfo info(this, access, ToType(types->first()), name); 71318297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (!info.CanAccessAsMonomorphic(types)) { 71328297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org HandlePolymorphicNamedFieldAccess( 71338297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org access, ast_id, return_id, object, value, types, name); 71348297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org return NULL; 71358297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org } 71368297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org 71378297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org HValue* checked_object; 71388297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org // Type::Number() is only supported by polymorphic load/call handling. 71398297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ASSERT(!info.type()->Is(Type::Number())); 71408297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org BuildCheckHeapObject(object); 71418297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (AreStringTypes(types)) { 71428297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org checked_object = 71438297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); 71448297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org } else { 7145052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org checked_object = Add<HCheckMaps>(object, types); 71468297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org } 71478297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org return BuildMonomorphicAccess( 71488297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org &info, object, checked_object, value, ast_id, return_id); 71498297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org } 71508297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org 7151f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return BuildNamedGeneric(access, object, name, value, is_uninitialized); 71528297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org} 71538297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org 71548297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org 71553d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgvoid HOptimizedGraphBuilder::PushLoad(Property* expr, 71563d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org HValue* object, 715771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org HValue* key) { 71583d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); 71593d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Push(object); 7160639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (key != NULL) Push(key); 716171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org BuildLoad(expr, expr->LoadId()); 71623d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org} 7163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 71653d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgvoid HOptimizedGraphBuilder::BuildLoad(Property* expr, 71663d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org BailoutId ast_id) { 7167a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HInstruction* instr = NULL; 7168528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (expr->IsStringAccess()) { 7169b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org HValue* index = Pop(); 7170b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org HValue* string = Pop(); 7171db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HInstruction* char_code = BuildStringCharCodeAt(string, index); 7172b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org AddInstruction(char_code); 7173db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org instr = NewUncasted<HStringCharFromCode>(char_code); 7174378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org 71759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org } else if (expr->IsFunctionPrototype()) { 71769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org HValue* function = Pop(); 71771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org BuildCheckHeapObject(function); 7178db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org instr = New<HLoadFunctionPrototype>(function); 7179a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7180a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (expr->key()->IsPropertyName()) { 7181a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 7182528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org HValue* object = Pop(); 7183a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 71848297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org instr = BuildNamedAccess(LOAD, ast_id, expr->LoadId(), expr, 71858297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org object, name, NULL, expr->IsUninitialized()); 71868297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (instr == NULL) return; 71878297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (instr->IsLinked()) return ast_context()->ReturnValue(instr); 7188a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 7190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* key = Pop(); 7191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* obj = Pop(); 71927b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org 71937b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org bool has_side_effects = false; 71947b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org HValue* load = HandleKeyedElementAccess( 7195f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org obj, key, NULL, expr, LOAD, &has_side_effects); 71967b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org if (has_side_effects) { 71977b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org if (ast_context()->IsEffect()) { 71983d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 71997b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } else { 72007b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org Push(load); 72013d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 72027b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org Drop(1); 72037b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 72047b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 72054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnValue(load); 7206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 72073d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org return ast_context()->ReturnInstruction(instr, ast_id); 72083d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org} 72093d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org 72103d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org 72113d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgvoid HOptimizedGraphBuilder::VisitProperty(Property* expr) { 72123d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org ASSERT(!HasStackOverflow()); 72133d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org ASSERT(current_block() != NULL); 72143d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org ASSERT(current_block()->HasPredecessor()); 72153d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org 72163d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org if (TryArgumentsAccess(expr)) return; 72173d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org 72183d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org CHECK_ALIVE(VisitForValue(expr->obj())); 7219528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if ((!expr->IsFunctionPrototype() && !expr->key()->IsPropertyName()) || 7220639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org expr->IsStringAccess()) { 7221639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org CHECK_ALIVE(VisitForValue(expr->key())); 7222639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org } 7223639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 722471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org BuildLoad(expr, expr->id()); 7225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 7226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7228af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.orgHInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant) { 7229af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org HCheckMaps* check = Add<HCheckMaps>( 7230af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org Add<HConstant>(constant), handle(constant->map())); 7231f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org check->ClearDependsOnFlag(kElementsKind); 7232ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org return check; 7233594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 7234594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 7235594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 7236ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.orgHInstruction* HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype, 7237ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org Handle<JSObject> holder) { 7238202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org while (holder.is_null() || !prototype.is_identical_to(holder)) { 7239af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org BuildConstantMapCheck(prototype); 7240202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org Object* next_prototype = prototype->GetPrototype(); 7241202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org if (next_prototype->IsNull()) return NULL; 7242202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org CHECK(next_prototype->IsJSObject()); 7243202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org prototype = handle(JSObject::cast(next_prototype)); 7244594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org } 7245af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org return BuildConstantMapCheck(prototype); 7246594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org} 7247594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 7248594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 7249a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, 7250a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<Map> receiver_map) { 7251e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (!holder.is_null()) { 72526bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); 7253594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org BuildCheckPrototypeMaps(prototype, holder); 7254e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 7255e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 7256e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 7257e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 725826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgHInstruction* HOptimizedGraphBuilder::NewPlainFunctionCall( 725926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org HValue* fun, int argument_count, bool pass_argument_count) { 726026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org return New<HCallJSFunction>( 726126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org fun, argument_count, pass_argument_count); 726226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org} 726326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 726426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 726526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgHInstruction* HOptimizedGraphBuilder::NewArgumentAdaptorCall( 726626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org HValue* fun, HValue* context, 726726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org int argument_count, HValue* expected_param_count) { 726826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org CallInterfaceDescriptor* descriptor = 726926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org isolate()->call_descriptor(Isolate::ArgumentAdaptorCall); 727026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 727126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org HValue* arity = Add<HConstant>(argument_count - 1); 727226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 727326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org HValue* op_vals[] = { fun, context, arity, expected_param_count }; 727426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 727526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org Handle<Code> adaptor = 727626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org isolate()->builtins()->ArgumentsAdaptorTrampoline(); 727726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org HConstant* adaptor_value = Add<HConstant>(adaptor); 727826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 727926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org return New<HCallWithDescriptor>( 728026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org adaptor_value, argument_count, descriptor, 728126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org Vector<HValue*>(op_vals, descriptor->environment_length())); 728226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org} 728326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 728426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 728526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildCallConstantFunction( 728626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org Handle<JSFunction> jsfun, int argument_count) { 728726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org HValue* target = Add<HConstant>(jsfun); 728826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org // For constant functions, we try to avoid calling the 728926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org // argument adaptor and instead call the function directly 729026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org int formal_parameter_count = jsfun->shared()->formal_parameter_count(); 729126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org bool dont_adapt_arguments = 729226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org (formal_parameter_count == 729326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org SharedFunctionInfo::kDontAdaptArgumentsSentinel); 729426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org int arity = argument_count - 1; 729526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org bool can_invoke_directly = 729626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org dont_adapt_arguments || formal_parameter_count == arity; 729726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org if (can_invoke_directly) { 7298a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (jsfun.is_identical_to(current_info()->closure())) { 7299a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org graph()->MarkRecursive(); 7300a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org } 730126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org return NewPlainFunctionCall(target, argument_count, dont_adapt_arguments); 730226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org } else { 730326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org HValue* param_count_value = Add<HConstant>(formal_parameter_count); 730409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* context = Add<HLoadNamedField>( 730509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org target, static_cast<HValue*>(NULL), 730626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org HObjectAccess::ForFunctionContextPointer()); 730726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org return NewArgumentAdaptorCall(target, context, 730826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org argument_count, param_count_value); 730926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org } 731026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org UNREACHABLE(); 731126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org return NULL; 731226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org} 731326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 731426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 73155aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.orgclass FunctionSorter { 73165aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org public: 73175aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org FunctionSorter(int index = 0, int ticks = 0, int size = 0) 73185aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org : index_(index), ticks_(ticks), size_(size) { } 73195aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org 73205aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org int index() const { return index_; } 73215aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org int ticks() const { return ticks_; } 73225aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org int size() const { return size_; } 73235aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org 73245aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org private: 73255aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org int index_; 73265aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org int ticks_; 73275aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org int size_; 73285aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org}; 73295aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org 73305aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org 73315aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.orginline bool operator<(const FunctionSorter& lhs, const FunctionSorter& rhs) { 73325aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org int diff = lhs.ticks() - rhs.ticks(); 73335aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org if (diff != 0) return diff > 0; 73345aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org return lhs.size() < rhs.size(); 73355aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org} 73365aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org 73375aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org 7338a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::HandlePolymorphicCallNamed( 7339a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Call* expr, 7340a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* receiver, 7341a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org SmallMapList* types, 7342a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> name) { 73434d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org int argument_count = expr->arguments()->length() + 1; // Includes receiver. 73445aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org FunctionSorter order[kMaxCallPolymorphism]; 73456e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 73466e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org bool handle_smi = false; 7347a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org bool handled_string = false; 7348a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org int ordered_functions = 0; 73496e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 7350212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org for (int i = 0; 7351e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org i < types->length() && ordered_functions < kMaxCallPolymorphism; 7352212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org ++i) { 73530a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name); 73540a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (info.CanAccessMonomorphic() && 7355a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org info.lookup()->IsConstant() && 7356a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org info.constant()->IsJSFunction()) { 73570a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (info.type()->Is(Type::String())) { 7358a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (handled_string) continue; 7359a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org handled_string = true; 7360a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org } 7361a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant()); 73620a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (info.type()->Is(Type::Number())) { 7363a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org handle_smi = true; 7364a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org } 7365a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org expr->set_target(target); 73665aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org order[ordered_functions++] = FunctionSorter( 73675aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org i, target->shared()->profiler_ticks(), InliningAstSize(target)); 7368212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org } 7369212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org } 73704d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org 73715aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org std::sort(order, order + ordered_functions); 73725aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org 73736e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org HBasicBlock* number_block = NULL; 7374a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org HBasicBlock* join = NULL; 7375a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org handled_string = false; 7376a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org int count = 0; 73776e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 7378e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org for (int fn = 0; fn < ordered_functions; ++fn) { 73795aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org int i = order[fn].index(); 73800a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name); 73810a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (info.type()->Is(Type::String())) { 7382a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (handled_string) continue; 7383a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org handled_string = true; 7384a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org } 7385a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Reloads the target. 73860a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org info.CanAccessMonomorphic(); 7387a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant()); 7388a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 7389a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org expr->set_target(target); 7390a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (count == 0) { 7391e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // Only needed once. 7392e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org join = graph()->CreateBasicBlock(); 7393e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org if (handle_smi) { 7394e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); 7395e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); 7396e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org number_block = graph()->CreateBasicBlock(); 7397e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org FinishCurrentBlock(New<HIsSmiAndBranch>( 7398e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org receiver, empty_smi_block, not_smi_block)); 7399f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org GotoNoSimulate(empty_smi_block, number_block); 7400e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org set_current_block(not_smi_block); 74016e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } else { 7402e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org BuildCheckHeapObject(receiver); 74039cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org } 7404e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org } 7405a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org ++count; 7406e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org HBasicBlock* if_true = graph()->CreateBasicBlock(); 7407e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org HBasicBlock* if_false = graph()->CreateBasicBlock(); 7408e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org HUnaryControlInstruction* compare; 7409e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 7410a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Handle<Map> map = info.map(); 74110a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (info.type()->Is(Type::Number())) { 7412a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); 7413052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org compare = New<HCompareMap>(receiver, heap_number_map, if_true, if_false); 74140a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org } else if (info.type()->Is(Type::String())) { 7415e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org compare = New<HIsStringAndBranch>(receiver, if_true, if_false); 7416e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org } else { 7417052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org compare = New<HCompareMap>(receiver, map, if_true, if_false); 7418e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org } 7419e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org FinishCurrentBlock(compare); 74209cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 74210a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (info.type()->Is(Type::Number())) { 7422f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org GotoNoSimulate(if_true, number_block); 7423e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org if_true = number_block; 74246e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } 7425a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 7426e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org set_current_block(if_true); 74276e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 7428a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org AddCheckPrototypeMaps(info.holder(), map); 7429a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 7430a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org HValue* function = Add<HConstant>(expr->target()); 7431a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org environment()->SetExpressionStackAt(0, function); 7432a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Push(receiver); 7433a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org CHECK_ALIVE(VisitExpressions(expr->arguments())); 7434a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org bool needs_wrapping = NeedsWrappingFor(info.type(), target); 7435a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org bool try_inline = FLAG_polymorphic_inlining && !needs_wrapping; 7436a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (FLAG_trace_inlining && try_inline) { 743741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<JSFunction> caller = current_info()->closure(); 7438212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org SmartArrayPointer<char> caller_name = 7439212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org caller->shared()->DebugName()->ToCString(); 7440212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org PrintF("Trying to inline the polymorphic call to %s from %s\n", 7441afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org name->ToCString().get(), 7442afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org caller_name.get()); 7443212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org } 7444a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (try_inline && TryInlineCall(expr)) { 7445212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // Trying to inline will signal that we should bailout from the 7446212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // entire compilation by setting stack overflow on the visitor. 7447212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org if (HasStackOverflow()) return; 7448212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org } else { 7449a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Since HWrapReceiver currently cannot actually wrap numbers and strings, 7450a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // use the regular CallFunctionStub for method calls to wrap the receiver. 7451a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // TODO(verwaest): Support creation of value wrappers directly in 7452a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // HWrapReceiver. 7453a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org HInstruction* call = needs_wrapping 7454a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org ? NewUncasted<HCallFunction>( 7455a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org function, argument_count, WRAP_AND_CALL) 7456a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org : BuildCallConstantFunction(target, argument_count); 745726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org PushArgumentsFromEnvironment(argument_count); 7458212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org AddInstruction(call); 7459a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Drop(1); // Drop the function. 7460212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org if (!ast_context()->IsEffect()) Push(call); 7461a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 74629cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 7463e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org if (current_block() != NULL) Goto(join); 7464212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org set_current_block(if_false); 7465a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 7466a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 74674d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // Finish up. Unconditionally deoptimize if we've handled all the maps we 74684d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // know about and do not want to handle ones we've never seen. Otherwise 74694d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // use a generic IC. 7470e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { 7471f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org FinishExitWithHardDeoptimization("Unknown map in polymorphic call"); 74724d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org } else { 7473a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Property* prop = expr->expression()->AsProperty(); 7474f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HInstruction* function = BuildNamedGeneric( 7475f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LOAD, receiver, name, NULL, prop->IsUninitialized()); 7476a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org AddInstruction(function); 7477a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Push(function); 7478a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 7479a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 7480a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org environment()->SetExpressionStackAt(1, function); 7481a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org environment()->SetExpressionStackAt(0, receiver); 7482a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org CHECK_ALIVE(VisitExpressions(expr->arguments())); 7483a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 7484a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org CallFunctionFlags flags = receiver->type().IsJSObject() 7485a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; 7486a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org HInstruction* call = New<HCallFunction>( 7487a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org function, argument_count, flags); 7488a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 748926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org PushArgumentsFromEnvironment(argument_count); 74908541d77d2d2a96c3e430974b3027f29b2a8e4a68lrn@chromium.org 7491a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Drop(1); // Function. 7492a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 74934d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org if (join != NULL) { 74944d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org AddInstruction(call); 74954d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org if (!ast_context()->IsEffect()) Push(call); 749671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(join); 74974d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org } else { 74984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(call, expr->id()); 7499c278c96bd6281dacdebe24cede7d454372362cadkmillikin@chromium.org } 75005f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 75014d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org 75024d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // We assume that control flow is always live after an expression. So 75034d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // even without predecessors to the join block, we set it as the exit 75044d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org // block and continue by adding instructions there. 75054d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org ASSERT(join != NULL); 75064d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org if (join->HasPredecessor()) { 7507160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org set_current_block(join); 75084d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org join->SetJoinId(expr->id()); 75094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); 7510160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else { 7511160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org set_current_block(NULL); 75124d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org } 7513a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 7514a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7515a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7516a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::TraceInline(Handle<JSFunction> target, 7517a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<JSFunction> caller, 7518a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org const char* reason) { 75198f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org if (FLAG_trace_inlining) { 752083e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org SmartArrayPointer<char> target_name = 752183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org target->shared()->DebugName()->ToCString(); 752283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org SmartArrayPointer<char> caller_name = 752383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org caller->shared()->DebugName()->ToCString(); 75248f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org if (reason == NULL) { 7525afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org PrintF("Inlined %s called from %s.\n", target_name.get(), 7526afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org caller_name.get()); 75278f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } else { 75288f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org PrintF("Did not inline %s called from %s (%s).\n", 7529afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org target_name.get(), caller_name.get(), reason); 75308f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 7531a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 7532a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 7533a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7534a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7535212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgstatic const int kNotInlinable = 1000000000; 7536212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 7537212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 7538a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgint HOptimizedGraphBuilder::InliningAstSize(Handle<JSFunction> target) { 7539212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org if (!FLAG_use_inlining) return kNotInlinable; 7540a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7541a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Precondition: call is monomorphic and we have found a target with the 7542a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // appropriate arity. 754341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<JSFunction> caller = current_info()->closure(); 7544ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<SharedFunctionInfo> target_shared(target->shared()); 7545a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 75460cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org // Always inline builtins marked for inlining. 75470cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org if (target->IsBuiltin()) { 75480cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org return target_shared->inline_builtin() ? 0 : kNotInlinable; 75490cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org } 75500cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 7551ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org if (target_shared->IsApiFunction()) { 7552ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org TraceInline(target, caller, "target is api function"); 7553ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org return kNotInlinable; 7554ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org } 7555ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 7556a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Do a quick check on source code length to avoid parsing large 7557a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // inlining candidates. 755888d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org if (target_shared->SourceSize() > 755988d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org Min(FLAG_max_inlined_source_size, kUnlimitedMaxInlinedSourceSize)) { 7560ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org TraceInline(target, caller, "target text too big"); 7561212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org return kNotInlinable; 7562a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 7563a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7564a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Target must be inlineable. 75650cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org if (!target_shared->IsInlineable()) { 7566ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org TraceInline(target, caller, "target not inlineable"); 7567212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org return kNotInlinable; 75688f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 756956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org if (target_shared->dont_inline() || target_shared->dont_optimize()) { 7570b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org TraceInline(target, caller, "target contains unsupported syntax [early]"); 7571212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org return kNotInlinable; 7572b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org } 7573b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org 7574b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org int nodes_added = target_shared->ast_node_count(); 7575212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org return nodes_added; 7576212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org} 7577212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 7578212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 7579e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.orgbool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target, 7580a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int arguments_count, 7581a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* implicit_return_value, 7582a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org BailoutId ast_id, 7583a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org BailoutId return_id, 7584f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org InliningKind inlining_kind, 7585f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HSourcePosition position) { 7586212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org int nodes_added = InliningAstSize(target); 7587212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org if (nodes_added == kNotInlinable) return false; 7588212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 758941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<JSFunction> caller = current_info()->closure(); 7590212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 759188d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { 7592b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org TraceInline(target, caller, "target AST is too large [early]"); 7593b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return false; 7594b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org } 7595a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7596ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Don't inline deeper than the maximum number of inlining levels. 7597a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HEnvironment* env = environment(); 759874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org int current_level = 1; 759974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org while (env->outer() != NULL) { 7600ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if (current_level == FLAG_max_inlining_levels) { 7601ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org TraceInline(target, caller, "inline depth limit reached"); 760274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org return false; 760374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org } 7604967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org if (env->outer()->frame_type() == JS_FUNCTION) { 7605659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org current_level++; 7606659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 760774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org env = env->outer(); 76088f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 7609a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7610a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Don't inline recursive functions. 7611394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for (FunctionState* state = function_state(); 7612394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com state != NULL; 7613394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com state = state->outer()) { 7614068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org if (*state->compilation_info()->closure() == *target) { 7615394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com TraceInline(target, caller, "target is recursive"); 7616394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return false; 7617394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 76188f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 7619a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7620a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // We don't want to add more than a certain number of nodes from inlining. 762188d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org if (inlined_count_ > Min(FLAG_max_inlined_nodes_cumulative, 762288d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org kUnlimitedMaxInlinedNodesCumulative)) { 7623ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org TraceInline(target, caller, "cumulative AST node limit reached"); 7624a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return false; 7625a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 7626a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7627a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Parse and allocate variables. 76285a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org CompilationInfo target_info(target, zone()); 7629068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org Handle<SharedFunctionInfo> target_shared(target->shared()); 7630e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (!Parser::Parse(&target_info) || !Scope::Analyze(&target_info)) { 7631ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (target_info.isolate()->has_pending_exception()) { 76328f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // Parse or scope error, never optimize this function. 7633496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org SetStackOverflow(); 7634594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org target_shared->DisableOptimization(kParseScopeError); 7635496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org } 7636ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org TraceInline(target, caller, "parse failure"); 76378f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org return false; 76388f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 76398f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 76408f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org if (target_info.scope()->num_heap_slots() > 0) { 7641ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org TraceInline(target, caller, "target has context-allocated variables"); 7642a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return false; 7643a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 76448f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org FunctionLiteral* function = target_info.function(); 7645a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7646b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org // The following conditions must be checked again after re-parsing, because 7647b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org // earlier the information might not have been complete due to lazy parsing. 7648b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org nodes_added = function->ast_node_count(); 764988d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { 7650b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org TraceInline(target, caller, "target AST is too large [late]"); 7651b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org return false; 7652b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org } 7653b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org AstProperties::Flags* flags(function->flags()); 76542c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org if (flags->Contains(kDontInline) || function->dont_optimize()) { 7655b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org TraceInline(target, caller, "target contains unsupported syntax [late]"); 7656a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return false; 7657a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 7658a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7659154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org // If the function uses the arguments object check that inlining of functions 7660154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org // with arguments object is enabled and the arguments-variable is 7661154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org // stack allocated. 7662659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org if (function->scope()->arguments() != NULL) { 7663154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org if (!FLAG_inline_arguments) { 7664154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org TraceInline(target, caller, "target uses arguments object"); 7665154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org return false; 7666154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org } 7667154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 7668154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org if (!function->scope()->arguments()->IsStackAllocated()) { 7669154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org TraceInline(target, 7670154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org caller, 7671154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org "target uses non-stackallocated arguments object"); 7672154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org return false; 7673154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org } 7674a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 7675a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7676d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com // All declarations must be inlineable. 7677d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com ZoneList<Declaration*>* decls = target_info.scope()->declarations(); 7678d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com int decl_count = decls->length(); 7679d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com for (int i = 0; i < decl_count; ++i) { 7680d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com if (!decls->at(i)->IsInlineable()) { 7681d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com TraceInline(target, caller, "target has non-trivial declaration"); 7682d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com return false; 7683d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com } 7684d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com } 7685a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7686a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Generate the deoptimization data for the unoptimized version of 7687a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // the target function if we don't already have it. 76888f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org if (!target_shared->has_deoptimization_support()) { 7689a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Note that we compile here using the same AST that we will use for 7690a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // generating the optimized inline code. 76918f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org target_info.EnableDeoptimizationSupport(); 76928f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org if (!FullCodeGenerator::MakeCode(&target_info)) { 7693ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org TraceInline(target, caller, "could not generate deoptimization info"); 76948f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org return false; 76958f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 76968432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org if (target_shared->scope_info() == ScopeInfo::Empty(isolate())) { 76974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // The scope info might not have been set if a lazily compiled 76984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // function is inlined before being called for the first time. 7699c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<ScopeInfo> target_scope_info = 77007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ScopeInfo::Create(target_info.scope(), zone()); 77014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org target_shared->set_scope_info(*target_scope_info); 77024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 77038f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org target_shared->EnableDeoptimizationSupport(*target_info.code()); 7704a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org target_shared->set_feedback_vector(*target_info.feedback_vector()); 77058f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG, 77068f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org &target_info, 77078f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org target_shared); 7708a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 7709a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 77108f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // ---------------------------------------------------------------- 7711d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com // After this point, we've made a decision to inline this function (so 7712d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com // TryInline should always return true). 7713d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 7714c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org // Type-check the inlined function. 77158f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org ASSERT(target_shared->has_deoptimization_support()); 771641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org AstTyper::Run(&target_info); 7717c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 7718f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int function_id = graph()->TraceInlinedFunction(target_shared, position); 7719f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 7720c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org // Save the pending call context. Set up new one for the inlined function. 7721394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // The function state is new-allocated because we need to delete it 7722394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // in two different places. 7723967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org FunctionState* target_state = new FunctionState( 7724f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org this, &target_info, inlining_kind, function_id); 7725a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 77264d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org HConstant* undefined = graph()->GetConstantUndefined(); 7727e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 77284d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org HEnvironment* inner_env = 77291c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org environment()->CopyForInlining(target, 7730304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org arguments_count, 77311c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org function, 773240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org undefined, 7733e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org function_state()->inlining_kind()); 7734935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org 77351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HConstant* context = Add<HConstant>(Handle<Context>(target->context())); 7736c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inner_env->BindContext(context); 773728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 7738b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org HArgumentsObject* arguments_object = NULL; 773928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 7740b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // If the function uses arguments object create and bind one, also copy 7741b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // current arguments values to use them for materialization. 774228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org if (function->scope()->arguments() != NULL) { 7743b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org ASSERT(function->scope()->arguments()->IsStackAllocated()); 774428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org HEnvironment* arguments_env = inner_env->arguments_environment(); 774528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org int arguments_count = arguments_env->parameter_count(); 7746d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org arguments_object = Add<HArgumentsObject>(arguments_count); 7747b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org inner_env->Bind(function->scope()->arguments(), arguments_object); 774828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org for (int i = 0; i < arguments_count; i++) { 7749b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org arguments_object->AddArgument(arguments_env->Lookup(i), zone()); 775028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 775128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 775228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 7753f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org // Capture the state before invoking the inlined function for deopt in the 7754f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org // inlined function. This simulate has no bailout-id since it's not directly 7755f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org // reachable for deopt, and is only used to capture the state. If the simulate 7756f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org // becomes reachable by merging, the ast id of the simulate merged into it is 7757f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org // adopted. 7758f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org Add<HSimulate>(BailoutId::None()); 7759f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org 7760f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org current_block()->UpdateEnvironment(inner_env); 77611e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org Scope* saved_scope = scope(); 77621e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org set_scope(target_info.scope()); 776328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org HEnterInlined* enter_inlined = 7764f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org Add<HEnterInlined>(return_id, target, arguments_count, function, 77651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org function_state()->inlining_kind(), 77661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org function->scope()->arguments(), 7767e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org arguments_object); 776828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org function_state()->set_entry(enter_inlined); 776928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 7770d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com VisitDeclarations(target_info.scope()->declarations()); 77714d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org VisitStatements(function->body()); 77721e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org set_scope(saved_scope); 7773a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (HasStackOverflow()) { 7774a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Bail out if the inline function did, as we cannot residualize a call 7775a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // instead. 7776ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org TraceInline(target, caller, "inline graph construction failed"); 7777594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org target_shared->DisableOptimization(kInliningBailedOut); 7778ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org inline_bailout_ = true; 7779394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com delete target_state; 7780160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org return true; 7781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 7782a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7783a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Update inlined nodes count. 7784a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org inlined_count_ += nodes_added; 7785a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7786c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Handle<Code> unoptimized_code(target_shared->code()); 778746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org ASSERT(unoptimized_code->kind() == Code::FUNCTION); 778846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Handle<TypeFeedbackInfo> type_info( 7789fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); 779046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org graph()->update_type_change_checksum(type_info->own_type_change_checksum()); 779146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 7792ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org TraceInline(target, caller, NULL); 7793a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 77944d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org if (current_block() != NULL) { 7795471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org FunctionState* state = function_state(); 7796471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { 7797471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // Falling off the end of an inlined construct call. In a test context the 7798471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // return value will always evaluate to true, in a value context the 7799471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // return value is the newly allocated receiver. 7800471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (call_context()->IsTest()) { 780171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(inlined_test_context()->if_true(), state); 7802471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else if (call_context()->IsEffect()) { 780371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(function_return(), state); 7804471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 7805471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ASSERT(call_context()->IsValue()); 780671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org AddLeaveInlined(implicit_return_value, state); 7807471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 7808471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else if (state->inlining_kind() == SETTER_CALL_RETURN) { 7809471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // Falling off the end of an inlined setter call. The returned value is 7810471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // never used, the value of an assignment is always the value of the RHS 7811471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // of the assignment. 7812471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (call_context()->IsTest()) { 7813471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org inlined_test_context()->ReturnValue(implicit_return_value); 7814471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else if (call_context()->IsEffect()) { 781571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(function_return(), state); 7816471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 7817471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ASSERT(call_context()->IsValue()); 781871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org AddLeaveInlined(implicit_return_value, state); 7819471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 7820a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 7821471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // Falling off the end of a normal inlined function. This basically means 7822471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // returning undefined. 7823471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (call_context()->IsTest()) { 782471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(inlined_test_context()->if_false(), state); 7825471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else if (call_context()->IsEffect()) { 782671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(function_return(), state); 7827471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else { 7828471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ASSERT(call_context()->IsValue()); 782971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org AddLeaveInlined(undefined, state); 7830471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 7831a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 7832a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 7833a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7834a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Fix up the function exits. 78358f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org if (inlined_test_context() != NULL) { 78368f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* if_true = inlined_test_context()->if_true(); 78378f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org HBasicBlock* if_false = inlined_test_context()->if_false(); 7838e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 7839d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org HEnterInlined* entry = function_state()->entry(); 7840d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 78418f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // Pop the return test context from the expression context stack. 7842e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org ASSERT(ast_context() == inlined_test_context()); 78438f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org ClearInlinedTestContext(); 7844394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com delete target_state; 7845a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 78465f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Forward to the real test context. 7847e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (if_true->HasPredecessor()) { 7848d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org entry->RegisterReturnTarget(if_true, zone()); 7849967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org if_true->SetJoinId(ast_id); 7850e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org HBasicBlock* true_target = TestContext::cast(ast_context())->if_true(); 785171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(if_true, true_target, function_state()); 7852e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 7853e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (if_false->HasPredecessor()) { 7854d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org entry->RegisterReturnTarget(if_false, zone()); 7855967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org if_false->SetJoinId(ast_id); 7856e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org HBasicBlock* false_target = TestContext::cast(ast_context())->if_false(); 785771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org Goto(if_false, false_target, function_state()); 7858e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 78593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org set_current_block(NULL); 7860394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return true; 7861a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7862160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else if (function_return()->HasPredecessor()) { 7863d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org function_state()->entry()->RegisterReturnTarget(function_return(), zone()); 7864967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org function_return()->SetJoinId(ast_id); 78658f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org set_current_block(function_return()); 7866160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else { 7867160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org set_current_block(NULL); 7868a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 7869394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com delete target_state; 7870a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return true; 7871a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 7872a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7873a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 7874a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.orgbool HOptimizedGraphBuilder::TryInlineCall(Call* expr) { 7875e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org return TryInline(expr->target(), 7876304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org expr->arguments()->length(), 7877967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org NULL, 7878967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org expr->id(), 7879967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org expr->ReturnId(), 7880f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org NORMAL_RETURN, 7881f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ScriptPositionToSourcePosition(expr->position())); 7882967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org} 7883967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 7884967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 7885a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgbool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, 7886a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* implicit_return_value) { 7887e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org return TryInline(expr->target(), 7888304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org expr->arguments()->length(), 7889471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org implicit_return_value, 7890967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org expr->id(), 7891967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org expr->ReturnId(), 7892f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CONSTRUCT_CALL_RETURN, 7893f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ScriptPositionToSourcePosition(expr->position())); 7894967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org} 7895967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 7896967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 7897a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgbool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, 78988297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org Handle<Map> receiver_map, 78993d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org BailoutId ast_id, 79003d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org BailoutId return_id) { 79018297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true; 7902e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org return TryInline(getter, 7903ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org 0, 7904ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org NULL, 79053d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org ast_id, 79063d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org return_id, 7907f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org GETTER_CALL_RETURN, 7908f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org source_position()); 7909ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org} 7910ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org 7911ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org 7912a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgbool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, 791325530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org Handle<Map> receiver_map, 7914b0deb658b04208a80c51265c6499f9eb564f1db3danno@chromium.org BailoutId id, 7915b0deb658b04208a80c51265c6499f9eb564f1db3danno@chromium.org BailoutId assignment_id, 7916a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* implicit_return_value) { 791725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org if (TryInlineApiSetter(setter, receiver_map, id)) return true; 7918e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org return TryInline(setter, 7919471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 1, 7920471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org implicit_return_value, 7921b0deb658b04208a80c51265c6499f9eb564f1db3danno@chromium.org id, assignment_id, 7922f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SETTER_CALL_RETURN, 7923f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org source_position()); 7924471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org} 7925471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 7926471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 79273ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgbool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function, 79283ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Call* expr, 79293ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org int arguments_count) { 7930e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org return TryInline(function, 79316ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org arguments_count, 79326ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org NULL, 79336ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org expr->id(), 79346ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org expr->ReturnId(), 7935f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org NORMAL_RETURN, 7936f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ScriptPositionToSourcePosition(expr->position())); 79376ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org} 79386ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org 79396ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org 7940a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.orgbool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr) { 794178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; 794278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); 794378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org switch (id) { 79441f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org case kMathExp: 79451f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org if (!FLAG_fast_math) break; 79461f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org // Fall through if FLAG_fast_math. 794778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org case kMathRound: 79482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org case kMathFloor: 794978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org case kMathAbs: 795078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org case kMathSqrt: 795178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org case kMathLog: 7952f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case kMathClz32: 795378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (expr->arguments()->length() == 1) { 795478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org HValue* argument = Pop(); 7955a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Drop(2); // Receiver and function. 7956db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id); 795778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org ast_context()->ReturnInstruction(op, expr->id()); 795878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org return true; 795978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 796078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org break; 7961ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org case kMathImul: 7962ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if (expr->arguments()->length() == 2) { 7963ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org HValue* right = Pop(); 7964ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org HValue* left = Pop(); 7965a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Drop(2); // Receiver and function. 7966db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HInstruction* op = HMul::NewImul(zone(), context(), left, right); 7967ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org ast_context()->ReturnInstruction(op, expr->id()); 7968ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org return true; 7969ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 7970ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org break; 797178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org default: 797278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Not supported for inlining yet. 797378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org break; 797478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 797578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org return false; 797678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org} 797778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 797878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 7979a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgbool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( 7980a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Call* expr, 79813ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org HValue* receiver, 79823ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Handle<Map> receiver_map) { 7983a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Try to inline calls like Math.* as operations in the calling function. 79843ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; 79853ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); 79863ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org int argument_count = expr->arguments()->length() + 1; // Plus receiver. 7987a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org switch (id) { 79880a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org case kStringCharCodeAt: 7989b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org case kStringCharAt: 7990a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (argument_count == 2) { 79910a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org HValue* index = Pop(); 79920a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org HValue* string = Pop(); 7993a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Drop(1); // Function. 79942e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org HInstruction* char_code = 7995d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org BuildStringCharCodeAt(string, index); 7996b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org if (id == kStringCharCodeAt) { 7997b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org ast_context()->ReturnInstruction(char_code, expr->id()); 7998b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org return true; 7999b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org } 8000b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org AddInstruction(char_code); 8001db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HInstruction* result = NewUncasted<HStringCharFromCode>(char_code); 80020a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org ast_context()->ReturnInstruction(result, expr->id()); 80030a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return true; 80040a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 80050a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org break; 8006b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org case kStringFromCharCode: 8007a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (argument_count == 2) { 8008b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org HValue* argument = Pop(); 8009a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Drop(2); // Receiver and function. 8010db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HInstruction* result = NewUncasted<HStringCharFromCode>(argument); 8011b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org ast_context()->ReturnInstruction(result, expr->id()); 8012b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org return true; 8013b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org } 8014b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org break; 80151f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org case kMathExp: 80161f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org if (!FLAG_fast_math) break; 80171f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org // Fall through if FLAG_fast_math. 8018a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case kMathRound: 8019a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case kMathFloor: 8020a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case kMathAbs: 8021a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case kMathSqrt: 80225f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org case kMathLog: 8023f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case kMathClz32: 8024a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (argument_count == 2) { 8025a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* argument = Pop(); 8026a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Drop(2); // Receiver and function. 8027db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id); 80285f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org ast_context()->ReturnInstruction(op, expr->id()); 80295f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org return true; 80305f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 80315f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org break; 80325f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org case kMathPow: 8033a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (argument_count == 3) { 80345f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org HValue* right = Pop(); 80355f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org HValue* left = Pop(); 8036a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Drop(2); // Receiver and function. 80375f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org HInstruction* result = NULL; 80385f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Use sqrt() if exponent is 0.5 or -0.5. 80395f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { 80405f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org double exponent = HConstant::cast(right)->DoubleValue(); 80415f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org if (exponent == 0.5) { 8042db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org result = NewUncasted<HUnaryMathOperation>(left, kMathPowHalf); 80435f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else if (exponent == -0.5) { 8044b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org HValue* one = graph()->GetConstant1(); 8045db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HInstruction* sqrt = AddUncasted<HUnaryMathOperation>( 8046db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org left, kMathPowHalf); 80475f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // MathPowHalf doesn't have side effects so there's no need for 80485f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // an environment simulation here. 80492e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org ASSERT(!sqrt->HasObservableSideEffects()); 8050db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org result = NewUncasted<HDiv>(one, sqrt); 80515f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else if (exponent == 2.0) { 8052db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org result = NewUncasted<HMul>(left, left); 80535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 80545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 80555f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 80560a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (result == NULL) { 8057db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org result = NewUncasted<HPower>(left, right); 80580a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 80595f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org ast_context()->ReturnInstruction(result, expr->id()); 8060a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return true; 8061a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 8062a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 8063f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com case kMathMax: 8064f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com case kMathMin: 8065a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (argument_count == 3) { 8066f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com HValue* right = Pop(); 8067f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com HValue* left = Pop(); 8068a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Drop(2); // Receiver and function. 8069471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin 8070471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org : HMathMinMax::kMathMax; 8071db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HInstruction* result = NewUncasted<HMathMinMax>(left, right, op); 8072471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ast_context()->ReturnInstruction(result, expr->id()); 8073f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com return true; 8074f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com } 8075f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com break; 8076ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org case kMathImul: 8077a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (argument_count == 3) { 8078ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org HValue* right = Pop(); 8079ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org HValue* left = Pop(); 8080a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Drop(2); // Receiver and function. 8081db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HInstruction* result = HMul::NewImul(zone(), context(), left, right); 8082ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org ast_context()->ReturnInstruction(result, expr->id()); 8083ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org return true; 8084ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 8085ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org break; 8086af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case kArrayPop: { 8087a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (receiver_map.is_null()) return false; 8088af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; 8089af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org ElementsKind elements_kind = receiver_map->elements_kind(); 8090af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org if (!IsFastElementsKind(elements_kind)) return false; 80918496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org if (receiver_map->is_observed()) return false; 80928496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org ASSERT(receiver_map->is_extensible()); 8093af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org 80943ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Drop(expr->arguments()->length()); 8095af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org HValue* result; 8096af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org HValue* reduced_length; 8097af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org HValue* receiver = Pop(); 809809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 809909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* checked_object = AddCheckMap(receiver, receiver_map); 810009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* length = Add<HLoadNamedField>( 810109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org checked_object, static_cast<HValue*>(NULL), 810209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HObjectAccess::ForArrayLength(elements_kind)); 810309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 8104a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Drop(1); // Function. 8105a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 8106af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org { NoObservableSideEffectsScope scope(this); 810709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org IfBuilder length_checker(this); 810809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 810909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* bounds_check = length_checker.If<HCompareNumericAndBranch>( 811009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org length, graph()->GetConstant0(), Token::EQ); 811109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org length_checker.Then(); 811209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 811309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org if (!ast_context()->IsEffect()) Push(graph()->GetConstantUndefined()); 811409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 811509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org length_checker.Else(); 8116af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org HValue* elements = AddLoadElements(checked_object); 8117af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org // Ensure that we aren't popping from a copy-on-write array. 8118af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org if (IsFastSmiOrObjectElementsKind(elements_kind)) { 811909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org elements = BuildCopyElementsOnWrite(checked_object, elements, 812009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org elements_kind, length); 8121af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org } 8122af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org reduced_length = AddUncasted<HSub>(length, graph()->GetConstant1()); 8123af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org result = AddElementAccess(elements, reduced_length, NULL, 8124f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bounds_check, elements_kind, LOAD); 8125af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org Factory* factory = isolate()->factory(); 8126af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org double nan_double = FixedDoubleArray::hole_nan_as_double(); 8127af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) 8128af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org ? Add<HConstant>(factory->the_hole_value()) 8129af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org : Add<HConstant>(nan_double); 8130af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org if (IsFastSmiOrObjectElementsKind(elements_kind)) { 8131af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org elements_kind = FAST_HOLEY_ELEMENTS; 8132af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org } 8133af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org AddElementAccess( 8134f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org elements, reduced_length, hole, bounds_check, elements_kind, STORE); 813509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org Add<HStoreNamedField>( 813609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org checked_object, HObjectAccess::ForArrayLength(elements_kind), 813709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org reduced_length, STORE_TO_INITIALIZED_ENTRY); 813809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 813909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org if (!ast_context()->IsEffect()) Push(result); 814009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 814109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org length_checker.End(); 8142af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org } 814309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); 8144af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 8145af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org if (!ast_context()->IsEffect()) Drop(1); 814609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 8147af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org ast_context()->ReturnValue(result); 8148af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org return true; 8149af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org } 8150af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org case kArrayPush: { 8151a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (receiver_map.is_null()) return false; 8152af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; 8153af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org ElementsKind elements_kind = receiver_map->elements_kind(); 8154af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org if (!IsFastElementsKind(elements_kind)) return false; 81558496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org if (receiver_map->is_observed()) return false; 8156fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org if (JSArray::IsReadOnlyLengthDescriptor(receiver_map)) return false; 81578496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org ASSERT(receiver_map->is_extensible()); 8158af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org 8159202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org // If there may be elements accessors in the prototype chain, the fast 8160202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org // inlined version can't be used. 8161202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; 8162202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org // If there currently can be no elements accessors on the prototype chain, 8163202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org // it doesn't mean that there won't be any later. Install a full prototype 8164202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org // chain check to trap element accessors being installed on the prototype 8165202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org // chain, which would cause elements to go to dictionary mode and result 8166202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org // in a map change. 8167202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); 8168202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org BuildCheckPrototypeMaps(prototype, Handle<JSObject>()); 8169202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org 81703ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org const int argc = expr->arguments()->length(); 81718496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org if (argc != 1) return false; 8172af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org 81738496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org HValue* value_to_push = Pop(); 81748496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org HValue* array = Pop(); 8175b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org Drop(1); // Drop function. 8176af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org 8177a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org HInstruction* new_size = NULL; 8178a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org HValue* length = NULL; 8179af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org 81808496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org { 81818496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org NoObservableSideEffectsScope scope(this); 81828496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org 8183a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org length = Add<HLoadNamedField>(array, static_cast<HValue*>(NULL), 8184a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org HObjectAccess::ForArrayLength(elements_kind)); 8185a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org 8186a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org new_size = AddUncasted<HAdd>(length, graph()->GetConstant1()); 8187a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org 81888496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org bool is_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 81898496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org BuildUncheckedMonomorphicElementAccess(array, length, 81908496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org value_to_push, is_array, 81918496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org elements_kind, STORE, 81928496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org NEVER_RETURN_HOLE, 81938496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org STORE_AND_GROW_NO_TRANSITION); 8194b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org 8195b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org if (!ast_context()->IsEffect()) Push(new_size); 8196a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 8197b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org if (!ast_context()->IsEffect()) Drop(1); 81988496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org } 8199af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org 8200a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org ast_context()->ReturnValue(new_size); 8201af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org return true; 8202af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org } 82033c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org case kArrayShift: { 82043c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org if (receiver_map.is_null()) return false; 82053c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; 82063c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org ElementsKind kind = receiver_map->elements_kind(); 82073c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org if (!IsFastElementsKind(kind)) return false; 82083c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org if (receiver_map->is_observed()) return false; 82093c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org ASSERT(receiver_map->is_extensible()); 82103c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 82113c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // If there may be elements accessors in the prototype chain, the fast 82123c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // inlined version can't be used. 82133c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; 82143c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 82153c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // If there currently can be no elements accessors on the prototype chain, 82163c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // it doesn't mean that there won't be any later. Install a full prototype 82173c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // chain check to trap element accessors being installed on the prototype 82183c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // chain, which would cause elements to go to dictionary mode and result 82193c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // in a map change. 82203c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org BuildCheckPrototypeMaps( 82213c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org handle(JSObject::cast(receiver_map->prototype()), isolate()), 82223c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Handle<JSObject>::null()); 82233c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 82248d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org // Threshold for fast inlined Array.shift(). 82258d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org HConstant* inline_threshold = Add<HConstant>(static_cast<int32_t>(16)); 82268d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org 82273ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Drop(expr->arguments()->length()); 82283c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org HValue* receiver = Pop(); 82298d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org HValue* function = Pop(); 82308d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org HValue* result; 82318d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org 82328d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org { 82338d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org NoObservableSideEffectsScope scope(this); 82348d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org 82358d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org HValue* length = Add<HLoadNamedField>( 82368d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org receiver, static_cast<HValue*>(NULL), 82378d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org HObjectAccess::ForArrayLength(kind)); 82388d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org 82398d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org IfBuilder if_lengthiszero(this); 82408d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org HValue* lengthiszero = if_lengthiszero.If<HCompareNumericAndBranch>( 82418d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org length, graph()->GetConstant0(), Token::EQ); 82428d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org if_lengthiszero.Then(); 82438d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org { 82448d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org if (!ast_context()->IsEffect()) Push(graph()->GetConstantUndefined()); 82458d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org } 82468d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org if_lengthiszero.Else(); 82478d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org { 82488d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org HValue* elements = AddLoadElements(receiver); 82498d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org 82508d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org // Check if we can use the fast inlined Array.shift(). 82518d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org IfBuilder if_inline(this); 82528d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org if_inline.If<HCompareNumericAndBranch>( 82538d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org length, inline_threshold, Token::LTE); 82548d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org if (IsFastSmiOrObjectElementsKind(kind)) { 82558d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org // We cannot handle copy-on-write backing stores here. 82568d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org if_inline.AndIf<HCompareMap>( 82578d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org elements, isolate()->factory()->fixed_array_map()); 82588d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org } 82598d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org if_inline.Then(); 82608d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org { 82618d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org // Remember the result. 82628d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org if (!ast_context()->IsEffect()) { 82638d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Push(AddElementAccess(elements, graph()->GetConstant0(), NULL, 82648d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org lengthiszero, kind, LOAD)); 82658d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org } 82668d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org 82678d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org // Compute the new length. 82688d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org HValue* new_length = AddUncasted<HSub>( 82698d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org length, graph()->GetConstant1()); 82708d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org new_length->ClearFlag(HValue::kCanOverflow); 82713c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org 82728d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org // Copy the remaining elements. 82738d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); 82748d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org { 82758d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org HValue* new_key = loop.BeginBody( 82768d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org graph()->GetConstant0(), new_length, Token::LT); 82778d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org HValue* key = AddUncasted<HAdd>(new_key, graph()->GetConstant1()); 82788d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org key->ClearFlag(HValue::kCanOverflow); 82798d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org HValue* element = AddUncasted<HLoadKeyed>( 82808d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org elements, key, lengthiszero, kind, ALLOW_RETURN_HOLE); 82818d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org HStoreKeyed* store = Add<HStoreKeyed>( 82828d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org elements, new_key, element, kind); 82838d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org store->SetFlag(HValue::kAllowUndefinedAsNaN); 82848d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org } 82858d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org loop.EndBody(); 82868d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org 82878d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org // Put a hole at the end. 82888d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org HValue* hole = IsFastSmiOrObjectElementsKind(kind) 82898d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org ? Add<HConstant>(isolate()->factory()->the_hole_value()) 82908d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org : Add<HConstant>(FixedDoubleArray::hole_nan_as_double()); 82918d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org if (IsFastSmiOrObjectElementsKind(kind)) kind = FAST_HOLEY_ELEMENTS; 82928d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Add<HStoreKeyed>( 82938d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org elements, new_length, hole, kind, INITIALIZING_STORE); 82948d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org 82958d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org // Remember new length. 82968d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Add<HStoreNamedField>( 82978d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org receiver, HObjectAccess::ForArrayLength(kind), 82988d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org new_length, STORE_TO_INITIALIZED_ENTRY); 82998d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org } 83008d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org if_inline.Else(); 83018d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org { 83028d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Add<HPushArguments>(receiver); 83038d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org result = Add<HCallJSFunction>(function, 1, true); 83048d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org if (!ast_context()->IsEffect()) Push(result); 83058d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org } 83068d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org if_inline.End(); 83078d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org } 83088d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org if_lengthiszero.End(); 83098d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org } 83108d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); 83118d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 83128d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org if (!ast_context()->IsEffect()) Drop(1); 83138d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org ast_context()->ReturnValue(result); 83143c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org return true; 83153c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org } 8316196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org case kArrayIndexOf: 8317196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org case kArrayLastIndexOf: { 8318196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (receiver_map.is_null()) return false; 8319196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; 8320196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ElementsKind kind = receiver_map->elements_kind(); 8321196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (!IsFastElementsKind(kind)) return false; 8322196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (receiver_map->is_observed()) return false; 8323196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (argument_count != 2) return false; 8324196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ASSERT(receiver_map->is_extensible()); 8325196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 8326196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // If there may be elements accessors in the prototype chain, the fast 8327196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // inlined version can't be used. 8328196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; 8329196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 8330196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // If there currently can be no elements accessors on the prototype chain, 8331196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // it doesn't mean that there won't be any later. Install a full prototype 8332196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // chain check to trap element accessors being installed on the prototype 8333196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // chain, which would cause elements to go to dictionary mode and result 8334196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // in a map change. 8335196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org BuildCheckPrototypeMaps( 8336196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org handle(JSObject::cast(receiver_map->prototype()), isolate()), 8337196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Handle<JSObject>::null()); 8338196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 8339196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org HValue* search_element = Pop(); 8340196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org HValue* receiver = Pop(); 8341196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Drop(1); // Drop function. 8342196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 8343196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ArrayIndexOfMode mode = (id == kArrayIndexOf) 8344196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ? kFirstIndexOf : kLastIndexOf; 8345196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org HValue* index = BuildArrayIndexOf(receiver, search_element, kind, mode); 8346196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 8347196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (!ast_context()->IsEffect()) Push(index); 8348196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 8349196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (!ast_context()->IsEffect()) Drop(1); 8350196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ast_context()->ReturnValue(index); 8351196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org return true; 8352196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 8353a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org default: 83545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Not yet supported for inlining. 8355a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 8356a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 8357a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return false; 8358a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 8359a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 8360a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 836157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.orgbool HOptimizedGraphBuilder::TryInlineApiFunctionCall(Call* expr, 8362a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org HValue* receiver) { 83638297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org Handle<JSFunction> function = expr->target(); 83648297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org int argc = expr->arguments()->length(); 83658297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org SmallMapList receiver_maps; 83668297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org return TryInlineApiCall(function, 83678297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org receiver, 83688297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org &receiver_maps, 83698297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org argc, 83708297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org expr->id(), 83718297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org kCallApiFunction); 837257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org} 837357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 837457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 83758297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.orgbool HOptimizedGraphBuilder::TryInlineApiMethodCall( 83768297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org Call* expr, 83778297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org HValue* receiver, 83788297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org SmallMapList* receiver_maps) { 83798297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org Handle<JSFunction> function = expr->target(); 83808297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org int argc = expr->arguments()->length(); 83818297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org return TryInlineApiCall(function, 83828297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org receiver, 83838297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org receiver_maps, 83848297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org argc, 83858297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org expr->id(), 83868297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org kCallApiMethod); 83878297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org} 83888297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org 83898297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org 83908297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.orgbool HOptimizedGraphBuilder::TryInlineApiGetter(Handle<JSFunction> function, 83918297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org Handle<Map> receiver_map, 83928297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org BailoutId ast_id) { 83938297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org SmallMapList receiver_maps(1, zone()); 83948297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org receiver_maps.Add(receiver_map, zone()); 83958297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org return TryInlineApiCall(function, 83968297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org NULL, // Receiver is on expression stack. 83978297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org &receiver_maps, 83988297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org 0, 83998297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ast_id, 84008297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org kCallApiGetter); 84018297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org} 84028297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org 84038297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org 840425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.orgbool HOptimizedGraphBuilder::TryInlineApiSetter(Handle<JSFunction> function, 840525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org Handle<Map> receiver_map, 840625530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org BailoutId ast_id) { 840725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org SmallMapList receiver_maps(1, zone()); 840825530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org receiver_maps.Add(receiver_map, zone()); 840925530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org return TryInlineApiCall(function, 841025530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org NULL, // Receiver is on expression stack. 841125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org &receiver_maps, 841225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org 1, 841325530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org ast_id, 841425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org kCallApiSetter); 841525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org} 841625530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org 841725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org 84188297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.orgbool HOptimizedGraphBuilder::TryInlineApiCall(Handle<JSFunction> function, 84198297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org HValue* receiver, 84208297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org SmallMapList* receiver_maps, 84218297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org int argc, 84228297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org BailoutId ast_id, 84238297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ApiCallType call_type) { 84248297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org CallOptimization optimization(function); 842557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (!optimization.is_simple_api_call()) return false; 842657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Handle<Map> holder_map; 84278297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (call_type == kCallApiFunction) { 842857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // Cannot embed a direct reference to the global proxy map 842957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // as it maybe dropped on deserialization. 8430fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org CHECK(!isolate()->serializer_enabled()); 84318297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ASSERT_EQ(0, receiver_maps->length()); 84328297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org receiver_maps->Add(handle( 84338297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org function->context()->global_object()->global_receiver()->map()), 84348297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org zone()); 843557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } 843657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org CallOptimization::HolderLookup holder_lookup = 843757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org CallOptimization::kHolderNotFound; 843857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType( 84398297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org receiver_maps->first(), &holder_lookup); 844057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (holder_lookup == CallOptimization::kHolderNotFound) return false; 844157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 844257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org if (FLAG_trace_inlining) { 844357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org PrintF("Inlining api function "); 84448297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org function->ShortPrint(); 844557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org PrintF("\n"); 844657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } 844757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 84488297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org bool drop_extra = false; 8449f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool is_store = false; 84508297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org switch (call_type) { 84518297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org case kCallApiFunction: 84528297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org case kCallApiMethod: 84538297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org // Need to check that none of the receiver maps could have changed. 8454052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org Add<HCheckMaps>(receiver, receiver_maps); 84558297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org // Need to ensure the chain between receiver and api_holder is intact. 84568297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (holder_lookup == CallOptimization::kHolderFound) { 84578297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org AddCheckPrototypeMaps(api_holder, receiver_maps->first()); 84588297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org } else { 84598297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ASSERT_EQ(holder_lookup, CallOptimization::kHolderIsReceiver); 84608297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org } 84618297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org // Includes receiver. 84628297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org PushArgumentsFromEnvironment(argc + 1); 84638297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org // Drop function after call. 84648297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org drop_extra = true; 84658297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org break; 84668297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org case kCallApiGetter: 84678297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org // Receiver and prototype chain cannot have changed. 84688297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ASSERT_EQ(0, argc); 84698297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ASSERT_EQ(NULL, receiver); 84708297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org // Receiver is on expression stack. 84718297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org receiver = Pop(); 84728d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Add<HPushArguments>(receiver); 84738297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org break; 847425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org case kCallApiSetter: 847525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org { 8476f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org is_store = true; 847725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org // Receiver and prototype chain cannot have changed. 847825530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org ASSERT_EQ(1, argc); 847925530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org ASSERT_EQ(NULL, receiver); 848025530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org // Receiver and value are on expression stack. 848125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org HValue* value = Pop(); 848225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org receiver = Pop(); 84838d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Add<HPushArguments>(receiver, value); 848425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org break; 848525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org } 848657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } 848757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 848857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HValue* holder = NULL; 848957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org switch (holder_lookup) { 849057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org case CallOptimization::kHolderFound: 849157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org holder = Add<HConstant>(api_holder); 849257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org break; 849357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org case CallOptimization::kHolderIsReceiver: 8494a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org holder = receiver; 849557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org break; 849657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org case CallOptimization::kHolderNotFound: 849757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org UNREACHABLE(); 849857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org break; 849957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org } 850057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 850157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Handle<Object> call_data_obj(api_call_info->data(), isolate()); 850257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org bool call_data_is_undefined = call_data_obj->IsUndefined(); 850357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HValue* call_data = Add<HConstant>(call_data_obj); 850457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org ApiFunction fun(v8::ToCData<Address>(api_call_info->callback())); 850557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org ExternalReference ref = ExternalReference(&fun, 850657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org ExternalReference::DIRECT_API_CALL, 850757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org isolate()); 850857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HValue* api_function_address = Add<HConstant>(ExternalReference(ref)); 850957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 851057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HValue* op_vals[] = { 85118297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org Add<HConstant>(function), 851257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org call_data, 851357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org holder, 851457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org api_function_address, 851557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org context() 851657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org }; 851757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 851857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org CallInterfaceDescriptor* descriptor = 851957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org isolate()->call_descriptor(Isolate::ApiFunctionCall); 852057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 8521f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallApiFunctionStub stub(isolate(), is_store, call_data_is_undefined, argc); 8522f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org Handle<Code> code = stub.GetCode(); 852357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HConstant* code_value = Add<HConstant>(code); 852457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 852557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org ASSERT((sizeof(op_vals) / kPointerSize) == 852657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org descriptor->environment_length()); 852757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 852857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org HInstruction* call = New<HCallWithDescriptor>( 852957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org code_value, argc + 1, descriptor, 853057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Vector<HValue*>(op_vals, descriptor->environment_length())); 853157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 85328297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (drop_extra) Drop(1); // Drop function. 85338297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org ast_context()->ReturnInstruction(call, ast_id); 853457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org return true; 853557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org} 853657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 853757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 85383ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgbool HOptimizedGraphBuilder::TryCallApply(Call* expr) { 8539a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org ASSERT(expr->expression()->IsProperty()); 8540a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 8541a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (!expr->IsMonomorphic()) { 85424acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org return false; 85434acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 85444acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Handle<Map> function_map = expr->GetReceiverTypes()->first(); 85454acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org if (function_map->instance_type() != JS_FUNCTION_TYPE || 85463ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org !expr->target()->shared()->HasBuiltinFunctionId() || 85473ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org expr->target()->shared()->builtin_function_id() != kFunctionApply) { 85484acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org return false; 85494acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 8550a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 85513ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org if (current_info()->scope()->arguments() == NULL) return false; 855270ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org 85533ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org ZoneList<Expression*>* args = expr->arguments(); 85543ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org if (args->length() != 2) return false; 8555a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 85563ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org VariableProxy* arg_two = args->at(1)->AsVariableProxy(); 85573ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; 85583ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); 85593ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; 8560a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 85613ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org // Found pattern f.apply(receiver, arguments). 85623ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org CHECK_ALIVE_OR_RETURN(VisitForValue(args->at(0)), true); 8563a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org HValue* receiver = Pop(); // receiver 8564a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org HValue* function = Pop(); // f 8565a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Drop(1); // apply 85664ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org 8567dc9b14d0e5f039213f6644c9ec2ffab31ad27a5cjarin@chromium.org HValue* checked_function = AddCheckMap(function, function_map); 8568dc9b14d0e5f039213f6644c9ec2ffab31ad27a5cjarin@chromium.org 8569154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org if (function_state()->outer() == NULL) { 85701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* elements = Add<HArgumentsElements>(false); 85711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* length = Add<HArgumentsLength>(elements); 8572dc9b14d0e5f039213f6644c9ec2ffab31ad27a5cjarin@chromium.org HValue* wrapped_receiver = BuildWrapReceiver(receiver, checked_function); 8573db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HInstruction* result = New<HApplyArguments>(function, 8574db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org wrapped_receiver, 8575db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org length, 8576db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org elements); 8577154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ast_context()->ReturnInstruction(result, expr->id()); 85783ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org return true; 8579154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org } else { 8580154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org // We are inside inlined function and we know exactly what is inside 858139110192b21bd92be3d617690fc33b4e9551b95dyangguo@chromium.org // arguments object. But we need to be able to materialize at deopt. 8582c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org ASSERT_EQ(environment()->arguments_environment()->parameter_count(), 8583b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org function_state()->entry()->arguments_object()->arguments_count()); 8584b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org HArgumentsObject* args = function_state()->entry()->arguments_object(); 8585b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org const ZoneList<HValue*>* arguments_values = args->arguments_values(); 8586c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org int arguments_count = arguments_values->length(); 8587a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Push(function); 8588dc9b14d0e5f039213f6644c9ec2ffab31ad27a5cjarin@chromium.org Push(BuildWrapReceiver(receiver, checked_function)); 8589c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org for (int i = 1; i < arguments_count; i++) { 8590c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org Push(arguments_values->at(i)); 85916ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org } 85926ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org 85933ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Handle<JSFunction> known_function; 85943ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org if (function->IsConstant() && 85953ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org HConstant::cast(function)->handle(isolate())->IsJSFunction()) { 85963ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org known_function = Handle<JSFunction>::cast( 85973ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org HConstant::cast(function)->handle(isolate())); 85983ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org int args_count = arguments_count - 1; // Excluding receiver. 85993ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org if (TryInlineApply(known_function, expr, args_count)) return true; 86003ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org } 86016ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org 86023ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org PushArgumentsFromEnvironment(arguments_count); 86033ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org HInvokeFunction* call = New<HInvokeFunction>( 86043ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org function, known_function, arguments_count); 86053ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Drop(1); // Function. 86063ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org ast_context()->ReturnInstruction(call, expr->id()); 86073ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org return true; 8608154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org } 8609a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 8610a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 8611a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 8612e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.orgHValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function, 8613e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org Handle<JSFunction> target) { 8614e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org SharedFunctionInfo* shared = target->shared(); 8615486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (shared->strict_mode() == SLOPPY && !shared->native()) { 861657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // Cannot embed a direct reference to the global proxy 861757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // as is it dropped on deserialization. 8618fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org CHECK(!isolate()->serializer_enabled()); 861957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Handle<JSObject> global_receiver( 862057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org target->context()->global_object()->global_receiver()); 862157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org return Add<HConstant>(global_receiver); 8622e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org } 8623e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org return graph()->GetConstantUndefined(); 86249ed27460593e67bc55b9feb15ca7c301e9f804b0rossberg@chromium.org} 86259ed27460593e67bc55b9feb15ca7c301e9f804b0rossberg@chromium.org 86269ed27460593e67bc55b9feb15ca7c301e9f804b0rossberg@chromium.org 86277e6132b924829c353864933f29124419916db550machenbach@chromium.orgvoid HOptimizedGraphBuilder::BuildArrayCall(Expression* expression, 86287e6132b924829c353864933f29124419916db550machenbach@chromium.org int arguments_count, 86297e6132b924829c353864933f29124419916db550machenbach@chromium.org HValue* function, 86307e6132b924829c353864933f29124419916db550machenbach@chromium.org Handle<AllocationSite> site) { 86317e6132b924829c353864933f29124419916db550machenbach@chromium.org Add<HCheckValue>(function, array_function()); 86327e6132b924829c353864933f29124419916db550machenbach@chromium.org 86337e6132b924829c353864933f29124419916db550machenbach@chromium.org if (IsCallArrayInlineable(arguments_count, site)) { 86347e6132b924829c353864933f29124419916db550machenbach@chromium.org BuildInlinedCallArray(expression, arguments_count, site); 86357e6132b924829c353864933f29124419916db550machenbach@chromium.org return; 86367e6132b924829c353864933f29124419916db550machenbach@chromium.org } 86377e6132b924829c353864933f29124419916db550machenbach@chromium.org 86387e6132b924829c353864933f29124419916db550machenbach@chromium.org HInstruction* call = PreProcessCall(New<HCallNewArray>( 86397e6132b924829c353864933f29124419916db550machenbach@chromium.org function, arguments_count + 1, site->GetElementsKind())); 86407e6132b924829c353864933f29124419916db550machenbach@chromium.org if (expression->IsCall()) { 86417e6132b924829c353864933f29124419916db550machenbach@chromium.org Drop(1); 86427e6132b924829c353864933f29124419916db550machenbach@chromium.org } 86437e6132b924829c353864933f29124419916db550machenbach@chromium.org ast_context()->ReturnInstruction(call, expression->id()); 86447e6132b924829c353864933f29124419916db550machenbach@chromium.org} 86457e6132b924829c353864933f29124419916db550machenbach@chromium.org 86467e6132b924829c353864933f29124419916db550machenbach@chromium.org 8647196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgHValue* HOptimizedGraphBuilder::BuildArrayIndexOf(HValue* receiver, 8648196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org HValue* search_element, 8649196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ElementsKind kind, 8650196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ArrayIndexOfMode mode) { 8651196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ASSERT(IsFastElementsKind(kind)); 8652196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 8653196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org NoObservableSideEffectsScope no_effects(this); 8654196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 8655196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org HValue* elements = AddLoadElements(receiver); 8656196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org HValue* length = AddLoadArrayLength(receiver, kind); 8657196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 8658196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org HValue* initial; 8659196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org HValue* terminating; 8660196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Token::Value token; 8661196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org LoopBuilder::Direction direction; 8662196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (mode == kFirstIndexOf) { 8663196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org initial = graph()->GetConstant0(); 8664196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org terminating = length; 8665196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org token = Token::LT; 8666196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org direction = LoopBuilder::kPostIncrement; 8667196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } else { 8668196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ASSERT_EQ(kLastIndexOf, mode); 8669196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org initial = length; 8670196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org terminating = graph()->GetConstant0(); 867138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org token = Token::GT; 8672196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org direction = LoopBuilder::kPreDecrement; 8673196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 8674196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 8675196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Push(graph()->GetConstantMinus1()); 8676196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (IsFastDoubleElementsKind(kind) || IsFastSmiElementsKind(kind)) { 8677196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org LoopBuilder loop(this, context(), direction); 8678196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org { 8679196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org HValue* index = loop.BeginBody(initial, terminating, token); 8680196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org HValue* element = AddUncasted<HLoadKeyed>( 8681196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org elements, index, static_cast<HValue*>(NULL), 8682196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org kind, ALLOW_RETURN_HOLE); 8683196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org IfBuilder if_issame(this); 8684196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (IsFastDoubleElementsKind(kind)) { 8685196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if_issame.If<HCompareNumericAndBranch>( 8686196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org element, search_element, Token::EQ_STRICT); 8687196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } else { 8688196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if_issame.If<HCompareObjectEqAndBranch>(element, search_element); 8689196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 8690196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if_issame.Then(); 8691196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org { 8692196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Drop(1); 8693196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Push(index); 8694196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org loop.Break(); 8695196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 8696196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if_issame.End(); 8697196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 8698196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org loop.EndBody(); 8699196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } else { 8700196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org IfBuilder if_isstring(this); 8701196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if_isstring.If<HIsStringAndBranch>(search_element); 8702196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if_isstring.Then(); 8703196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org { 8704196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org LoopBuilder loop(this, context(), direction); 8705196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org { 8706196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org HValue* index = loop.BeginBody(initial, terminating, token); 8707196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org HValue* element = AddUncasted<HLoadKeyed>( 8708196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org elements, index, static_cast<HValue*>(NULL), 8709196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org kind, ALLOW_RETURN_HOLE); 8710196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org IfBuilder if_issame(this); 8711196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if_issame.If<HIsStringAndBranch>(element); 8712196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if_issame.AndIf<HStringCompareAndBranch>( 8713196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org element, search_element, Token::EQ_STRICT); 8714196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if_issame.Then(); 8715196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org { 8716196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Drop(1); 8717196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Push(index); 8718196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org loop.Break(); 8719196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 8720196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if_issame.End(); 8721196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 8722196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org loop.EndBody(); 8723196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 8724196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if_isstring.Else(); 8725196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org { 8726e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org IfBuilder if_isnumber(this); 8727e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if_isnumber.If<HIsSmiAndBranch>(search_element); 8728e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if_isnumber.OrIf<HCompareMap>( 8729196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org search_element, isolate()->factory()->heap_number_map()); 8730e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if_isnumber.Then(); 8731196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org { 8732e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org HValue* search_number = 8733e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org AddUncasted<HForceRepresentation>(search_element, 8734e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Representation::Double()); 8735196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org LoopBuilder loop(this, context(), direction); 8736196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org { 8737196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org HValue* index = loop.BeginBody(initial, terminating, token); 8738196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org HValue* element = AddUncasted<HLoadKeyed>( 8739196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org elements, index, static_cast<HValue*>(NULL), 8740196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org kind, ALLOW_RETURN_HOLE); 8741e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org 8742e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org IfBuilder if_element_isnumber(this); 8743e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if_element_isnumber.If<HIsSmiAndBranch>(element); 8744e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if_element_isnumber.OrIf<HCompareMap>( 8745196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org element, isolate()->factory()->heap_number_map()); 8746e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if_element_isnumber.Then(); 8747196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org { 8748e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org HValue* number = 8749e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org AddUncasted<HForceRepresentation>(element, 8750e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Representation::Double()); 8751e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org IfBuilder if_issame(this); 8752e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if_issame.If<HCompareNumericAndBranch>( 8753e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org number, search_number, Token::EQ_STRICT); 8754e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if_issame.Then(); 8755e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org { 8756e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Drop(1); 8757e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Push(index); 8758e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org loop.Break(); 8759e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 8760e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if_issame.End(); 8761196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 8762e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if_element_isnumber.End(); 8763196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 8764196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org loop.EndBody(); 8765196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 8766e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if_isnumber.Else(); 8767196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org { 8768196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org LoopBuilder loop(this, context(), direction); 8769196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org { 8770196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org HValue* index = loop.BeginBody(initial, terminating, token); 8771196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org HValue* element = AddUncasted<HLoadKeyed>( 8772196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org elements, index, static_cast<HValue*>(NULL), 8773196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org kind, ALLOW_RETURN_HOLE); 8774196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org IfBuilder if_issame(this); 8775196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if_issame.If<HCompareObjectEqAndBranch>( 8776196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org element, search_element); 8777196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if_issame.Then(); 8778196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org { 8779196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Drop(1); 8780196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Push(index); 8781196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org loop.Break(); 8782196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 8783196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if_issame.End(); 8784196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 8785196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org loop.EndBody(); 8786196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 8787e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if_isnumber.End(); 8788196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 8789196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if_isstring.End(); 8790196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 8791196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 8792196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org return Pop(); 8793196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org} 8794196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 8795196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 87967e6132b924829c353864933f29124419916db550machenbach@chromium.orgbool HOptimizedGraphBuilder::TryHandleArrayCall(Call* expr, HValue* function) { 87977e6132b924829c353864933f29124419916db550machenbach@chromium.org if (!array_function().is_identical_to(expr->target())) { 87987e6132b924829c353864933f29124419916db550machenbach@chromium.org return false; 87997e6132b924829c353864933f29124419916db550machenbach@chromium.org } 88007e6132b924829c353864933f29124419916db550machenbach@chromium.org 88017e6132b924829c353864933f29124419916db550machenbach@chromium.org Handle<AllocationSite> site = expr->allocation_site(); 88027e6132b924829c353864933f29124419916db550machenbach@chromium.org if (site.is_null()) return false; 88037e6132b924829c353864933f29124419916db550machenbach@chromium.org 88047e6132b924829c353864933f29124419916db550machenbach@chromium.org BuildArrayCall(expr, 88057e6132b924829c353864933f29124419916db550machenbach@chromium.org expr->arguments()->length(), 88067e6132b924829c353864933f29124419916db550machenbach@chromium.org function, 88077e6132b924829c353864933f29124419916db550machenbach@chromium.org site); 88087e6132b924829c353864933f29124419916db550machenbach@chromium.org return true; 88097e6132b924829c353864933f29124419916db550machenbach@chromium.org} 88107e6132b924829c353864933f29124419916db550machenbach@chromium.org 88117e6132b924829c353864933f29124419916db550machenbach@chromium.org 88127e6132b924829c353864933f29124419916db550machenbach@chromium.orgbool HOptimizedGraphBuilder::TryHandleArrayCallNew(CallNew* expr, 88137e6132b924829c353864933f29124419916db550machenbach@chromium.org HValue* function) { 88147e6132b924829c353864933f29124419916db550machenbach@chromium.org if (!array_function().is_identical_to(expr->target())) { 88157e6132b924829c353864933f29124419916db550machenbach@chromium.org return false; 88167e6132b924829c353864933f29124419916db550machenbach@chromium.org } 88177e6132b924829c353864933f29124419916db550machenbach@chromium.org 88187e6132b924829c353864933f29124419916db550machenbach@chromium.org BuildArrayCall(expr, 88197e6132b924829c353864933f29124419916db550machenbach@chromium.org expr->arguments()->length(), 88207e6132b924829c353864933f29124419916db550machenbach@chromium.org function, 88217e6132b924829c353864933f29124419916db550machenbach@chromium.org expr->allocation_site()); 88227e6132b924829c353864933f29124419916db550machenbach@chromium.org return true; 88237e6132b924829c353864933f29124419916db550machenbach@chromium.org} 88247e6132b924829c353864933f29124419916db550machenbach@chromium.org 88257e6132b924829c353864933f29124419916db550machenbach@chromium.org 8826a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitCall(Call* expr) { 8827160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 8828160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 8829160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 8830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Expression* callee = expr->expression(); 8831a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int argument_count = expr->arguments()->length() + 1; // Plus receiver. 88323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org HInstruction* call = NULL; 8833a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 8834a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Property* prop = callee->AsProperty(); 8835a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (prop != NULL) { 8836a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org CHECK_ALIVE(VisitForValue(prop->obj())); 8837a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org HValue* receiver = Top(); 8838ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 8839a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org SmallMapList* types; 88400a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org ComputeReceiverTypes(expr, receiver, &types, zone()); 8841ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 8842a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (prop->key()->IsPropertyName() && types->length() > 0) { 8843a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 88440a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org PropertyAccessInfo info(this, LOAD, ToType(types->first()), name); 88450a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (!info.CanAccessAsMonomorphic(types)) { 8846a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org HandlePolymorphicCallNamed(expr, receiver, types, name); 8847a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org return; 8848ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 8849a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 8850a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 8851a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org HValue* key = NULL; 8852a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (!prop->key()->IsPropertyName()) { 8853a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org CHECK_ALIVE(VisitForValue(prop->key())); 8854a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org key = Pop(); 8855a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org } 8856a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 8857a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org CHECK_ALIVE(PushLoad(prop, receiver, key)); 8858a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org HValue* function = Pop(); 8859a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 8860f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 8861f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 8862a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Push the function under the receiver. 8863a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org environment()->SetExpressionStackAt(0, function); 8864a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 8865a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Push(receiver); 8866fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 8867a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (function->IsConstant() && 8868a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org HConstant::cast(function)->handle(isolate())->IsJSFunction()) { 8869a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Handle<JSFunction> known_function = Handle<JSFunction>::cast( 8870a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org HConstant::cast(function)->handle(isolate())); 8871a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org expr->set_target(known_function); 8872a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 88733ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org if (TryCallApply(expr)) return; 8874a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org CHECK_ALIVE(VisitExpressions(expr->arguments())); 8875a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 8876a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>(); 88773ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org if (TryInlineBuiltinMethodCall(expr, receiver, map)) { 887878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (FLAG_trace_inlining) { 887978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org PrintF("Inlining builtin "); 8880a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org known_function->ShortPrint(); 888178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org PrintF("\n"); 888278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 8883a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return; 8884a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 88858297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org if (TryInlineApiMethodCall(expr, receiver, types)) return; 88865f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 8887a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Wrap the receiver if necessary. 88880a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org if (NeedsWrappingFor(ToType(types->first()), known_function)) { 8889a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Since HWrapReceiver currently cannot actually wrap numbers and 8890a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // strings, use the regular CallFunctionStub for method calls to wrap 8891a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // the receiver. 8892a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // TODO(verwaest): Support creation of value wrappers directly in 8893a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // HWrapReceiver. 8894a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org call = New<HCallFunction>( 8895a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org function, argument_count, WRAP_AND_CALL); 8896a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org } else if (TryInlineCall(expr)) { 8897a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org return; 88980a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } else { 8899a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org call = BuildCallConstantFunction(known_function, argument_count); 89000a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 8901a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 8902a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 8903a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org CHECK_ALIVE(VisitExpressions(expr->arguments())); 8904a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org CallFunctionFlags flags = receiver->type().IsJSObject() 8905a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; 8906a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org call = New<HCallFunction>(function, argument_count, flags); 8907a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 8908a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org PushArgumentsFromEnvironment(argument_count); 8909a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 8910a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 8911486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org VariableProxy* proxy = expr->expression()->AsVariableProxy(); 8912fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { 8913594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kPossibleDirectCallToEval); 891428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 891528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 8916bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // The function is on the stack in the unoptimized code during 8917bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // evaluation of the arguments. 8918bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org CHECK_ALIVE(VisitForValue(expr->expression())); 8919bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org HValue* function = Top(); 89207e6132b924829c353864933f29124419916db550machenbach@chromium.org if (expr->global_call()) { 8921486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Variable* var = proxy->var(); 89228f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org bool known_global_function = false; 8923a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // If there is a global property cell for the name at compile time and 8924a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // access check is not enabled we assume that the function will not change 8925a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // and generate optimized code for calling the function. 8926394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com LookupResult lookup(isolate()); 8927f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, LOAD); 8928c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (type == kUseCell && 892941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org !current_info()->global_object()->IsAccessCheckNeeded()) { 893041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<GlobalObject> global(current_info()->global_object()); 8931c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org known_global_function = expr->ComputeGlobalTarget(global, &lookup); 89328f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 8933a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (known_global_function) { 8934a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Add<HCheckValue>(function, expr->target()); 8935e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 8936a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Placeholder for the receiver. 8937a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Push(graph()->GetConstantUndefined()); 8938160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitExpressions(expr->arguments())); 8939a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 8940e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // Patch the global object on the stack by the expected receiver. 8941e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org HValue* receiver = ImplicitReceiverFor(function, expr->target()); 8942a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const int receiver_index = argument_count - 1; 8943e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org environment()->SetExpressionStackAt(receiver_index, receiver); 8944a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 8945a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (TryInlineBuiltinFunctionCall(expr)) { 894678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (FLAG_trace_inlining) { 894778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org PrintF("Inlining builtin "); 894878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org expr->target()->ShortPrint(); 894978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org PrintF("\n"); 895078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 895178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org return; 895278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 8953a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (TryInlineApiFunctionCall(expr, receiver)) return; 89547e6132b924829c353864933f29124419916db550machenbach@chromium.org if (TryHandleArrayCall(expr, function)) return; 8955967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org if (TryInlineCall(expr)) return; 89567028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 895757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org PushArgumentsFromEnvironment(argument_count); 8958a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org call = BuildCallConstantFunction(expr->target(), argument_count); 8959a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 8960bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org Push(graph()->GetConstantUndefined()); 8961bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org CHECK_ALIVE(VisitExpressions(expr->arguments())); 8962bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org PushArgumentsFromEnvironment(argument_count); 8963a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org call = New<HCallFunction>(function, argument_count); 8964a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 8965a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 8966c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else if (expr->IsMonomorphic()) { 89671f410f9a9c4fbd4270749af64b477df87b753158mstarzinger@chromium.org Add<HCheckValue>(function, expr->target()); 896878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 8969a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Push(graph()->GetConstantUndefined()); 8970e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org CHECK_ALIVE(VisitExpressions(expr->arguments())); 89719ed27460593e67bc55b9feb15ca7c301e9f804b0rossberg@chromium.org 8972a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org HValue* receiver = ImplicitReceiverFor(function, expr->target()); 8973a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org const int receiver_index = argument_count - 1; 8974a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org environment()->SetExpressionStackAt(receiver_index, receiver); 8975a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 8976a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (TryInlineBuiltinFunctionCall(expr)) { 897778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (FLAG_trace_inlining) { 897878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org PrintF("Inlining builtin "); 897978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org expr->target()->ShortPrint(); 898078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org PrintF("\n"); 898178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 898278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org return; 898378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 8984a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (TryInlineApiFunctionCall(expr, receiver)) return; 898578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 8986a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org if (TryInlineCall(expr)) return; 8987a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 8988a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org call = PreProcessCall(New<HInvokeFunction>( 8989a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org function, expr->target(), argument_count)); 8990c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 8991a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 8992bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org Push(graph()->GetConstantUndefined()); 8993bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org CHECK_ALIVE(VisitExpressions(expr->arguments())); 8994bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org PushArgumentsFromEnvironment(argument_count); 8995a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org call = New<HCallFunction>(function, argument_count); 8996a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 8997a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 8998a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 8999a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Drop(1); // Drop the function. 90004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(call, expr->id()); 9001a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 9002a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9003a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 90047e6132b924829c353864933f29124419916db550machenbach@chromium.orgvoid HOptimizedGraphBuilder::BuildInlinedCallArray( 90057e6132b924829c353864933f29124419916db550machenbach@chromium.org Expression* expression, 90067e6132b924829c353864933f29124419916db550machenbach@chromium.org int argument_count, 90077e6132b924829c353864933f29124419916db550machenbach@chromium.org Handle<AllocationSite> site) { 90087e6132b924829c353864933f29124419916db550machenbach@chromium.org ASSERT(!site.is_null()); 90097e6132b924829c353864933f29124419916db550machenbach@chromium.org ASSERT(argument_count >= 0 && argument_count <= 1); 9010b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org NoObservableSideEffectsScope no_effects(this); 9011b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 9012b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // We should at least have the constructor on the expression stack. 9013b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HValue* constructor = environment()->ExpressionStackAt(argument_count); 9014b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 901543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org // Register on the site for deoptimization if the transition feedback changes. 90164ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org AllocationSite::AddDependentCompilationInfo( 90174ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org site, AllocationSite::TRANSITIONS, top_info()); 90187e6132b924829c353864933f29124419916db550machenbach@chromium.org ElementsKind kind = site->GetElementsKind(); 901943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org HInstruction* site_instruction = Add<HConstant>(site); 9020b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 9021b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // In the single constant argument case, we may have to adjust elements kind 9022b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // to avoid creating a packed non-empty array. 9023b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (argument_count == 1 && !IsHoleyElementsKind(kind)) { 9024b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HValue* argument = environment()->Top(); 9025b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (argument->IsConstant()) { 9026b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HConstant* constant_argument = HConstant::cast(argument); 9027b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org ASSERT(constant_argument->HasSmiValue()); 9028b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org int constant_array_size = constant_argument->Integer32Value(); 9029b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (constant_array_size != 0) { 9030b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org kind = GetHoleyElementsKind(kind); 9031b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 9032b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 9033b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 9034b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 9035b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // Build the array. 9036b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org JSArrayBuilder array_builder(this, 9037b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org kind, 903843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org site_instruction, 9039b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org constructor, 9040b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org DISABLE_ALLOCATION_SITES); 90417e6132b924829c353864933f29124419916db550machenbach@chromium.org HValue* new_object = argument_count == 0 90427e6132b924829c353864933f29124419916db550machenbach@chromium.org ? array_builder.AllocateEmptyArray() 90437e6132b924829c353864933f29124419916db550machenbach@chromium.org : BuildAllocateArrayFromLength(&array_builder, Top()); 90447e6132b924829c353864933f29124419916db550machenbach@chromium.org 90457e6132b924829c353864933f29124419916db550machenbach@chromium.org int args_to_drop = argument_count + (expression->IsCall() ? 2 : 1); 90467e6132b924829c353864933f29124419916db550machenbach@chromium.org Drop(args_to_drop); 9047b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org ast_context()->ReturnValue(new_object); 9048b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org} 9049b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 9050b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 9051967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// Checks whether allocation using the given constructor can be inlined. 9052967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgstatic bool IsAllocationInlineable(Handle<JSFunction> constructor) { 9053967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org return constructor->has_initial_map() && 90547d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && 905510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org constructor->initial_map()->instance_size() < HAllocate::kMaxInlineSize && 905610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org constructor->initial_map()->InitialPropertiesLength() == 0; 9057967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org} 9058967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 9059967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 90607e6132b924829c353864933f29124419916db550machenbach@chromium.orgbool HOptimizedGraphBuilder::IsCallArrayInlineable( 90617e6132b924829c353864933f29124419916db550machenbach@chromium.org int argument_count, 90627e6132b924829c353864933f29124419916db550machenbach@chromium.org Handle<AllocationSite> site) { 9063b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<JSFunction> caller = current_info()->closure(); 90647e6132b924829c353864933f29124419916db550machenbach@chromium.org Handle<JSFunction> target = array_function(); 9065b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // We should have the function plus array arguments on the environment stack. 9066b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org ASSERT(environment()->length() >= (argument_count + 1)); 9067c8cbc43a1fd5fda5d6a1e172f720cbd1215157c8machenbach@chromium.org ASSERT(!site.is_null()); 9068c8cbc43a1fd5fda5d6a1e172f720cbd1215157c8machenbach@chromium.org 9069f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool inline_ok = false; 9070b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (site->CanInlineCall()) { 9071b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // We also want to avoid inlining in certain 1 argument scenarios. 9072b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (argument_count == 1) { 9073b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HValue* argument = Top(); 9074b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (argument->IsConstant()) { 9075b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // Do not inline if the constant length argument is not a smi or 90767e6132b924829c353864933f29124419916db550machenbach@chromium.org // outside the valid range for unrolled loop initialization. 9077b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HConstant* constant_argument = HConstant::cast(argument); 9078b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (constant_argument->HasSmiValue()) { 9079b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org int value = constant_argument->Integer32Value(); 90807e6132b924829c353864933f29124419916db550machenbach@chromium.org inline_ok = value >= 0 && value <= kElementLoopUnrollThreshold; 9081b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (!inline_ok) { 9082b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org TraceInline(target, caller, 90837e6132b924829c353864933f29124419916db550machenbach@chromium.org "Constant length outside of valid inlining range."); 9084b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 9085b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 9086b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } else { 90877e6132b924829c353864933f29124419916db550machenbach@chromium.org TraceInline(target, caller, 90887e6132b924829c353864933f29124419916db550machenbach@chromium.org "Dont inline [new] Array(n) where n isn't constant."); 9089b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 90907e6132b924829c353864933f29124419916db550machenbach@chromium.org } else if (argument_count == 0) { 9091ed50beee6c90dc00e0f746de915014f57eaeccbdmachenbach@chromium.org inline_ok = true; 90927e6132b924829c353864933f29124419916db550machenbach@chromium.org } else { 90937e6132b924829c353864933f29124419916db550machenbach@chromium.org TraceInline(target, caller, "Too many arguments to inline."); 9094b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 9095b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } else { 9096b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org TraceInline(target, caller, "AllocationSite requested no inlining."); 9097b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 9098b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 9099b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (inline_ok) { 9100b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org TraceInline(target, caller, NULL); 9101b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 9102b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org return inline_ok; 9103b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org} 9104b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 9105b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 9106a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { 9107160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 9108160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 9109160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 9110f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 9111967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org int argument_count = expr->arguments()->length() + 1; // Plus constructor. 911210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org Factory* factory = isolate()->factory(); 9113496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 9114b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // The constructor function is on the stack in the unoptimized code 9115b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // during evaluation of the arguments. 9116b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org CHECK_ALIVE(VisitForValue(expr->expression())); 9117b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HValue* function = Top(); 9118b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org CHECK_ALIVE(VisitExpressions(expr->arguments())); 9119b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 9120967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org if (FLAG_inline_construct && 9121967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org expr->IsMonomorphic() && 9122967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org IsAllocationInlineable(expr->target())) { 9123967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org Handle<JSFunction> constructor = expr->target(); 91241f410f9a9c4fbd4270749af64b477df87b753158mstarzinger@chromium.org HValue* check = Add<HCheckValue>(function, constructor); 912535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org 912635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // Force completion of inobject slack tracking before generating 912735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // allocation code to finalize instance size. 9128011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org if (constructor->IsInobjectSlackTrackingInProgress()) { 9129011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org constructor->CompleteInobjectSlackTracking(); 913035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org } 9131967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 913210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // Calculate instance size from initial map of constructor. 913310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org ASSERT(constructor->has_initial_map()); 913410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org Handle<Map> initial_map(constructor->initial_map()); 913510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org int instance_size = initial_map->instance_size(); 913610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org ASSERT(initial_map->InitialPropertiesLength() == 0); 913710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org 913810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // Allocate an instance of the implicit receiver object. 913910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org HValue* size_in_bytes = Add<HConstant>(instance_size); 914069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org HAllocationMode allocation_mode; 914169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org if (FLAG_pretenuring_call_new) { 914269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org if (FLAG_allocation_site_pretenuring) { 914369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // Try to use pretenuring feedback. 914469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org Handle<AllocationSite> allocation_site = expr->allocation_site(); 914569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org allocation_mode = HAllocationMode(allocation_site); 914669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // Take a dependency on allocation site. 914769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org AllocationSite::AddDependentCompilationInfo(allocation_site, 914869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org AllocationSite::TENURING, 914969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org top_info()); 915069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 915169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 915269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 9153011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org HAllocate* receiver = BuildAllocate( 9154011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode); 915510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org receiver->set_known_initial_map(initial_map); 915610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org 915710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // Initialize map and fields of the newly allocated object. 915810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org { NoObservableSideEffectsScope no_effects(this); 915910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE); 9160d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Add<HStoreNamedField>(receiver, 91610a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HObjectAccess::ForMapAndOffset(initial_map, JSObject::kMapOffset), 9162011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org Add<HConstant>(initial_map)); 916310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array()); 9164d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Add<HStoreNamedField>(receiver, 91650a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HObjectAccess::ForMapAndOffset(initial_map, 91660a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org JSObject::kPropertiesOffset), 91670a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org empty_fixed_array); 9168d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Add<HStoreNamedField>(receiver, 91690a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HObjectAccess::ForMapAndOffset(initial_map, 91700a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org JSObject::kElementsOffset), 91710a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org empty_fixed_array); 917210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org if (initial_map->inobject_properties() != 0) { 917310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org HConstant* undefined = graph()->GetConstantUndefined(); 917410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org for (int i = 0; i < initial_map->inobject_properties(); i++) { 91750a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org int property_offset = initial_map->GetInObjectPropertyOffset(i); 9176d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Add<HStoreNamedField>(receiver, 91770a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HObjectAccess::ForMapAndOffset(initial_map, property_offset), 91780a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org undefined); 917910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org } 918010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org } 918110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org } 918210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org 918310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // Replace the constructor function with a newly allocated receiver using 918410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // the index of the receiver from the top of the expression stack. 9185967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org const int receiver_index = argument_count - 1; 9186967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org ASSERT(environment()->ExpressionStackAt(receiver_index) == function); 9187967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org environment()->SetExpressionStackAt(receiver_index, receiver); 9188967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 9189011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org if (TryInlineConstruct(expr, receiver)) { 9190011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org // Inlining worked, add a dependency on the initial map to make sure that 9191011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org // this code is deoptimized whenever the initial map of the constructor 9192011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org // changes. 9193011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org Map::AddDependentCompilationInfo( 9194011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org initial_map, DependentCode::kInitialMapChangedGroup, top_info()); 9195011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org return; 9196011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org } 9197967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 919810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // TODO(mstarzinger): For now we remove the previous HAllocate and all 9199011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org // corresponding instructions and instead add HPushArguments for the 920010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // arguments in case inlining failed. What we actually should do is for 920110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // inlining to try to build a subgraph without mutating the parent graph. 920210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org HInstruction* instr = current_block()->last(); 9203011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org do { 920410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org HInstruction* prev_instr = instr->previous(); 920510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org instr->DeleteAndReplaceWith(NULL); 920610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org instr = prev_instr; 9207011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org } while (instr != check); 9208967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org environment()->SetExpressionStackAt(receiver_index, function); 92098e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org HInstruction* call = 92108e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org PreProcessCall(New<HCallNew>(function, argument_count)); 9211967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org return ast_context()->ReturnInstruction(call, expr->id()); 9212967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org } else { 9213967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org // The constructor function is both an operand to the instruction and an 9214967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org // argument to the construct call. 92157e6132b924829c353864933f29124419916db550machenbach@chromium.org if (TryHandleArrayCallNew(expr, function)) return; 9216b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 92177e6132b924829c353864933f29124419916db550machenbach@chromium.org HInstruction* call = 92187e6132b924829c353864933f29124419916db550machenbach@chromium.org PreProcessCall(New<HCallNew>(function, argument_count)); 9219967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org return ast_context()->ReturnInstruction(call, expr->id()); 9220967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org } 9221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 9222a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Support for generating inlined runtime functions. 9225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9226a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// Lookup table for generators for runtime calls that are generated inline. 9227a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// Elements of the table are member pointers to functions of 9228a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// HOptimizedGraphBuilder. 92295f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org#define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \ 9230a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org &HOptimizedGraphBuilder::Generate##Name, 9231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9232a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgconst HOptimizedGraphBuilder::InlineFunctionGenerator 9233a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HOptimizedGraphBuilder::kInlineFunctionGenerators[] = { 9234a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 92359b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org INLINE_OPTIMIZED_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 9236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}; 9237a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#undef INLINE_FUNCTION_GENERATOR_ADDRESS 9238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9239a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 924037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.orgtemplate <class ViewClass> 924137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.orgvoid HGraphBuilder::BuildArrayBufferViewInitialization( 924237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org HValue* obj, 924337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org HValue* buffer, 924437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org HValue* byte_offset, 924537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org HValue* byte_length) { 924637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 924737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org for (int offset = ViewClass::kSize; 924837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org offset < ViewClass::kSizeWithInternalFields; 924937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org offset += kPointerSize) { 925037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org Add<HStoreNamedField>(obj, 92510a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HObjectAccess::ForObservableJSObjectOffset(offset), 92520a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org graph()->GetConstant0()); 925337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org } 925437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 925537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org Add<HStoreNamedField>( 925637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org obj, 925737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org HObjectAccess::ForJSArrayBufferViewByteOffset(), 92580a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org byte_offset); 925937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org Add<HStoreNamedField>( 926037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org obj, 926137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org HObjectAccess::ForJSArrayBufferViewByteLength(), 92620a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org byte_length); 926337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 9264895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org if (buffer != NULL) { 9265895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Add<HStoreNamedField>( 9266895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org obj, 9267895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HObjectAccess::ForJSArrayBufferViewBuffer(), buffer); 9268895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HObjectAccess weak_first_view_access = 9269895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HObjectAccess::ForJSArrayBufferWeakFirstView(); 9270895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Add<HStoreNamedField>(obj, 9271895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HObjectAccess::ForJSArrayBufferViewWeakNext(), 9272895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Add<HLoadNamedField>(buffer, 9273895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org static_cast<HValue*>(NULL), 9274895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org weak_first_view_access)); 9275895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Add<HStoreNamedField>(buffer, weak_first_view_access, obj); 9276895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } else { 9277895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Add<HStoreNamedField>( 9278895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org obj, 9279895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HObjectAccess::ForJSArrayBufferViewBuffer(), 9280895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Add<HConstant>(static_cast<int32_t>(0))); 9281895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Add<HStoreNamedField>(obj, 9282895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HObjectAccess::ForJSArrayBufferViewWeakNext(), 9283895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org graph()->GetConstantUndefined()); 9284895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 928537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org} 928637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 928737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 9288a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateDataViewInitialize( 9289af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org CallRuntime* expr) { 9290af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org ZoneList<Expression*>* arguments = expr->arguments(); 9291af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 9292af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org ASSERT(arguments->length()== 4); 9293af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org CHECK_ALIVE(VisitForValue(arguments->at(0))); 9294af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org HValue* obj = Pop(); 9295af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 9296af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org CHECK_ALIVE(VisitForValue(arguments->at(1))); 9297af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org HValue* buffer = Pop(); 9298af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 9299af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org CHECK_ALIVE(VisitForValue(arguments->at(2))); 9300af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org HValue* byte_offset = Pop(); 9301af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 9302af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org CHECK_ALIVE(VisitForValue(arguments->at(3))); 9303af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org HValue* byte_length = Pop(); 9304af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 9305eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org { 9306eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org NoObservableSideEffectsScope scope(this); 9307eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org BuildArrayBufferViewInitialization<JSDataView>( 9308eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org obj, buffer, byte_offset, byte_length); 9309eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org } 931037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org} 931137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 931237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 9313895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgstatic Handle<Map> TypedArrayMap(Isolate* isolate, 9314895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org ExternalArrayType array_type, 9315895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org ElementsKind target_kind) { 9316895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Handle<Context> native_context = isolate->native_context(); 9317895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Handle<JSFunction> fun; 9318895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org switch (array_type) { 9319895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 9320895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org case kExternal##Type##Array: \ 9321895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org fun = Handle<JSFunction>(native_context->type##_array_fun()); \ 9322895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org break; 9323895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9324895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org TYPED_ARRAYS(TYPED_ARRAY_CASE) 9325895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org#undef TYPED_ARRAY_CASE 9326895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 9327895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Handle<Map> map(fun->initial_map()); 9328895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org return Map::AsElementsKind(map, target_kind); 9329895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org} 9330895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9331895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9332895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgHValue* HOptimizedGraphBuilder::BuildAllocateExternalElements( 9333895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org ExternalArrayType array_type, 9334895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org bool is_zero_byte_offset, 9335895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HValue* buffer, HValue* byte_offset, HValue* length) { 9336895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Handle<Map> external_array_map( 9337895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org isolate()->heap()->MapForExternalArrayType(array_type)); 93382f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 93392f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // The HForceRepresentation is to prevent possible deopt on int-smi 93402f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // conversion after allocation but before the new object fields are set. 93412f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org length = AddUncasted<HForceRepresentation>(length, Representation::Smi()); 9342895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HValue* elements = 9343895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Add<HAllocate>( 9344895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Add<HConstant>(ExternalArray::kAlignedSize), 9345eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org HType::HeapObject(), 9346895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org NOT_TENURED, 9347895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org external_array_map->instance_type()); 9348895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9349895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org AddStoreMapConstant(elements, external_array_map); 93502f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org Add<HStoreNamedField>(elements, 93512f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org HObjectAccess::ForFixedArrayLength(), length); 9352895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9353895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HValue* backing_store = Add<HLoadNamedField>( 9354895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org buffer, static_cast<HValue*>(NULL), 9355895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HObjectAccess::ForJSArrayBufferBackingStore()); 9356895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9357895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HValue* typed_array_start; 9358895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org if (is_zero_byte_offset) { 9359895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org typed_array_start = backing_store; 9360895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } else { 9361895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HInstruction* external_pointer = 9362895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org AddUncasted<HAdd>(backing_store, byte_offset); 9363895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org // Arguments are checked prior to call to TypedArrayInitialize, 9364895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org // including byte_offset. 9365895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org external_pointer->ClearFlag(HValue::kCanOverflow); 9366895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org typed_array_start = external_pointer; 9367895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 9368895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9369895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Add<HStoreNamedField>(elements, 9370895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HObjectAccess::ForExternalArrayExternalPointer(), 9371895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org typed_array_start); 9372895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9373895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org return elements; 9374895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org} 9375895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9376895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9377895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgHValue* HOptimizedGraphBuilder::BuildAllocateFixedTypedArray( 9378895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org ExternalArrayType array_type, size_t element_size, 9379895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org ElementsKind fixed_elements_kind, 9380895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HValue* byte_length, HValue* length) { 9381895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org STATIC_ASSERT( 9382895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org (FixedTypedArrayBase::kHeaderSize & kObjectAlignmentMask) == 0); 9383895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HValue* total_size; 9384895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9385895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org // if fixed array's elements are not aligned to object's alignment, 9386895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org // we need to align the whole array to object alignment. 9387895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org if (element_size % kObjectAlignment != 0) { 9388895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org total_size = BuildObjectSizeAlignment( 9389895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org byte_length, FixedTypedArrayBase::kHeaderSize); 9390895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } else { 9391895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org total_size = AddUncasted<HAdd>(byte_length, 9392895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Add<HConstant>(FixedTypedArrayBase::kHeaderSize)); 9393895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org total_size->ClearFlag(HValue::kCanOverflow); 9394895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 9395895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 93962f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // The HForceRepresentation is to prevent possible deopt on int-smi 93972f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // conversion after allocation but before the new object fields are set. 93982f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org length = AddUncasted<HForceRepresentation>(length, Representation::Smi()); 9399895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Handle<Map> fixed_typed_array_map( 9400895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org isolate()->heap()->MapForFixedTypedArray(array_type)); 9401895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HValue* elements = 9402eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org Add<HAllocate>(total_size, HType::HeapObject(), 94036a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org NOT_TENURED, fixed_typed_array_map->instance_type()); 9404895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org AddStoreMapConstant(elements, fixed_typed_array_map); 9405895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9406895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Add<HStoreNamedField>(elements, 9407895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HObjectAccess::ForFixedArrayLength(), 9408895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org length); 94092f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 9410895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HValue* filler = Add<HConstant>(static_cast<int32_t>(0)); 9411895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9412895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org { 9413895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement); 9414895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9415895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HValue* key = builder.BeginBody( 9416895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Add<HConstant>(static_cast<int32_t>(0)), 9417895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org length, Token::LT); 9418895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Add<HStoreKeyed>(elements, key, filler, fixed_elements_kind); 9419895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9420895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org builder.EndBody(); 9421895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 9422895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org return elements; 9423895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org} 9424895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9425895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9426a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateTypedArrayInitialize( 942737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org CallRuntime* expr) { 942837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org ZoneList<Expression*>* arguments = expr->arguments(); 942937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 943037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org static const int kObjectArg = 0; 943137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org static const int kArrayIdArg = 1; 943237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org static const int kBufferArg = 2; 943337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org static const int kByteOffsetArg = 3; 943437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org static const int kByteLengthArg = 4; 943537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org static const int kArgsLength = 5; 943637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org ASSERT(arguments->length() == kArgsLength); 943737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 943837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 943937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org CHECK_ALIVE(VisitForValue(arguments->at(kObjectArg))); 944037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org HValue* obj = Pop(); 944137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 9442196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (arguments->at(kArrayIdArg)->IsLiteral()) { 9443a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org // This should never happen in real use, but can happen when fuzzing. 9444a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org // Just bail out. 9445a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org Bailout(kNeedSmiLiteral); 9446a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org return; 9447a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org } 944837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org Handle<Object> value = 944937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org static_cast<Literal*>(arguments->at(kArrayIdArg))->value(); 9450a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org if (!value->IsSmi()) { 9451a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org // This should never happen in real use, but can happen when fuzzing. 9452a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org // Just bail out. 9453a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org Bailout(kNeedSmiLiteral); 9454a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org return; 9455a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org } 945637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org int array_id = Smi::cast(*value)->value(); 945737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 9458895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HValue* buffer; 9459895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org if (!arguments->at(kBufferArg)->IsNullLiteral()) { 9460895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org CHECK_ALIVE(VisitForValue(arguments->at(kBufferArg))); 9461895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org buffer = Pop(); 9462895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } else { 9463895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org buffer = NULL; 9464895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 946537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 946637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org HValue* byte_offset; 946737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org bool is_zero_byte_offset; 946837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 9469196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (arguments->at(kByteOffsetArg)->IsLiteral() 947037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org && Smi::FromInt(0) == 947137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org *static_cast<Literal*>(arguments->at(kByteOffsetArg))->value()) { 947237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org byte_offset = Add<HConstant>(static_cast<int32_t>(0)); 947337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org is_zero_byte_offset = true; 947437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org } else { 947537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org CHECK_ALIVE(VisitForValue(arguments->at(kByteOffsetArg))); 947637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org byte_offset = Pop(); 947737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org is_zero_byte_offset = false; 9478895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org ASSERT(buffer != NULL); 9479af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org } 9480af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 948137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org CHECK_ALIVE(VisitForValue(arguments->at(kByteLengthArg))); 948237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org HValue* byte_length = Pop(); 9483af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 9484eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org NoObservableSideEffectsScope scope(this); 948537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org IfBuilder byte_offset_smi(this); 948637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 948737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org if (!is_zero_byte_offset) { 948837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org byte_offset_smi.If<HIsSmiAndBranch>(byte_offset); 948937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org byte_offset_smi.Then(); 949037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org } 949137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 9492895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org ExternalArrayType array_type = 9493895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org kExternalInt8Array; // Bogus initialization. 9494895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org size_t element_size = 1; // Bogus initialization. 9495895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org ElementsKind external_elements_kind = // Bogus initialization. 9496895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org EXTERNAL_INT8_ELEMENTS; 9497895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org ElementsKind fixed_elements_kind = // Bogus initialization. 9498895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org INT8_ELEMENTS; 9499895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Runtime::ArrayIdToTypeAndSize(array_id, 9500895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org &array_type, 9501895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org &external_elements_kind, 9502895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org &fixed_elements_kind, 9503895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org &element_size); 9504895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9505895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 950637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org { // byte_offset is Smi. 950737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org BuildArrayBufferViewInitialization<JSTypedArray>( 950837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org obj, buffer, byte_offset, byte_length); 950937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 951037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 951137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org HInstruction* length = AddUncasted<HDiv>(byte_length, 951237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org Add<HConstant>(static_cast<int32_t>(element_size))); 951337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 951437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org Add<HStoreNamedField>(obj, 951537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org HObjectAccess::ForJSTypedArrayLength(), 95160a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org length); 95170a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 9518895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HValue* elements; 9519895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org if (buffer != NULL) { 9520895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org elements = BuildAllocateExternalElements( 9521895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org array_type, is_zero_byte_offset, buffer, byte_offset, length); 9522895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Handle<Map> obj_map = TypedArrayMap( 9523895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org isolate(), array_type, external_elements_kind); 9524895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org AddStoreMapConstant(obj, obj_map); 952537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org } else { 9526895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org ASSERT(is_zero_byte_offset); 9527895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org elements = BuildAllocateFixedTypedArray( 9528895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org array_type, element_size, fixed_elements_kind, 9529895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org byte_length, length); 9530895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org } 953137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org Add<HStoreNamedField>( 95320a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org obj, HObjectAccess::ForElementsPointer(), elements); 953337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org } 953437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 953537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org if (!is_zero_byte_offset) { 953637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org byte_offset_smi.Else(); 953737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org { // byte_offset is not Smi. 9538bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org Push(obj); 9539bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org CHECK_ALIVE(VisitForValue(arguments->at(kArrayIdArg))); 9540bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org Push(buffer); 9541bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org Push(byte_offset); 9542bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org Push(byte_length); 9543bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org PushArgumentsFromEnvironment(kArgsLength); 954437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength); 954537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org } 954637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org } 954737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org byte_offset_smi.End(); 9548af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org} 9549af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 9550af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 9551a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateMaxSmi(CallRuntime* expr) { 9552a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org ASSERT(expr->arguments()->length() == 0); 9553a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue)); 9554a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org return ast_context()->ReturnInstruction(max_smi, expr->id()); 9555a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org} 9556a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org 9557a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org 9558895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateTypedArrayMaxSizeInHeap( 9559895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org CallRuntime* expr) { 9560895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org ASSERT(expr->arguments()->length() == 0); 9561895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org HConstant* result = New<HConstant>(static_cast<int32_t>( 9562895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org FLAG_typed_array_max_size_in_heap)); 9563895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org return ast_context()->ReturnInstruction(result, expr->id()); 9564895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org} 9565895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 9566895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org 95672f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateArrayBufferGetByteLength( 95682f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org CallRuntime* expr) { 95692f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org ASSERT(expr->arguments()->length() == 1); 95702f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 95712f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org HValue* buffer = Pop(); 95722f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org HInstruction* result = New<HLoadNamedField>( 95732f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org buffer, 95742f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org static_cast<HValue*>(NULL), 95752f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org HObjectAccess::ForJSArrayBufferByteLength()); 95762f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org return ast_context()->ReturnInstruction(result, expr->id()); 95772f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org} 95782f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 95792f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 95802f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteLength( 95812f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org CallRuntime* expr) { 95822f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org ASSERT(expr->arguments()->length() == 1); 95832f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 95842f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org HValue* buffer = Pop(); 95852f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org HInstruction* result = New<HLoadNamedField>( 95862f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org buffer, 95872f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org static_cast<HValue*>(NULL), 95882f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org HObjectAccess::ForJSArrayBufferViewByteLength()); 95892f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org return ast_context()->ReturnInstruction(result, expr->id()); 95902f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org} 95912f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 95922f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 95932f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteOffset( 95942f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org CallRuntime* expr) { 95952f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org ASSERT(expr->arguments()->length() == 1); 95962f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 95972f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org HValue* buffer = Pop(); 95982f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org HInstruction* result = New<HLoadNamedField>( 95992f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org buffer, 96002f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org static_cast<HValue*>(NULL), 96012f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org HObjectAccess::ForJSArrayBufferViewByteOffset()); 96022f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org return ast_context()->ReturnInstruction(result, expr->id()); 96032f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org} 96042f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 96052f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 96062f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateTypedArrayGetLength( 96072f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org CallRuntime* expr) { 96082f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org ASSERT(expr->arguments()->length() == 1); 96092f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 96102f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org HValue* buffer = Pop(); 96112f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org HInstruction* result = New<HLoadNamedField>( 96122f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org buffer, 96132f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org static_cast<HValue*>(NULL), 96142f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org HObjectAccess::ForJSTypedArrayLength()); 96152f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org return ast_context()->ReturnInstruction(result, expr->id()); 96162f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org} 96172f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 96182f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 9619a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { 9620160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 9621160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 9622160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 9623a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (expr->is_jsruntime()) { 9624594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kCallToAJavaScriptRuntimeFunction); 9625a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 9626a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9627ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org const Runtime::Function* function = expr->function(); 96283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(function != NULL); 9629af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 96309b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org if (function->intrinsic_type == Runtime::INLINE || 96319b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org function->intrinsic_type == Runtime::INLINE_OPTIMIZED) { 96323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(expr->name()->length() > 0); 96333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(expr->name()->Get(0) == '_'); 9634a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Call to an inline function. 9635a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int lookup_index = static_cast<int>(function->function_id) - 9636a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org static_cast<int>(Runtime::kFirstInlineFunction); 9637a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(lookup_index >= 0); 9638a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(static_cast<size_t>(lookup_index) < 9639a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ARRAY_SIZE(kInlineFunctionGenerators)); 9640a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; 9641a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9642a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Call the inline code generator using the pointer-to-member. 96433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org (this->*generator)(expr); 9644a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 9645a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(function->intrinsic_type == Runtime::RUNTIME); 96463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Handle<String> name = expr->name(); 96473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int argument_count = expr->arguments()->length(); 9648bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org CHECK_ALIVE(VisitExpressions(expr->arguments())); 9649bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org PushArgumentsFromEnvironment(argument_count); 9650d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HCallRuntime* call = New<HCallRuntime>(name, function, 9651d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org argument_count); 96524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(call, expr->id()); 9653a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 9654a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 9655a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9656a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9657a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { 9658160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 9659160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 9660160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 966183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org switch (expr->op()) { 966283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org case Token::DELETE: return VisitDelete(expr); 966383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org case Token::VOID: return VisitVoid(expr); 966483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org case Token::TYPEOF: return VisitTypeof(expr); 966583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org case Token::NOT: return VisitNot(expr); 966683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org default: UNREACHABLE(); 966783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 966883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 966983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 9670c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 9671a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { 967283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Property* prop = expr->expression()->AsProperty(); 9673486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org VariableProxy* proxy = expr->expression()->AsVariableProxy(); 9674486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (prop != NULL) { 96754668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org CHECK_ALIVE(VisitForValue(prop->obj())); 96764668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org CHECK_ALIVE(VisitForValue(prop->key())); 96774668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org HValue* key = Pop(); 96784668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org HValue* obj = Pop(); 9679d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HValue* function = AddLoadJSBuiltin(Builtins::DELETE); 96808d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Add<HPushArguments>(obj, key, Add<HConstant>(function_strict_mode())); 9681bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // TODO(olivf) InvokeFunction produces a check for the parameter count, 9682bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // even though we are certain to pass the correct number of arguments here. 9683d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HInstruction* instr = New<HInvokeFunction>(function, 3); 96844668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org return ast_context()->ReturnInstruction(instr, expr->id()); 9685486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } else if (proxy != NULL) { 9686486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Variable* var = proxy->var(); 9687486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (var->IsUnallocated()) { 9688594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Bailout(kDeleteWithGlobalVariable); 9689486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } else if (var->IsStackAllocated() || var->IsContextSlot()) { 9690486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Result of deleting non-global variables is false. 'this' is not 9691486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // really a variable, though we implement it as one. The 9692486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // subexpression does not have side effects. 9693486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org HValue* value = var->is_this() 9694486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ? graph()->GetConstantTrue() 9695486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org : graph()->GetConstantFalse(); 9696486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org return ast_context()->ReturnValue(value); 9697486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } else { 9698594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Bailout(kDeleteWithNonGlobalVariable); 9699486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 970083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 9701486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Result of deleting non-property, non-variable reference is true. 9702486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Evaluate the subexpression for side effects. 9703486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org CHECK_ALIVE(VisitForEffect(expr->expression())); 9704486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org return ast_context()->ReturnValue(graph()->GetConstantTrue()); 970583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 970683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 97078f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 97088f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 9709a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitVoid(UnaryOperation* expr) { 971083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CHECK_ALIVE(VisitForEffect(expr->expression())); 97114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 971283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 97133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 9714badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 9715a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) { 971683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CHECK_ALIVE(VisitForTypeOf(expr->expression())); 971783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org HValue* value = Pop(); 97188e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org HInstruction* instr = New<HTypeof>(value); 9719ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org return ast_context()->ReturnInstruction(instr, expr->id()); 972083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 972183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 972283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 9723a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { 972483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (ast_context()->IsTest()) { 972583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org TestContext* context = TestContext::cast(ast_context()); 972683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org VisitForControl(expr->expression(), 972783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org context->if_false(), 972883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org context->if_true()); 972983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return; 973083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 973183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 973283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (ast_context()->IsEffect()) { 973383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org VisitForEffect(expr->expression()); 973483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return; 973583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 973683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 973783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(ast_context()->IsValue()); 973883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org HBasicBlock* materialize_false = graph()->CreateBasicBlock(); 973983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org HBasicBlock* materialize_true = graph()->CreateBasicBlock(); 974083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CHECK_BAILOUT(VisitForControl(expr->expression(), 974183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org materialize_false, 974283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org materialize_true)); 974383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 974483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (materialize_false->HasPredecessor()) { 9745c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org materialize_false->SetJoinId(expr->MaterializeFalseId()); 974683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org set_current_block(materialize_false); 974783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Push(graph()->GetConstantFalse()); 9748badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } else { 974983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org materialize_false = NULL; 975083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 975183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 975283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (materialize_true->HasPredecessor()) { 9753c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org materialize_true->SetJoinId(expr->MaterializeTrueId()); 975483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org set_current_block(materialize_true); 975583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Push(graph()->GetConstantTrue()); 975683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 975783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org materialize_true = NULL; 9758a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 975983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 976083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org HBasicBlock* join = 976183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CreateJoin(materialize_false, materialize_true, expr->id()); 976283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org set_current_block(join); 97634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (join != NULL) return ast_context()->ReturnValue(Pop()); 9764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 9765a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9766a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9767a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildIncrement( 9768a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool returns_original_input, 9769a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CountOperation* expr) { 9770c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // The input to the count operation is on top of the expression stack. 97716d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Representation rep = Representation::FromType(expr->type()); 97721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (rep.IsNone() || rep.IsTagged()) { 9773ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org rep = Representation::Smi(); 97748e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org } 9775c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 9776c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (returns_original_input) { 9777c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // We need an explicit HValue representing ToNumber(input). The 9778c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // actual HChange instruction we need is (sometimes) added in a later 9779c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // phase, so it is not available now to be used as an input to HAdd and 9780c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // as the return value. 97819af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org HInstruction* number_input = AddUncasted<HForceRepresentation>(Pop(), rep); 97821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (!rep.IsDouble()) { 97831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org number_input->SetFlag(HInstruction::kFlexibleRepresentation); 97841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org number_input->SetFlag(HInstruction::kCannotBeTagged); 97851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 9786c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Push(number_input); 9787c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 9788c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 9789c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // The addition has no side effects, so we do not need 9790c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // to simulate the expression stack after this instruction. 9791c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Any later failures deopt to the load of the input or earlier. 9792c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org HConstant* delta = (expr->op() == Token::INC) 9793a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ? graph()->GetConstant1() 9794a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org : graph()->GetConstantMinus1(); 9795662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org HInstruction* instr = AddUncasted<HAdd>(Top(), delta); 9796662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org if (instr->IsAdd()) { 9797662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org HAdd* add = HAdd::cast(instr); 9798662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org add->set_observed_input_representation(1, rep); 9799662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org add->set_observed_input_representation(2, Representation::Smi()); 9800662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } 98011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org instr->SetFlag(HInstruction::kCannotBeTagged); 9802fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org instr->ClearAllSideEffects(); 9803a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return instr; 9804a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 9805a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9806a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9807639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.orgvoid HOptimizedGraphBuilder::BuildStoreForEffect(Expression* expr, 9808639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Property* prop, 9809639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org BailoutId ast_id, 9810639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org BailoutId return_id, 9811639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org HValue* object, 9812639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org HValue* key, 9813639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org HValue* value) { 98142c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org EffectContext for_effect(this); 98152c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org Push(object); 9816639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (key != NULL) Push(key); 98172c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org Push(value); 9818639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org BuildStore(expr, prop, ast_id, return_id); 98192c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org} 98202c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org 98212c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org 9822a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { 9823160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 9824160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 9825160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 9826f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 982744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org Expression* target = expr->expression(); 9828a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org VariableProxy* proxy = target->AsVariableProxy(); 9829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Property* prop = target->AsProperty(); 9830486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (proxy == NULL && prop == NULL) { 9831594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kInvalidLhsInCountOperation); 9832c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 9833c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 9834c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Match the full code generator stack by simulating an extra stack 9835c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // element for postfix operations in a non-effect context. The return 9836c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // value is ToNumber(input). 9837c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org bool returns_original_input = 9838c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org expr->is_postfix() && !ast_context()->IsEffect(); 9839c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org HValue* input = NULL; // ToNumber(original_input). 9840c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org HValue* after = NULL; // The result after incrementing or decrementing. 9841a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9842486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (proxy != NULL) { 9843486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Variable* var = proxy->var(); 9844486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (var->mode() == CONST_LEGACY) { 9845594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kUnsupportedCountOperationWithConst); 9846d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } 9847c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Argument of the count operation is a variable, not a property. 9848c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(prop == NULL); 9849160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(target)); 9850a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9851c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org after = BuildIncrement(returns_original_input, expr); 9852c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org input = returns_original_input ? Top() : Pop(); 98535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Push(after); 9854a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9855486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org switch (var->location()) { 9856486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::UNALLOCATED: 9857486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org HandleGlobalVariableAssignment(var, 9858486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org after, 9859486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org expr->AssignmentId()); 9860486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org break; 9861486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 9862486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::PARAMETER: 9863486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::LOCAL: 9864d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org BindIfLive(var, after); 9865486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org break; 9866486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 9867486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::CONTEXT: { 9868486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Bail out if we try to mutate a parameter value in a function 9869486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // using the arguments object. We do not (yet) correctly handle the 9870486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // arguments property of the function. 987141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (current_info()->scope()->arguments() != NULL) { 9872486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Parameters will rewrite to context slots. We have no direct 9873486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // way to detect that the variable is a parameter so we use a 9874486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // linear search of the parameter list. 987541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org int count = current_info()->scope()->num_parameters(); 9876486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org for (int i = 0; i < count; ++i) { 987741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (var == current_info()->scope()->parameter(i)) { 9878594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kAssignmentToParameterInArgumentsObject); 9879486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 98807b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 98817b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 9882486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 9883486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org HValue* context = BuildContextChainWalk(var); 9884355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) 98857ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; 98861510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), 98871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org mode, after); 9888c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (instr->HasObservableSideEffects()) { 9889c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 9890c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 9891486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org break; 98927b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 98937b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org 9894486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::LOOKUP: 9895594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kLookupVariableInCountOperation); 9896a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 9897a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9898639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Drop(returns_original_input ? 2 : 1); 9899639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org return ast_context()->ReturnValue(expr->is_postfix() ? input : after); 9900639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org } 9901a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9902639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org // Argument of the count operation is a property. 9903639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org ASSERT(prop != NULL); 9904639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (returns_original_input) Push(graph()->GetConstantUndefined()); 9905a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9906639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org CHECK_ALIVE(VisitForValue(prop->obj())); 9907639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org HValue* object = Top(); 9908a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9909639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org HValue* key = NULL; 9910528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if ((!prop->IsFunctionPrototype() && !prop->key()->IsPropertyName()) || 9911639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org prop->IsStringAccess()) { 9912639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org CHECK_ALIVE(VisitForValue(prop->key())); 9913639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org key = Top(); 9914639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org } 99153d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org 991671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org CHECK_ALIVE(PushLoad(prop, object, key)); 9917a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9918639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org after = BuildIncrement(returns_original_input, expr); 9919a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9920639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (returns_original_input) { 9921639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org input = Pop(); 9922639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org // Drop object and key to push it again in the effect context below. 9923639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Drop(key == NULL ? 1 : 2); 9924639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org environment()->SetExpressionStackAt(0, input); 9925639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org CHECK_ALIVE(BuildStoreForEffect( 9926639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org expr, prop, expr->id(), expr->AssignmentId(), object, key, after)); 9927639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org return ast_context()->ReturnValue(Pop()); 9928a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 9929c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 9930639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org environment()->SetExpressionStackAt(0, after); 9931639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org return BuildStore(expr, prop, expr->id(), expr->AssignmentId()); 9932a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 9933a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9934a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 99352e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( 9936a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* string, 9937a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* index) { 99382e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org if (string->IsConstant() && index->IsConstant()) { 99392e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org HConstant* c_string = HConstant::cast(string); 99402e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org HConstant* c_index = HConstant::cast(index); 99412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org if (c_string->HasStringValue() && c_index->HasNumberValue()) { 99422e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org int32_t i = c_index->NumberValueAsInteger32(); 99432e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org Handle<String> s = c_string->StringValue(); 99442e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org if (i < 0 || i >= s->length()) { 9945d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return New<HConstant>(OS::nan_value()); 99462e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org } 9947d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return New<HConstant>(s->Get(i)); 99482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org } 99492e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org } 99500f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org string = BuildCheckString(string); 99510f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org index = Add<HBoundsCheck>(index, AddLoadStringLength(string)); 99520f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org return New<HStringCharCodeAt>(string, index); 99530a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 99540a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 9955e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 9956528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org// Checks if the given shift amounts have following forms: 9957528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org// (N1) and (N2) with N1 + N2 = 32; (sa) and (32 - sa). 9958e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgstatic bool ShiftAmountsAllowReplaceByRotate(HValue* sa, 9959e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org HValue* const32_minus_sa) { 9960528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (sa->IsConstant() && const32_minus_sa->IsConstant()) { 9961528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org const HConstant* c1 = HConstant::cast(sa); 9962528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org const HConstant* c2 = HConstant::cast(const32_minus_sa); 9963528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return c1->HasInteger32Value() && c2->HasInteger32Value() && 9964528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org (c1->Integer32Value() + c2->Integer32Value() == 32); 9965528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 9966e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (!const32_minus_sa->IsSub()) return false; 9967e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org HSub* sub = HSub::cast(const32_minus_sa); 9968381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org return sub->left()->EqualsInteger32Constant(32) && sub->right() == sa; 9969e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 9970e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 9971e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 9972e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org// Checks if the left and the right are shift instructions with the oposite 9973e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org// directions that can be replaced by one rotate right instruction or not. 9974e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org// Returns the operand and the shift amount for the rotate instruction in the 9975e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org// former case. 9976528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgbool HGraphBuilder::MatchRotateRight(HValue* left, 9977528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org HValue* right, 9978528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org HValue** operand, 9979528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org HValue** shift_amount) { 9980e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org HShl* shl; 9981e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org HShr* shr; 9982e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (left->IsShl() && right->IsShr()) { 9983e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org shl = HShl::cast(left); 9984e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org shr = HShr::cast(right); 9985e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else if (left->IsShr() && right->IsShl()) { 9986e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org shl = HShl::cast(right); 9987e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org shr = HShr::cast(left); 9988e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else { 9989e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org return false; 9990e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 99916bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org if (shl->left() != shr->left()) return false; 9992e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 9993e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (!ShiftAmountsAllowReplaceByRotate(shl->right(), shr->right()) && 9994e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org !ShiftAmountsAllowReplaceByRotate(shr->right(), shl->right())) { 9995e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org return false; 9996e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 9997e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org *operand= shr->left(); 9998e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org *shift_amount = shr->right(); 9999e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org return true; 10000e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 10001e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 10002e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 100034e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgbool CanBeZero(HValue* right) { 10004e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (right->IsConstant()) { 10005e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org HConstant* right_const = HConstant::cast(right); 10006e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (right_const->HasInteger32Value() && 10007e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org (right_const->Integer32Value() & 0x1f) != 0) { 10008e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org return false; 10009e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 10010e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 10011e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org return true; 10012e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 10013e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 100140a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 10015528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgHValue* HGraphBuilder::EnforceNumberType(HValue* number, 100166d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* expected) { 100174452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org if (expected->Is(Type::SignedSmall())) { 10018ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org return AddUncasted<HForceRepresentation>(number, Representation::Smi()); 10019ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 10020ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org if (expected->Is(Type::Signed32())) { 10021ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org return AddUncasted<HForceRepresentation>(number, 10022ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org Representation::Integer32()); 10023ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org } 10024ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org return number; 10025528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 10026528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 10027528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 100286d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.orgHValue* HGraphBuilder::TruncateToNumber(HValue* value, Type** expected) { 10029c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (value->IsConstant()) { 10030c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org HConstant* constant = HConstant::cast(value); 10031c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone()); 10032c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (number.has_value) { 100336d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org *expected = Type::Number(zone()); 10034c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org return AddInstruction(number.value); 10035c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } 10036c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } 10037c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 10038528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // We put temporary values on the stack, which don't correspond to anything 10039528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // in baseline code. Since nothing is observable we avoid recording those 10040528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // pushes with a NoObservableSideEffectsScope. 10041528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org NoObservableSideEffectsScope no_effects(this); 10042528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 100436d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* expected_type = *expected; 10044528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 10045528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Separate the number type from the rest. 100466d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* expected_obj = 100476d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type::Intersect(expected_type, Type::NonNumber(zone()), zone()); 100486d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* expected_number = 100496d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type::Intersect(expected_type, Type::Number(zone()), zone()); 10050528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 10051528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // We expect to get a number. 10052528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // (We need to check first, since Type::None->Is(Type::Any()) == true. 10053528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (expected_obj->Is(Type::None())) { 100546d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org ASSERT(!expected_number->Is(Type::None(zone()))); 10055528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return value; 10056528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 10057528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 100586d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org if (expected_obj->Is(Type::Undefined(zone()))) { 10059528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // This is already done by HChange. 100607e6132b924829c353864933f29124419916db550machenbach@chromium.org *expected = Type::Union(expected_number, Type::Number(zone()), zone()); 10061528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return value; 10062528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 10063528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 10064c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org return value; 10065c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org} 10066c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 10067c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 100687ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.orgHValue* HOptimizedGraphBuilder::BuildBinaryOperation( 10069a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org BinaryOperation* expr, 10070a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org HValue* left, 1007125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org HValue* right, 1007225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org PushBeforeSimulateBehavior push_sim_result) { 100736d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* left_type = expr->left()->bounds().lower; 100746d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* right_type = expr->right()->bounds().lower; 100756d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* result_type = expr->bounds().lower; 100761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Maybe<int> fixed_right_arg = expr->fixed_right_arg(); 100770f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Handle<AllocationSite> allocation_site = expr->allocation_site(); 100780f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 10079d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org HAllocationMode allocation_mode; 10080d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) { 10081d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org allocation_mode = HAllocationMode(allocation_site); 10082d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org } 10083528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 100847ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HValue* result = HGraphBuilder::BuildBinaryOperation( 100850f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org expr->op(), left, right, left_type, right_type, result_type, 100860f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org fixed_right_arg, allocation_mode); 100877ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // Add a simulate after instructions with observable side effects, and 100887ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // after phis, which are the result of BuildBinaryOperation when we 100897ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // inlined some complex subgraph. 100907ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org if (result->HasObservableSideEffects() || result->IsPhi()) { 10091f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (push_sim_result == PUSH_BEFORE_SIMULATE) { 10092052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org Push(result); 10093bfd1d202fb7cd6d54d956414bad9f75a995d0f65machenbach@chromium.org Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 10094052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org Drop(1); 10095f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 10096f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 1009725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org } 100987ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org } 100997ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org return result; 10100528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 10101528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 10102528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 101037ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.orgHValue* HGraphBuilder::BuildBinaryOperation( 10104528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Token::Value op, 10105528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org HValue* left, 10106528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org HValue* right, 101076d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* left_type, 101086d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* right_type, 101096d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* result_type, 101100f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Maybe<int> fixed_right_arg, 101110f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HAllocationMode allocation_mode) { 10112528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 10113e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org Representation left_rep = Representation::FromType(left_type); 10114e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org Representation right_rep = Representation::FromType(right_type); 10115e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 10116528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bool maybe_string_add = op == Token::ADD && 10117528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org (left_type->Maybe(Type::String()) || 10118528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org right_type->Maybe(Type::String())); 10119c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 10120b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (left_type->Is(Type::None())) { 101213d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation", 10122594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Deoptimizer::SOFT); 10123528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // TODO(rossberg): we should be able to get rid of non-continuous 10124528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // defaults. 101256d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org left_type = Type::Any(zone()); 10126528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } else { 10127528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (!maybe_string_add) left = TruncateToNumber(left, &left_type); 10128528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org left_rep = Representation::FromType(left_type); 10129b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 10130528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 10131b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (right_type->Is(Type::None())) { 101323d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation", 10133594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Deoptimizer::SOFT); 101346d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org right_type = Type::Any(zone()); 10135528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } else { 10136528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (!maybe_string_add) right = TruncateToNumber(right, &right_type); 10137528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org right_rep = Representation::FromType(right_type); 10138e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 10139528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 10140e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org // Special case for string addition here. 10141e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org if (op == Token::ADD && 10142e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { 10143b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // Validate type feedback for left argument. 10144e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org if (left_type->Is(Type::String())) { 1014590dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org left = BuildCheckString(left); 10146b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 10147b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 10148b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // Validate type feedback for right argument. 10149b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (right_type->Is(Type::String())) { 1015090dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org right = BuildCheckString(right); 10151b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 10152b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 10153b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // Convert left argument as necessary. 10154b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (left_type->Is(Type::Number())) { 10155b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org ASSERT(right_type->Is(Type::String())); 10156e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org left = BuildNumberToString(left, left_type); 10157b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } else if (!left_type->Is(Type::String())) { 10158e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org ASSERT(right_type->Is(Type::String())); 10159e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT); 101608d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Add<HPushArguments>(left, right); 101617ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org return AddUncasted<HInvokeFunction>(function, 2); 10162e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org } 10163e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org 10164b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // Convert right argument as necessary. 10165b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (right_type->Is(Type::Number())) { 10166b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org ASSERT(left_type->Is(Type::String())); 10167e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org right = BuildNumberToString(right, right_type); 10168b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } else if (!right_type->Is(Type::String())) { 10169e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org ASSERT(left_type->Is(Type::String())); 10170e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); 101718d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Add<HPushArguments>(left, right); 101727ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org return AddUncasted<HInvokeFunction>(function, 2); 10173e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org } 10174e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org 10175bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org // Fast path for empty constant strings. 10176bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org if (left->IsConstant() && 10177bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org HConstant::cast(left)->HasStringValue() && 10178bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org HConstant::cast(left)->StringValue()->length() == 0) { 10179bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org return right; 10180bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org } 10181bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org if (right->IsConstant() && 10182bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org HConstant::cast(right)->HasStringValue() && 10183bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org HConstant::cast(right)->StringValue()->length() == 0) { 10184bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org return left; 101850f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } 101860f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 101870f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Register the dependent code with the allocation site. 101880f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if (!allocation_mode.feedback_site().is_null()) { 101890f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org ASSERT(!graph()->info()->IsStub()); 101904ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org Handle<AllocationSite> site(allocation_mode.feedback_site()); 101914ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org AllocationSite::AddDependentCompilationInfo( 101924ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org site, AllocationSite::TENURING, top_info()); 101930f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } 101940f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 10195bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org // Inline the string addition into the stub when creating allocation 10196bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org // mementos to gather allocation site feedback, or if we can statically 10197bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org // infer that we're going to create a cons string. 10198bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org if ((graph()->info()->IsStub() && 10199bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org allocation_mode.CreateAllocationMementos()) || 10200bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org (left->IsConstant() && 10201bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org HConstant::cast(left)->HasStringValue() && 10202bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org HConstant::cast(left)->StringValue()->length() + 1 >= 10203bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org ConsString::kMinLength) || 10204bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org (right->IsConstant() && 10205bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org HConstant::cast(right)->HasStringValue() && 10206bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org HConstant::cast(right)->StringValue()->length() + 1 >= 10207bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org ConsString::kMinLength)) { 10208bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org return BuildStringAdd(left, right, allocation_mode); 102090f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } 102100f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 102110f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Fallback to using the string add stub. 102120f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org return AddUncasted<HStringAdd>( 102130f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org left, right, allocation_mode.GetPretenureMode(), 102140f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); 10215e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org } 10216e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org 10217f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (graph()->info()->IsStub()) { 1021825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org left = EnforceNumberType(left, left_type); 1021925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org right = EnforceNumberType(right, right_type); 1022025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org } 1022125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org 10222528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Representation result_rep = Representation::FromType(result_type); 10223528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 1022425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || 1022525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org (right_rep.IsTagged() && !right_rep.IsSmi()); 10226528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 10227e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org HInstruction* instr = NULL; 1022825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org // Only the stub is allowed to call into the runtime, since otherwise we would 1022925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org // inline several instructions (including the two pushes) for every tagged 1023025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org // operation in optimized code, which is more expensive, than a stub call. 10231f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (graph()->info()->IsStub() && is_non_primitive) { 1023225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op)); 102338d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Add<HPushArguments>(left, right); 102347ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org instr = AddUncasted<HInvokeFunction>(function, 2); 1023525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org } else { 1023625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org switch (op) { 1023725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::ADD: 102387ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org instr = AddUncasted<HAdd>(left, right); 1023925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 1024025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::SUB: 102417ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org instr = AddUncasted<HSub>(left, right); 1024225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 1024325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::MUL: 102447ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org instr = AddUncasted<HMul>(left, right); 1024525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 102467ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org case Token::MOD: { 10247381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org if (fixed_right_arg.has_value && 10248381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org !right->EqualsInteger32Constant(fixed_right_arg.value)) { 10249381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org HConstant* fixed_right = Add<HConstant>( 10250381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org static_cast<int>(fixed_right_arg.value)); 10251381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org IfBuilder if_same(this); 10252381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ); 10253381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org if_same.Then(); 10254381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org if_same.ElseDeopt("Unexpected RHS of binary operation"); 10255381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org right = fixed_right; 102567ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org } 102577ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org instr = AddUncasted<HMod>(left, right); 1025825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 102597ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org } 1026025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::DIV: 102617ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org instr = AddUncasted<HDiv>(left, right); 1026225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 1026325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::BIT_XOR: 1026425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::BIT_AND: 102657ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org instr = AddUncasted<HBitwise>(op, left, right); 1026625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 1026725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::BIT_OR: { 1026825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org HValue* operand, *shift_amount; 1026925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org if (left_type->Is(Type::Signed32()) && 1027025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org right_type->Is(Type::Signed32()) && 1027125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org MatchRotateRight(left, right, &operand, &shift_amount)) { 102727ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org instr = AddUncasted<HRor>(operand, shift_amount); 1027325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org } else { 102747ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org instr = AddUncasted<HBitwise>(op, left, right); 1027525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org } 1027625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 10277e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 1027825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::SAR: 102797ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org instr = AddUncasted<HSar>(left, right); 1028025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 1028125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::SHR: 102827ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org instr = AddUncasted<HShr>(left, right); 1028325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org if (FLAG_opt_safe_uint32_operations && instr->IsShr() && 1028425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org CanBeZero(right)) { 1028525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org graph()->RecordUint32Instruction(instr); 1028625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org } 1028725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 1028825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::SHL: 102897ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org instr = AddUncasted<HShl>(left, right); 1029025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 1029125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org default: 1029225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org UNREACHABLE(); 10293e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 10294e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 10295e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 10296fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (instr->IsBinaryOperation()) { 10297fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org HBinaryOperation* binop = HBinaryOperation::cast(instr); 10298ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org binop->set_observed_input_representation(1, left_rep); 10299ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org binop->set_observed_input_representation(2, right_rep); 10300fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org binop->initialize_output_representation(result_rep); 10301f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (graph()->info()->IsStub()) { 1030225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org // Stub should not call into stub. 1030325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org instr->SetFlag(HValue::kCannotBeTagged); 1030425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org // And should truncate on HForceRepresentation already. 1030525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org if (left->IsForceRepresentation()) { 1030625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org left->CopyFlag(HValue::kTruncatingToSmi, instr); 1030725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org left->CopyFlag(HValue::kTruncatingToInt32, instr); 1030825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org } 1030925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org if (right->IsForceRepresentation()) { 1031025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org right->CopyFlag(HValue::kTruncatingToSmi, instr); 1031125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org right->CopyFlag(HValue::kTruncatingToInt32, instr); 1031225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org } 1031325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org } 10314a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 10315a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return instr; 10316a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 10317a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 10318a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 10319a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Check for the form (%_ClassOf(foo) === 'BarClass'). 10320a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgstatic bool IsClassOfTest(CompareOperation* expr) { 10321a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (expr->op() != Token::EQ_STRICT) return false; 10322a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CallRuntime* call = expr->left()->AsCallRuntime(); 10323a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (call == NULL) return false; 10324a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Literal* literal = expr->right()->AsLiteral(); 10325a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (literal == NULL) return false; 103261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (!literal->value()->IsString()) return false; 1032759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (!call->name()->IsOneByteEqualTo(STATIC_ASCII_VECTOR("_ClassOf"))) { 1032859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org return false; 1032959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 10330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(call->arguments()->length() == 1); 10331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return true; 10332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 10333a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 10334a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 10335a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { 10336160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 10337160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 10338160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 1033983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org switch (expr->op()) { 10340d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com case Token::COMMA: 10341d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com return VisitComma(expr); 10342d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com case Token::OR: 10343d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com case Token::AND: 10344d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com return VisitLogicalExpression(expr); 10345d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com default: 10346d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com return VisitArithmeticExpression(expr); 1034783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 1034883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 103495f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 103505f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 10351a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitComma(BinaryOperation* expr) { 1035283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CHECK_ALIVE(VisitForEffect(expr->left())); 1035383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Visit the right subexpression in the same AST context as the entire 1035483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // expression. 1035583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Visit(expr->right()); 1035683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 103575f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 103588f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 10359a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) { 10360d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com bool is_logical_and = expr->op() == Token::AND; 1036183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (ast_context()->IsTest()) { 1036283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org TestContext* context = TestContext::cast(ast_context()); 1036383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Translate left subexpression. 1036483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org HBasicBlock* eval_right = graph()->CreateBasicBlock(); 1036583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (is_logical_and) { 1036683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CHECK_BAILOUT(VisitForControl(expr->left(), 1036783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org eval_right, 1036883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org context->if_false())); 1036983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 1037083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CHECK_BAILOUT(VisitForControl(expr->left(), 1037183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org context->if_true(), 1037283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org eval_right)); 1037383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 1037483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 1037583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Translate right subexpression by visiting it in the same AST 1037683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // context as the entire expression. 1037783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (eval_right->HasPredecessor()) { 1037883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org eval_right->SetJoinId(expr->RightId()); 103798f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org set_current_block(eval_right); 1038083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Visit(expr->right()); 1038183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 103828f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 1038383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else if (ast_context()->IsValue()) { 1038483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CHECK_ALIVE(VisitForValue(expr->left())); 1038583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(current_block() != NULL); 103862e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org HValue* left_value = Top(); 103872e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org 103886f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org // Short-circuit left values that always evaluate to the same boolean value. 103896f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org if (expr->left()->ToBooleanIsTrue() || expr->left()->ToBooleanIsFalse()) { 103906f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org // l (evals true) && r -> r 103916f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org // l (evals true) || r -> l 103926f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org // l (evals false) && r -> l 103936f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org // l (evals false) || r -> r 103946f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org if (is_logical_and == expr->left()->ToBooleanIsTrue()) { 103956f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org Drop(1); 10396bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org CHECK_ALIVE(VisitForValue(expr->right())); 103972e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org } 103982e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org return ast_context()->ReturnValue(Pop()); 103992e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org } 1040083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 1040183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // We need an extra block to maintain edge-split form. 1040283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org HBasicBlock* empty_block = graph()->CreateBasicBlock(); 1040383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org HBasicBlock* eval_right = graph()->CreateBasicBlock(); 10404c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org ToBooleanStub::Types expected(expr->left()->to_boolean_types()); 104054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HBranch* test = is_logical_and 10406528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org ? New<HBranch>(left_value, expected, eval_right, empty_block) 10407528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org : New<HBranch>(left_value, expected, empty_block, eval_right); 1040871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org FinishCurrentBlock(test); 1040983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 1041083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org set_current_block(eval_right); 1041183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Drop(1); // Value of the left subexpression. 1041283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CHECK_BAILOUT(VisitForValue(expr->right())); 1041383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 1041483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org HBasicBlock* join_block = 1041583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CreateJoin(empty_block, current_block(), expr->id()); 1041683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org set_current_block(join_block); 104174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnValue(Pop()); 104188f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 1041983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 1042083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(ast_context()->IsEffect()); 1042183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // In an effect context, we don't need the value of the left subexpression, 1042283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // only its control flow and side effects. We need an extra block to 1042383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // maintain edge-split form. 1042483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org HBasicBlock* empty_block = graph()->CreateBasicBlock(); 1042583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org HBasicBlock* right_block = graph()->CreateBasicBlock(); 1042683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (is_logical_and) { 1042783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CHECK_BAILOUT(VisitForControl(expr->left(), right_block, empty_block)); 104283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else { 1042983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CHECK_BAILOUT(VisitForControl(expr->left(), empty_block, right_block)); 1043083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 10431160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 1043283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // TODO(kmillikin): Find a way to fix this. It's ugly that there are 1043383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // actually two empty blocks (one here and one inserted by 1043483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // TestContext::BuildBranch, and that they both have an HSimulate though the 1043583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // second one is not a merge node, and that we really have no good AST ID to 1043683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // put on that first HSimulate. 10437160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 1043883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (empty_block->HasPredecessor()) { 1043983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org empty_block->SetJoinId(expr->id()); 1044083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 1044183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org empty_block = NULL; 104425f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 10443a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1044483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (right_block->HasPredecessor()) { 1044583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org right_block->SetJoinId(expr->RightId()); 1044683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org set_current_block(right_block); 1044783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CHECK_BAILOUT(VisitForEffect(expr->right())); 1044883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org right_block = current_block(); 1044983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 1045083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org right_block = NULL; 1045183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 10452a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1045383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org HBasicBlock* join_block = 1045483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CreateJoin(empty_block, right_block, expr->id()); 1045583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org set_current_block(join_block); 1045683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // We did not materialize any value in the predecessor environments, 1045783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // so there is no need to handle it here. 10458a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 10459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 10460a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 10461a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 10462a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { 1046383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CHECK_ALIVE(VisitForValue(expr->left())); 1046483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CHECK_ALIVE(VisitForValue(expr->right())); 10465af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org SetSourcePosition(expr->position()); 1046683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org HValue* right = Pop(); 1046783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org HValue* left = Pop(); 1046825530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org HValue* result = 1046925530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org BuildBinaryOperation(expr, left, right, 1047025530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE 1047125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org : PUSH_BEFORE_SIMULATE); 10472f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (FLAG_hydrogen_track_positions && result->IsBinaryOperation()) { 104737ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org HBinaryOperation::cast(result)->SetOperandPositions( 10474f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org zone(), 10475f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ScriptPositionToSourcePosition(expr->left()->position()), 10476f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ScriptPositionToSourcePosition(expr->right()->position())); 10477af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org } 104787ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org return ast_context()->ReturnValue(result); 1047983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 1048083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 1048183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 10482a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, 1048396a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org Expression* sub_expr, 10484a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> check) { 1048596a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org CHECK_ALIVE(VisitForTypeOf(sub_expr)); 10486af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org SetSourcePosition(expr->position()); 1048796a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org HValue* value = Pop(); 10488db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HTypeofIsAndBranch* instr = New<HTypeofIsAndBranch>(value, check); 10489c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return ast_context()->ReturnControl(instr, expr->id()); 1049004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org} 1049104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org 1049204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org 10493639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.orgstatic bool IsLiteralCompareBool(Isolate* isolate, 10494639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org HValue* left, 104952c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org Token::Value op, 104962c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org HValue* right) { 104972c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org return op == Token::EQ_STRICT && 10498639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org ((left->IsConstant() && 10499639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org HConstant::cast(left)->handle(isolate)->IsBoolean()) || 10500639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org (right->IsConstant() && 10501639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org HConstant::cast(right)->handle(isolate)->IsBoolean())); 105022c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org} 105032c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org 105042c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org 10505a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 10506160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 10507160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 10508160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 1050996a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org 10510f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 1051171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org 1051296a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org // Check for a few fast cases. The AST visiting behavior must be in sync 1051396a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org // with the full codegen: We don't push both left and right values onto 1051496a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org // the expression stack when one side is a special-case literal. 1051596a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org Expression* sub_expr = NULL; 1051696a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org Handle<String> check; 1051796a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { 1051896a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org return HandleLiteralCompareTypeof(expr, sub_expr, check); 1051996a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org } 1052096a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) { 1052196a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue); 1052296a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org } 1052396a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org if (expr->IsLiteralCompareNull(&sub_expr)) { 1052496a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org return HandleLiteralCompareNil(expr, sub_expr, kNullValue); 1052596a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org } 1052696a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org 10527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (IsClassOfTest(expr)) { 10528a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org CallRuntime* call = expr->left()->AsCallRuntime(); 105294f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(call->arguments()->length() == 1); 10530160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 10531a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* value = Pop(); 10532a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Literal* literal = expr->right()->AsLiteral(); 105331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> rhs = Handle<String>::cast(literal->value()); 10534db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HClassOfTestAndBranch* instr = New<HClassOfTestAndBranch>(value, rhs); 105354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnControl(instr, expr->id()); 10536a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 10537a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 105386d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* left_type = expr->left()->bounds().lower; 105396d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* right_type = expr->right()->bounds().lower; 105406d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* combined_type = expr->combined_type(); 10541e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 10542160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(expr->left())); 10543160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(expr->right())); 10544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 10545f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 10546af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 10547a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* right = Pop(); 10548a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* left = Pop(); 10549a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Token::Value op = expr->op(); 10550a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 10551639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (IsLiteralCompareBool(isolate(), left, op, right)) { 105522c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org HCompareObjectEqAndBranch* result = 10553d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org New<HCompareObjectEqAndBranch>(left, right); 105542c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org return ast_context()->ReturnControl(result, expr->id()); 105552c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org } 10556394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 10557a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (op == Token::INSTANCEOF) { 10558d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Check to see if the rhs of the instanceof is a global function not 10559d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // residing in new space. If it is we assume that the function will stay the 10560d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // same. 10561d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org Handle<JSFunction> target = Handle<JSFunction>::null(); 10562486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org VariableProxy* proxy = expr->right()->AsVariableProxy(); 10563486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated(); 10564d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org if (global_function && 1056541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org current_info()->has_global_object() && 1056641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org !current_info()->global_object()->IsAccessCheckNeeded()) { 10567486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Handle<String> name = proxy->name(); 1056841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<GlobalObject> global(current_info()->global_object()); 10569394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com LookupResult lookup(isolate()); 105703484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org global->Lookup(name, &lookup); 10571de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org if (lookup.IsNormal() && lookup.GetValue()->IsJSFunction()) { 10572d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org Handle<JSFunction> candidate(JSFunction::cast(lookup.GetValue())); 10573d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // If the function is in new space we assume it's more likely to 10574d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // change and thus prefer the general IC code. 10575ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (!isolate()->heap()->InNewSpace(*candidate)) { 10576d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org target = candidate; 10577d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 10578d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 10579d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 10580d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 10581d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // If the target is not null we have found a known global function that is 10582d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // assumed to stay the same for this instanceof. 10583d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org if (target.is_null()) { 10584db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HInstanceOf* result = New<HInstanceOf>(left, right); 105854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(result, expr->id()); 10586d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } else { 105871f410f9a9c4fbd4270749af64b477df87b753158mstarzinger@chromium.org Add<HCheckValue>(right, target); 105884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HInstanceOfKnownGlobal* result = 105898e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org New<HInstanceOfKnownGlobal>(left, target); 105904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(result, expr->id()); 10591d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 10592c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 10593c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // Code below assumes that we don't fall through. 10594c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org UNREACHABLE(); 10595a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (op == Token::IN) { 10596d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HValue* function = AddLoadJSBuiltin(Builtins::IN); 105978d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org Add<HPushArguments>(left, right); 10598bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // TODO(olivf) InvokeFunction produces a check for the parameter count, 10599bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // even though we are certain to pass the correct number of arguments here. 106008e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org HInstruction* result = New<HInvokeFunction>(function, 2); 106014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(result, expr->id()); 10602c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 10603c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 10604f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PushBeforeSimulateBehavior push_behavior = 10605f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE 10606f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org : PUSH_BEFORE_SIMULATE; 106074f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org HControlInstruction* compare = BuildCompareInstruction( 106084f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org op, left, right, left_type, right_type, combined_type, 10609f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ScriptPositionToSourcePosition(expr->left()->position()), 10610f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ScriptPositionToSourcePosition(expr->right()->position()), 10611f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org push_behavior, expr->id()); 106124f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org if (compare == NULL) return; // Bailed out. 106134f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org return ast_context()->ReturnControl(compare, expr->id()); 106144f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org} 106154f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org 106164f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org 106174f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.orgHControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( 106184f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org Token::Value op, 106194f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org HValue* left, 106204f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org HValue* right, 106216d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* left_type, 106226d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* right_type, 106236d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* combined_type, 10624f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HSourcePosition left_position, 10625f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HSourcePosition right_position, 10626f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PushBeforeSimulateBehavior push_sim_result, 106274f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org BailoutId bailout_id) { 1062871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org // Cases handled below depend on collected type feedback. They should 1062971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org // soft deoptimize when there is no type feedback. 1063071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org if (combined_type->Is(Type::None())) { 1063171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org Add<HDeoptimize>("Insufficient type feedback for combined type " 1063271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org "of binary operation", 1063371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org Deoptimizer::SOFT); 106346d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org combined_type = left_type = right_type = Type::Any(zone()); 1063571ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } 1063671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org 106374f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org Representation left_rep = Representation::FromType(left_type); 106384f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org Representation right_rep = Representation::FromType(right_type); 106394f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org Representation combined_rep = Representation::FromType(combined_type); 106404f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org 10641c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (combined_type->Is(Type::Receiver())) { 106424f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org if (Token::IsEqualityOp(op)) { 106432ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org // HCompareObjectEqAndBranch can only deal with object, so 106442ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org // exclude numbers. 106452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if ((left->IsConstant() && 106462ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org HConstant::cast(left)->HasNumberValue()) || 106472ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org (right->IsConstant() && 106482ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org HConstant::cast(right)->HasNumberValue())) { 106492ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Add<HDeoptimize>("Type mismatch between feedback and constant", 106502ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Deoptimizer::SOFT); 106512ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org // The caller expects a branch instruction, so make it happy. 106522ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org return New<HBranch>(graph()->GetConstantTrue()); 106532ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 106544f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org // Can we get away with map check and not instance type check? 1065571ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org HValue* operand_to_check = 1065671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org left->block()->block_id() < right->block()->block_id() ? left : right; 106574f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org if (combined_type->IsClass()) { 106589fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<Map> map = combined_type->AsClass()->Map(); 1065971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org AddCheckMap(operand_to_check, map); 106604f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org HCompareObjectEqAndBranch* result = 106614f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org New<HCompareObjectEqAndBranch>(left, right); 10662f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (FLAG_hydrogen_track_positions) { 106634f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org result->set_operand_position(zone(), 0, left_position); 106644f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org result->set_operand_position(zone(), 1, right_position); 1066564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 106664f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org return result; 106674f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org } else { 1066871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org BuildCheckHeapObject(operand_to_check); 1066971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org Add<HCheckInstanceType>(operand_to_check, 1067071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org HCheckInstanceType::IS_SPEC_OBJECT); 106714f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org HCompareObjectEqAndBranch* result = 106724f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org New<HCompareObjectEqAndBranch>(left, right); 106734f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org return result; 10674a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 106754f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org } else { 106764f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org Bailout(kUnsupportedNonPrimitiveCompare); 106774f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org return NULL; 10678a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 106791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } else if (combined_type->Is(Type::InternalizedString()) && 106804a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Token::IsEqualityOp(op)) { 106815b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org // If we have a constant argument, it should be consistent with the type 106825b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org // feedback (otherwise we fail assertions in HCompareObjectEqAndBranch). 106835b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org if ((left->IsConstant() && 106845b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org !HConstant::cast(left)->HasInternalizedStringValue()) || 106855b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org (right->IsConstant() && 106865b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org !HConstant::cast(right)->HasInternalizedStringValue())) { 106875b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org Add<HDeoptimize>("Type mismatch between feedback and constant", 106885b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org Deoptimizer::SOFT); 106895b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org // The caller expects a branch instruction, so make it happy. 106905b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org return New<HBranch>(graph()->GetConstantTrue()); 106915b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org } 106921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org BuildCheckHeapObject(left); 10693c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Add<HCheckInstanceType>(left, HCheckInstanceType::IS_INTERNALIZED_STRING); 106941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org BuildCheckHeapObject(right); 10695c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Add<HCheckInstanceType>(right, HCheckInstanceType::IS_INTERNALIZED_STRING); 106964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HCompareObjectEqAndBranch* result = 10697528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org New<HCompareObjectEqAndBranch>(left, right); 106984f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org return result; 10699d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } else if (combined_type->Is(Type::String())) { 10700d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org BuildCheckHeapObject(left); 10701c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Add<HCheckInstanceType>(left, HCheckInstanceType::IS_STRING); 10702d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org BuildCheckHeapObject(right); 10703c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Add<HCheckInstanceType>(right, HCheckInstanceType::IS_STRING); 10704d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org HStringCompareAndBranch* result = 10705d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org New<HStringCompareAndBranch>(left, right, op); 107064f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org return result; 10707a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 10708fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (combined_rep.IsTagged() || combined_rep.IsNone()) { 107094f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org HCompareGeneric* result = Add<HCompareGeneric>(left, right, op); 10710ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org result->set_observed_input_representation(1, left_rep); 10711ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org result->set_observed_input_representation(2, right_rep); 107124f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org if (result->HasObservableSideEffects()) { 10713f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (push_sim_result == PUSH_BEFORE_SIMULATE) { 10714f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Push(result); 10715f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org AddSimulate(bailout_id, REMOVABLE_SIMULATE); 10716f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Drop(1); 10717f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 10718f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org AddSimulate(bailout_id, REMOVABLE_SIMULATE); 10719f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 107204f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org } 107214f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org // TODO(jkummerow): Can we make this more efficient? 107224f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org HBranch* branch = New<HBranch>(result); 107234f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org return branch; 107244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } else { 10725e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org HCompareNumericAndBranch* result = 10726528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org New<HCompareNumericAndBranch>(left, right, op); 10727fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org result->set_observed_input_representation(left_rep, right_rep); 10728f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (FLAG_hydrogen_track_positions) { 107294f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org result->SetOperandPositions(zone(), left_position, right_position); 10730af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org } 107314f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org return result; 107324f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 10733a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 10734a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 10735a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 10736a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 10737a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, 1073896a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org Expression* sub_expr, 10739a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org NilValue nil) { 10740160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 10741160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 10742160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 1074341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); 10744f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 1074596a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org CHECK_ALIVE(VisitForValue(sub_expr)); 1074696a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org HValue* value = Pop(); 10747837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org if (expr->op() == Token::EQ_STRICT) { 10748ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org HConstant* nil_constant = nil == kNullValue 10749ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org ? graph()->GetConstantNull() 10750ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org : graph()->GetConstantUndefined(); 10751ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org HCompareObjectEqAndBranch* instr = 10752ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org New<HCompareObjectEqAndBranch>(value, nil_constant); 10753ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org return ast_context()->ReturnControl(instr, expr->id()); 10754ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org } else { 10755ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org ASSERT_EQ(Token::EQ, expr->op()); 107566d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Type* type = expr->combined_type()->Is(Type::None()) 107576d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org ? Type::Any(zone()) : expr->combined_type(); 10758ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org HIfContinuation continuation; 1075971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org BuildCompareNil(value, type, &continuation); 10760837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org return ast_context()->ReturnContinuation(&continuation, expr->id()); 10761ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 10762a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 10763a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 10764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 10765a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildThisFunction() { 107665a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // If we share optimized code between different closures, the 107675a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // this-function is not a constant, except inside an inlined body. 107685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org if (function_state()->outer() != NULL) { 10769d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return New<HConstant>( 10770b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org function_state()->compilation_info()->closure()); 107715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } else { 10772db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org return New<HThisFunction>(); 107735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org } 107745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org} 107755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 107765a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 10777e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildFastLiteral( 10778b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Handle<JSObject> boilerplate_object, 1077937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org AllocationSiteUsageContext* site_context) { 10780e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org NoObservableSideEffectsScope no_effects(this); 107814844ec2010ae872691d16199d0a685870c04bd9bhpayer@chromium.org InstanceType instance_type = boilerplate_object->map()->instance_type(); 107824844ec2010ae872691d16199d0a685870c04bd9bhpayer@chromium.org ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); 10783fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org 107844844ec2010ae872691d16199d0a685870c04bd9bhpayer@chromium.org HType type = instance_type == JS_ARRAY_TYPE 107854844ec2010ae872691d16199d0a685870c04bd9bhpayer@chromium.org ? HType::JSArray() : HType::JSObject(); 10786fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org HValue* object_size_constant = Add<HConstant>( 10787fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org boilerplate_object->map()->instance_size()); 10788c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org 10789d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org PretenureFlag pretenure_flag = NOT_TENURED; 10790c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org if (FLAG_allocation_site_pretenuring) { 10791034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org pretenure_flag = site_context->current()->GetPretenureMode(); 107924ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org Handle<AllocationSite> site(site_context->current()); 107934ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org AllocationSite::AddDependentCompilationInfo( 107944ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org site, AllocationSite::TENURING, top_info()); 10795c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org } 10796c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org 107974844ec2010ae872691d16199d0a685870c04bd9bhpayer@chromium.org HInstruction* object = Add<HAllocate>(object_size_constant, type, 107989f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org pretenure_flag, instance_type, site_context->current()); 10799dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 108007a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org // If allocation folding reaches Page::kMaxRegularHeapObjectSize the 108017a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org // elements array may not get folded into the object. Hence, we set the 108027a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org // elements pointer to empty fixed array and let store elimination remove 108037a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org // this store in the folding case. 108047a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org HConstant* empty_fixed_array = Add<HConstant>( 108057a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org isolate()->factory()->empty_fixed_array()); 108067a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 1080738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org empty_fixed_array); 108087a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org 10809dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org BuildEmitObjectHeader(boilerplate_object, object); 10810dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 10811fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org Handle<FixedArrayBase> elements(boilerplate_object->elements()); 10812e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int elements_size = (elements->length() > 0 && 10813e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org elements->map() != isolate()->heap()->fixed_cow_array_map()) ? 10814e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org elements->Size() : 0; 10815e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 108162904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org if (pretenure_flag == TENURED && 108172904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org elements->map() == isolate()->heap()->fixed_cow_array_map() && 108182904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org isolate()->heap()->InNewSpace(*elements)) { 108192904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org // If we would like to pretenure a fixed cow array, we must ensure that the 108202904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org // array is already in old space, otherwise we'll create too many old-to- 108212904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org // new-space pointers (overflowing the store buffer). 108222904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org elements = Handle<FixedArrayBase>( 108232904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org isolate()->factory()->CopyAndTenureFixedCOWArray( 108242904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org Handle<FixedArray>::cast(elements))); 108252904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org boilerplate_object->set_elements(*elements); 108262904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org } 108272904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org 10828dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org HInstruction* object_elements = NULL; 10829dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org if (elements_size > 0) { 10830dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org HValue* object_elements_size = Add<HConstant>(elements_size); 108316a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org InstanceType instance_type = boilerplate_object->HasFastDoubleElements() 108326a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org ? FIXED_DOUBLE_ARRAY_TYPE : FIXED_ARRAY_TYPE; 108336a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org object_elements = Add<HAllocate>( 10834eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org object_elements_size, HType::HeapObject(), 108356a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org pretenure_flag, instance_type, site_context->current()); 108361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 10837dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org BuildInitElementsInObjectHeader(boilerplate_object, object, object_elements); 10838dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 10839c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org // Copy object elements if non-COW. 10840c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org if (object_elements != NULL) { 10841b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org BuildEmitElements(boilerplate_object, elements, object_elements, 10842b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org site_context); 10843c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org } 10844e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 10845e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Copy in-object properties. 108461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (boilerplate_object->map()->NumberOfFields() != 0) { 10847c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org BuildEmitInObjectProperties(boilerplate_object, object, site_context, 10848c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org pretenure_flag); 10849c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org } 10850dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org return object; 10851c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org} 10852c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 10853c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 10854dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid HOptimizedGraphBuilder::BuildEmitObjectHeader( 10855c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Handle<JSObject> boilerplate_object, 10856dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org HInstruction* object) { 10857c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org ASSERT(boilerplate_object->properties()->length() == 0); 10858c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 10859c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Handle<Map> boilerplate_object_map(boilerplate_object->map()); 10860dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org AddStoreMapConstant(object, boilerplate_object_map); 10861c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 10862c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Handle<Object> properties_field = 10863c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Handle<Object>(boilerplate_object->properties(), isolate()); 10864c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); 108651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* properties = Add<HConstant>(properties_field); 10866c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org HObjectAccess access = HObjectAccess::ForPropertiesPointer(); 108670a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HStoreNamedField>(object, access, properties); 10868c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 10869c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org if (boilerplate_object->IsJSArray()) { 10870c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Handle<JSArray> boilerplate_array = 10871c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Handle<JSArray>::cast(boilerplate_object); 10872c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Handle<Object> length_field = 10873c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Handle<Object>(boilerplate_array->length(), isolate()); 108741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* length = Add<HConstant>(length_field); 1087557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 10876c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org ASSERT(boilerplate_array->length()->IsSmi()); 10877dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength( 108780a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org boilerplate_array->GetElementsKind()), length); 10879c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org } 10880dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org} 10881c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 10882dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 10883dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid HOptimizedGraphBuilder::BuildInitElementsInObjectHeader( 10884dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org Handle<JSObject> boilerplate_object, 10885dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org HInstruction* object, 10886dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org HInstruction* object_elements) { 10887dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org ASSERT(boilerplate_object->properties()->length() == 0); 10888dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org if (object_elements == NULL) { 10889dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org Handle<Object> elements_field = 10890dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org Handle<Object>(boilerplate_object->elements(), isolate()); 10891dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org object_elements = Add<HConstant>(elements_field); 10892dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org } 10893dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 108940a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org object_elements); 10895c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org} 10896c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 10897c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 10898c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgvoid HOptimizedGraphBuilder::BuildEmitInObjectProperties( 10899c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Handle<JSObject> boilerplate_object, 10900b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org HInstruction* object, 10901c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org AllocationSiteUsageContext* site_context, 10902c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org PretenureFlag pretenure_flag) { 109030a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Handle<Map> boilerplate_map(boilerplate_object->map()); 109040a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Handle<DescriptorArray> descriptors(boilerplate_map->instance_descriptors()); 109050a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org int limit = boilerplate_map->NumberOfOwnDescriptors(); 1090657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 109074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org int copied_fields = 0; 1090857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org for (int i = 0; i < limit; i++) { 1090957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org PropertyDetails details = descriptors->GetDetails(i); 1091057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (details.type() != FIELD) continue; 109114e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org copied_fields++; 1091257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org int index = descriptors->GetFieldIndex(i); 1091357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); 1091457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Handle<Name> name(descriptors->GetKey(i)); 10915e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Handle<Object> value = 1091657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Handle<Object>(boilerplate_object->InObjectPropertyAt(index), 10917e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org isolate()); 10918a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 10919a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org // The access for the store depends on the type of the boilerplate. 10920a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org HObjectAccess access = boilerplate_object->IsJSArray() ? 10921a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org HObjectAccess::ForJSArrayOffset(property_offset) : 109220a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset); 10923a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 10924e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (value->IsJSObject()) { 10925e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Handle<JSObject> value_object = Handle<JSObject>::cast(value); 10926b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Handle<AllocationSite> current_site = site_context->EnterNewScope(); 10927b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org HInstruction* result = 10928b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org BuildFastLiteral(value_object, site_context); 10929b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org site_context->ExitScope(current_site, value_object); 109300a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HStoreNamedField>(object, access, result); 10931e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 1093257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Representation representation = details.representation(); 1093371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org HInstruction* value_instruction; 10934a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 1093557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (representation.IsDouble()) { 10936a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org // Allocate a HeapNumber box and store the value into it. 10937dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize); 10938c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org // This heap number alloc does not have a corresponding 10939b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org // AllocationSite. That is okay because 10940b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org // 1) it's a child object of another object with a valid allocation site 10941b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org // 2) we can just use the mode of the parent object for pretenuring 10942dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org HInstruction* double_box = 1094370ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org Add<HAllocate>(heap_number_constant, HType::HeapObject(), 10944c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org pretenure_flag, HEAP_NUMBER_TYPE); 10945a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org AddStoreMapConstant(double_box, 10946a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org isolate()->factory()->heap_number_map()); 10947d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(), 109480a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HConstant>(value)); 1094957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org value_instruction = double_box; 10950f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else if (representation.IsSmi()) { 10951f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org value_instruction = value->IsUninitialized() 10952f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ? graph()->GetConstant0() 10953f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org : Add<HConstant>(value); 10954f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Ensure that value is stored as smi. 10955f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org access = access.WithRepresentation(representation); 1095671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org } else { 1095771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org value_instruction = Add<HConstant>(value); 1095857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 10959a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 109600a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HStoreNamedField>(object, access, value_instruction); 10961e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 10962e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 10963e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 109644e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org int inobject_properties = boilerplate_object->map()->inobject_properties(); 109651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* value_instruction = 109661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); 109674e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org for (int i = copied_fields; i < inobject_properties; i++) { 1096856f4c2e9e396d74e916f0b3e0612bc0cbd29a281jkummerow@chromium.org ASSERT(boilerplate_object->IsJSObject()); 1096956f4c2e9e396d74e916f0b3e0612bc0cbd29a281jkummerow@chromium.org int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); 109700a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HObjectAccess access = 109710a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset); 109720a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HStoreNamedField>(object, access, value_instruction); 109734e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } 10974e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 10975e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 10976e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 10977c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgvoid HOptimizedGraphBuilder::BuildEmitElements( 10978dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org Handle<JSObject> boilerplate_object, 10979c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Handle<FixedArrayBase> elements, 10980b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org HValue* object_elements, 1098137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org AllocationSiteUsageContext* site_context) { 10982dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org ElementsKind kind = boilerplate_object->map()->elements_kind(); 10983c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org int elements_length = elements->length(); 109841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HValue* object_elements_length = Add<HConstant>(elements_length); 10985c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org BuildInitializeElementsHeader(object_elements, kind, object_elements_length); 10986c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 10987c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org // Copy elements backing store content. 10988c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org if (elements->IsFixedDoubleArray()) { 10989c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org BuildEmitFixedDoubleArray(elements, kind, object_elements); 10990c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org } else if (elements->IsFixedArray()) { 10991b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org BuildEmitFixedArray(elements, kind, object_elements, 10992b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org site_context); 10993e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 10994c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org UNREACHABLE(); 10995e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 10996c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org} 10997e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 10998a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 10999c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgvoid HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( 11000c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Handle<FixedArrayBase> elements, 11001c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org ElementsKind kind, 11002c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org HValue* object_elements) { 110031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* boilerplate_elements = Add<HConstant>(elements); 11004c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org int elements_length = elements->length(); 11005c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org for (int i = 0; i < elements_length; i++) { 110061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HValue* key_constant = Add<HConstant>(i); 11007c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org HInstruction* value_instruction = 110081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Add<HLoadKeyed>(boilerplate_elements, key_constant, 110091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org static_cast<HValue*>(NULL), kind, 110101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ALLOW_RETURN_HOLE); 110111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, 110120a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org value_instruction, kind); 11013b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org store->SetFlag(HValue::kAllowUndefinedAsNaN); 11014c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org } 11015c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org} 11016c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 11017c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org 11018c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgvoid HOptimizedGraphBuilder::BuildEmitFixedArray( 11019c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Handle<FixedArrayBase> elements, 11020c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org ElementsKind kind, 11021b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org HValue* object_elements, 1102237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org AllocationSiteUsageContext* site_context) { 110231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* boilerplate_elements = Add<HConstant>(elements); 11024c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org int elements_length = elements->length(); 11025c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); 11026c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org for (int i = 0; i < elements_length; i++) { 11027c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Handle<Object> value(fast_elements->get(i), isolate()); 110281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HValue* key_constant = Add<HConstant>(i); 11029c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org if (value->IsJSObject()) { 11030c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org Handle<JSObject> value_object = Handle<JSObject>::cast(value); 11031b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Handle<AllocationSite> current_site = site_context->EnterNewScope(); 11032b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org HInstruction* result = 11033b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org BuildFastLiteral(value_object, site_context); 11034b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org site_context->ExitScope(current_site, value_object); 110350a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HStoreKeyed>(object_elements, key_constant, result, kind); 11036c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org } else { 11037c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org HInstruction* value_instruction = 110381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Add<HLoadKeyed>(boilerplate_elements, key_constant, 110391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org static_cast<HValue*>(NULL), kind, 110401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ALLOW_RETURN_HOLE); 110410a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); 11042c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org } 11043e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 11044e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 11045e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 11046e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 11047a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { 11048160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(!HasStackOverflow()); 11049160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block() != NULL); 11050160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(current_block()->HasPredecessor()); 110515a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org HInstruction* instr = BuildThisFunction(); 110525a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org return ast_context()->ReturnInstruction(instr, expr->id()); 11053a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11054a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11055a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11056a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitDeclarations( 11057a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ZoneList<Declaration*>* declarations) { 11058ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com ASSERT(globals_.is_empty()); 11059ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com AstVisitor::VisitDeclarations(declarations); 11060ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if (!globals_.is_empty()) { 1106156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org Handle<FixedArray> array = 11062ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com isolate()->factory()->NewFixedArray(globals_.length(), TENURED); 11063ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); 1106441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) | 1106541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org DeclareGlobalsNativeFlag::encode(current_info()->is_native()) | 11066486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org DeclareGlobalsStrictMode::encode(current_info()->strict_mode()); 11067d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Add<HDeclareGlobals>(array, flags); 11068e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org globals_.Rewind(0); 1106956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org } 110701805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org} 110711805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 110721805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 11073a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitVariableDeclaration( 11074a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org VariableDeclaration* declaration) { 11075ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VariableProxy* proxy = declaration->proxy(); 11076ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VariableMode mode = declaration->mode(); 11077ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Variable* variable = proxy->var(); 11078486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY; 11079ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com switch (variable->location()) { 11080486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::UNALLOCATED: 110817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org globals_.Add(variable->name(), zone()); 11082ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com globals_.Add(variable->binding_needs_init() 11083ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com ? isolate()->factory()->the_hole_value() 110847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org : isolate()->factory()->undefined_value(), zone()); 1108556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org return; 11086486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::PARAMETER: 11087486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::LOCAL: 11088ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if (hole_init) { 11089ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com HValue* value = graph()->GetConstantHole(); 11090ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com environment()->Bind(variable, value); 11091ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 11092ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com break; 11093486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::CONTEXT: 11094ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if (hole_init) { 11095ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com HValue* value = graph()->GetConstantHole(); 11096d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HValue* context = environment()->context(); 110971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HStoreContextSlot* store = Add<HStoreContextSlot>( 11098ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com context, variable->index(), HStoreContextSlot::kNoCheck, value); 11099fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (store->HasObservableSideEffects()) { 11100c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); 11101fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 111021805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org } 111031805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org break; 11104486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::LOOKUP: 11105594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kUnsupportedLookupSlotInDeclaration); 11106d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } 11107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11108a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11110a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitFunctionDeclaration( 11111a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org FunctionDeclaration* declaration) { 11112ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VariableProxy* proxy = declaration->proxy(); 11113ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Variable* variable = proxy->var(); 11114ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com switch (variable->location()) { 11115ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com case Variable::UNALLOCATED: { 111167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org globals_.Add(variable->name(), zone()); 1111741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<SharedFunctionInfo> function = Compiler::BuildFunctionInfo( 1111841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org declaration->fun(), current_info()->script()); 11119ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // Check for stack-overflow exception. 11120ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if (function.is_null()) return SetStackOverflow(); 111217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org globals_.Add(function, zone()); 11122ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com return; 11123ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 11124ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com case Variable::PARAMETER: 11125ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com case Variable::LOCAL: { 11126ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CHECK_ALIVE(VisitForValue(declaration->fun())); 11127ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com HValue* value = Pop(); 11128d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org BindIfLive(variable, value); 11129ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com break; 11130ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 11131ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com case Variable::CONTEXT: { 11132ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com CHECK_ALIVE(VisitForValue(declaration->fun())); 11133ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com HValue* value = Pop(); 11134d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HValue* context = environment()->context(); 111351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HStoreContextSlot* store = Add<HStoreContextSlot>( 11136ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com context, variable->index(), HStoreContextSlot::kNoCheck, value); 11137fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (store->HasObservableSideEffects()) { 11138c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); 11139fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 11140ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com break; 11141ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 11142ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com case Variable::LOOKUP: 11143594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kUnsupportedLookupSlotInDeclaration); 11144ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 11145812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org} 11146812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 11147812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 11148a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitModuleDeclaration( 11149a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ModuleDeclaration* declaration) { 11150812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org UNREACHABLE(); 11151812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org} 11152812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 11153812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 11154a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitImportDeclaration( 11155a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ImportDeclaration* declaration) { 11156812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org UNREACHABLE(); 11157812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org} 11158812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 11159812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 11160a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitExportDeclaration( 11161a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ExportDeclaration* declaration) { 11162812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org UNREACHABLE(); 1116378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org} 1116478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 1116578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 11166a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitModuleLiteral(ModuleLiteral* module) { 11167ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com UNREACHABLE(); 1116878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org} 1116978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 1117078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 11171a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitModuleVariable(ModuleVariable* module) { 11172ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com UNREACHABLE(); 1117378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org} 1117478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 1117578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 11176a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitModulePath(ModulePath* module) { 11177ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com UNREACHABLE(); 1117878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org} 1117978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 1118078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 11181a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitModuleUrl(ModuleUrl* module) { 11182ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com UNREACHABLE(); 1118378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org} 1118478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 1118578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 11186a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitModuleStatement(ModuleStatement* stmt) { 111878e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org UNREACHABLE(); 111888e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org} 111898e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 111908e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 11191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Generators for inline runtime functions. 11192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Support for types. 11193a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsSmi(CallRuntime* call) { 111943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(call->arguments()->length() == 1); 11195160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11196a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* value = Pop(); 11197528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org HIsSmiAndBranch* result = New<HIsSmiAndBranch>(value); 111984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnControl(result, call->id()); 11199a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11200a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11201a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11202a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsSpecObject(CallRuntime* call) { 112033a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(call->arguments()->length() == 1); 11204160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* value = Pop(); 112064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HHasInstanceTypeAndBranch* result = 11207dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org New<HHasInstanceTypeAndBranch>(value, 11208dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org FIRST_SPEC_OBJECT_TYPE, 11209dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org LAST_SPEC_OBJECT_TYPE); 112104f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnControl(result, call->id()); 11211a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11214a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsFunction(CallRuntime* call) { 112153a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(call->arguments()->length() == 1); 11216160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11217a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* value = Pop(); 112184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HHasInstanceTypeAndBranch* result = 11219dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org New<HHasInstanceTypeAndBranch>(value, JS_FUNCTION_TYPE); 112204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnControl(result, call->id()); 11221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11222a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 112240cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsMinusZero(CallRuntime* call) { 112250cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org ASSERT(call->arguments()->length() == 1); 112260cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 112270cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org HValue* value = Pop(); 112280cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org HCompareMinusZeroAndBranch* result = New<HCompareMinusZeroAndBranch>(value); 112290cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org return ast_context()->ReturnControl(result, call->id()); 112300cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org} 112310cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 112320cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 11233a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) { 112343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(call->arguments()->length() == 1); 11235160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* value = Pop(); 112374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HHasCachedArrayIndexAndBranch* result = 11238db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org New<HHasCachedArrayIndexAndBranch>(value); 112394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnControl(result, call->id()); 11240a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11241a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11242a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11243a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsArray(CallRuntime* call) { 112443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(call->arguments()->length() == 1); 11245160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* value = Pop(); 112474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HHasInstanceTypeAndBranch* result = 11248dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org New<HHasInstanceTypeAndBranch>(value, JS_ARRAY_TYPE); 112494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnControl(result, call->id()); 11250a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11251a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11253a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsRegExp(CallRuntime* call) { 112543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(call->arguments()->length() == 1); 11255160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11256a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* value = Pop(); 112574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HHasInstanceTypeAndBranch* result = 11258dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org New<HHasInstanceTypeAndBranch>(value, JS_REGEXP_TYPE); 112594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnControl(result, call->id()); 11260a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11261a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11263a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsObject(CallRuntime* call) { 112643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(call->arguments()->length() == 1); 11265160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 112665f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org HValue* value = Pop(); 11267528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org HIsObjectAndBranch* result = New<HIsObjectAndBranch>(value); 112684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnControl(result, call->id()); 11269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11272a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) { 11273594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kInlinedRuntimeFunctionIsNonNegativeSmi); 11274a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11275a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11276a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11277a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) { 112787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ASSERT(call->arguments()->length() == 1); 112797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 112807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org HValue* value = Pop(); 11281528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org HIsUndetectableAndBranch* result = New<HIsUndetectableAndBranch>(value); 112824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnControl(result, call->id()); 11283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11286a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( 112873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org CallRuntime* call) { 11288594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kInlinedRuntimeFunctionIsStringWrapperSafeForDefaultValueOf); 11289a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11290a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11292d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com// Support for construct call checks. 11293a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsConstructCall(CallRuntime* call) { 112943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(call->arguments()->length() == 0); 11295c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (function_state()->outer() != NULL) { 11296967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org // We are generating graph for inlined function. 11297471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org HValue* value = function_state()->inlining_kind() == CONSTRUCT_CALL_RETURN 11298967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org ? graph()->GetConstantTrue() 11299967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org : graph()->GetConstantFalse(); 11300967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org return ast_context()->ReturnValue(value); 11301c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } else { 11302db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org return ast_context()->ReturnControl(New<HIsConstructCallAndBranch>(), 113034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org call->id()); 11304c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } 11305a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11306a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11308a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Support for arguments.length and arguments[?]. 11309a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { 11310c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org // Our implementation of arguments (based on this stack frame or an 11311c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org // adapter below it) does not work for inlined functions. This runtime 11312c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org // function is blacklisted by AstNode::IsInlineable. 11313c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org ASSERT(function_state()->outer() == NULL); 113143a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(call->arguments()->length() == 0); 113151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* elements = Add<HArgumentsElements>(false); 11316d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HArgumentsLength* result = New<HArgumentsLength>(elements); 113174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 11318a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11319a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11320a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11321a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { 11322c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org // Our implementation of arguments (based on this stack frame or an 11323c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org // adapter below it) does not work for inlined functions. This runtime 11324c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org // function is blacklisted by AstNode::IsInlineable. 11325c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org ASSERT(function_state()->outer() == NULL); 113263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(call->arguments()->length() == 1); 11327160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11328a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* index = Pop(); 113291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* elements = Add<HArgumentsElements>(false); 113301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* length = Add<HArgumentsLength>(elements); 113311510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HInstruction* checked_index = Add<HBoundsCheck>(index, length); 11332db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HAccessArgumentsAt* result = New<HAccessArgumentsAt>( 11333db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org elements, length, checked_index); 113344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 11335a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11336a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11337a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11338a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Support for accessing the class and value fields of an object. 11339a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { 11340a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // The special form detected by IsClassOfTest is detected before we get here 11341a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // and does not cause a bailout. 11342594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kInlinedRuntimeFunctionClassOf); 11343a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11344a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11345a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11346a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateValueOf(CallRuntime* call) { 113473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(call->arguments()->length() == 1); 11348160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 1134909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* object = Pop(); 1135009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org 1135109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org IfBuilder if_objectisvalue(this); 1135209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* objectisvalue = if_objectisvalue.If<HHasInstanceTypeAndBranch>( 1135309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org object, JS_VALUE_TYPE); 1135409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org if_objectisvalue.Then(); 1135509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org { 1135609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org // Return the actual value. 1135709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org Push(Add<HLoadNamedField>( 1135809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org object, objectisvalue, 113590a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HObjectAccess::ForObservableJSObjectOffset( 113600a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org JSValue::kValueOffset))); 1136109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org Add<HSimulate>(call->id(), FIXED_SIMULATE); 1136209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org } 1136309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org if_objectisvalue.Else(); 1136409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org { 1136509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org // If the object is not a value return the object. 1136609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org Push(object); 1136709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org Add<HSimulate>(call->id(), FIXED_SIMULATE); 1136809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org } 1136909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org if_objectisvalue.End(); 1137009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org return ast_context()->ReturnValue(Pop()); 11371a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11372a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11373a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11374a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateDateField(CallRuntime* call) { 113754efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org ASSERT(call->arguments()->length() == 2); 113764efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org ASSERT_NE(NULL, call->arguments()->at(1)->AsLiteral()); 113771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Smi* index = Smi::cast(*(call->arguments()->at(1)->AsLiteral()->value())); 113784efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 113794efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org HValue* date = Pop(); 11380db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HDateField* result = New<HDateField>(date, index); 113814efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 113824efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org} 113834efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 113844efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 11385a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateOneByteSeqStringSetChar( 1138632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org CallRuntime* call) { 1138732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org ASSERT(call->arguments()->length() == 3); 11388f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // We need to follow the evaluation order of full codegen. 1138932280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 1139032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 11391f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11392f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HValue* string = Pop(); 1139332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org HValue* value = Pop(); 1139432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org HValue* index = Pop(); 113959af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Add<HSeqStringSetChar>(String::ONE_BYTE_ENCODING, string, 113969af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org index, value); 113979af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Add<HSimulate>(call->id(), FIXED_SIMULATE); 113989af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 1139932280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org} 1140032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 1140132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 11402a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateTwoByteSeqStringSetChar( 1140332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org CallRuntime* call) { 1140432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org ASSERT(call->arguments()->length() == 3); 11405f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // We need to follow the evaluation order of full codegen. 1140632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 1140732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 11408f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11409f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org HValue* string = Pop(); 1141032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org HValue* value = Pop(); 1141132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org HValue* index = Pop(); 114129af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Add<HSeqStringSetChar>(String::TWO_BYTE_ENCODING, string, 114139af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org index, value); 114149af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Add<HSimulate>(call->id(), FIXED_SIMULATE); 114159af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 1141632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org} 1141732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 1141832280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 11419a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) { 114202c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org ASSERT(call->arguments()->length() == 2); 114212c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 114222c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 114232c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org HValue* value = Pop(); 114242c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org HValue* object = Pop(); 114252c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 114262c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org // Check if object is a JSValue. 1142709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org IfBuilder if_objectisvalue(this); 1142809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org if_objectisvalue.If<HHasInstanceTypeAndBranch>(object, JS_VALUE_TYPE); 1142909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org if_objectisvalue.Then(); 1143009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org { 1143109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org // Create in-object property store to kValueOffset. 114320a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org Add<HStoreNamedField>(object, 114330a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org HObjectAccess::ForObservableJSObjectOffset(JSValue::kValueOffset), 114340a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org value); 11435f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!ast_context()->IsEffect()) { 11436f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Push(value); 11437f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 1143809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org Add<HSimulate>(call->id(), FIXED_SIMULATE); 1143909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org } 1144009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org if_objectisvalue.Else(); 1144109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org { 1144209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org // Nothing to do in this case. 11443f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!ast_context()->IsEffect()) { 11444f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Push(value); 11445f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 1144609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org Add<HSimulate>(call->id(), FIXED_SIMULATE); 1144709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org } 1144809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org if_objectisvalue.End(); 11449f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (!ast_context()->IsEffect()) { 11450f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Drop(1); 11451f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 114522c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org return ast_context()->ReturnValue(value); 11453a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11454a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11455a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11456a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast support for charCodeAt(n). 11457a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { 114583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(call->arguments()->length() == 2); 11459160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11460160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 114610a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org HValue* index = Pop(); 114620a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org HValue* string = Pop(); 11463d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HInstruction* result = BuildStringCharCodeAt(string, index); 114644f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 11465a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11466a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11467a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11468a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast support for string.charAt(n) and string[n]. 11469a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { 11470b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org ASSERT(call->arguments()->length() == 1); 11471160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11472b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org HValue* char_code = Pop(); 11473db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HInstruction* result = NewUncasted<HStringCharFromCode>(char_code); 114744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 11475a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11476a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11477a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11478a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast support for string.charAt(n) and string[n]. 11479a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) { 11480b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org ASSERT(call->arguments()->length() == 2); 11481160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11482160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11483b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org HValue* index = Pop(); 11484b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org HValue* string = Pop(); 11485d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HInstruction* char_code = BuildStringCharCodeAt(string, index); 11486b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org AddInstruction(char_code); 11487db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HInstruction* result = NewUncasted<HStringCharFromCode>(char_code); 114884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 11489a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11490a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11491a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11492a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast support for object equality testing. 11493a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) { 114943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(call->arguments()->length() == 2); 11495160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11496160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* right = Pop(); 11498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* left = Pop(); 114994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HCompareObjectEqAndBranch* result = 11500d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org New<HCompareObjectEqAndBranch>(left, right); 115014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnControl(result, call->id()); 11502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast support for StringAdd. 11506a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { 115073a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT_EQ(2, call->arguments()->length()); 11508ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11509ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11510ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HValue* right = Pop(); 11511ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HValue* left = Pop(); 115120f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HInstruction* result = NewUncasted<HStringAdd>(left, right); 115134f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 11514a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11515a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast support for SubString. 11518a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { 115193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT_EQ(3, call->arguments()->length()); 11520bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org CHECK_ALIVE(VisitExpressions(call->arguments())); 11521bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org PushArgumentsFromEnvironment(call->arguments()->length()); 115228e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org HCallStub* result = New<HCallStub>(CodeStub::SubString, 3); 115234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 11524a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11525a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11526a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast support for StringCompare. 11528a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) { 115293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT_EQ(2, call->arguments()->length()); 11530bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org CHECK_ALIVE(VisitExpressions(call->arguments())); 11531bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org PushArgumentsFromEnvironment(call->arguments()->length()); 115328e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org HCallStub* result = New<HCallStub>(CodeStub::StringCompare, 2); 115334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 11534a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11535a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11536a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11537a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Support for direct calls from JavaScript to native RegExp code. 11538a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { 115393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT_EQ(4, call->arguments()->length()); 11540bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org CHECK_ALIVE(VisitExpressions(call->arguments())); 11541bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org PushArgumentsFromEnvironment(call->arguments()->length()); 115428e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org HCallStub* result = New<HCallStub>(CodeStub::RegExpExec, 4); 115434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 11544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11545a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11546a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11547ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateDoubleLo(CallRuntime* call) { 11548ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org ASSERT_EQ(1, call->arguments()->length()); 11549ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11550ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org HValue* value = Pop(); 11551ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org HInstruction* result = NewUncasted<HDoubleBits>(value, HDoubleBits::LOW); 11552ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 11553ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org} 11554ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 11555ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 11556ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateDoubleHi(CallRuntime* call) { 11557ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org ASSERT_EQ(1, call->arguments()->length()); 11558ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11559ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org HValue* value = Pop(); 11560ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org HInstruction* result = NewUncasted<HDoubleBits>(value, HDoubleBits::HIGH); 11561ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 11562ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org} 11563ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 11564ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 11565ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateConstructDouble(CallRuntime* call) { 11566ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org ASSERT_EQ(2, call->arguments()->length()); 11567ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11568ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11569ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org HValue* lo = Pop(); 11570ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org HValue* hi = Pop(); 11571ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org HInstruction* result = NewUncasted<HConstructDouble>(hi, lo); 11572ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 11573ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org} 11574ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 11575ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org 11576a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Construct a RegExp exec result with two in-object properties. 11577a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { 115783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT_EQ(3, call->arguments()->length()); 1157909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 1158009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 1158109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 1158209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* input = Pop(); 1158309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* index = Pop(); 1158409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* length = Pop(); 1158509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org HValue* result = BuildRegExpConstructResult(length, index, input); 1158609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org return ast_context()->ReturnValue(result); 11587a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11588a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11589a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11590a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Support for fast native caches. 11591a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { 11592594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kInlinedRuntimeFunctionGetFromCache); 11593a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11594a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11595a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11596a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast support for number to string. 11597a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { 115983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT_EQ(1, call->arguments()->length()); 115993d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 116003d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org HValue* number = Pop(); 116016d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org HValue* result = BuildNumberToString(number, Type::Any(zone())); 116023d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org return ast_context()->ReturnValue(result); 11603a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11604a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11605a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11606a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast call for custom callbacks. 11607a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { 11608160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // 1 ~ The function to call is not itself an argument to the call. 11609160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org int arg_count = call->arguments()->length() - 1; 11610160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org ASSERT(arg_count >= 1); // There's always at least a receiver. 11611160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 11612bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org CHECK_ALIVE(VisitExpressions(call->arguments())); 11613bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // The function is the last argument 11614160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org HValue* function = Pop(); 11615bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org // Push the arguments to the stack 11616bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org PushArgumentsFromEnvironment(arg_count); 11617c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 1161825530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org IfBuilder if_is_jsfunction(this); 1161925530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org if_is_jsfunction.If<HHasInstanceTypeAndBranch>(function, JS_FUNCTION_TYPE); 11620c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 1162125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org if_is_jsfunction.Then(); 1162225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org { 1162325530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org HInstruction* invoke_result = 1162425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org Add<HInvokeFunction>(function, arg_count); 1162525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org if (!ast_context()->IsEffect()) { 1162625530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org Push(invoke_result); 1162725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org } 1162825530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org Add<HSimulate>(call->id(), FIXED_SIMULATE); 1162925530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org } 1163025530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org 1163125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org if_is_jsfunction.Else(); 1163225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org { 1163325530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org HInstruction* call_result = 1163425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org Add<HCallFunction>(function, arg_count); 1163525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org if (!ast_context()->IsEffect()) { 1163625530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org Push(call_result); 1163725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org } 1163825530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org Add<HSimulate>(call->id(), FIXED_SIMULATE); 1163925530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org } 1164025530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org if_is_jsfunction.End(); 1164125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org 1164225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org if (ast_context()->IsEffect()) { 1164325530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org // EffectContext::ReturnValue ignores the value, so we can just pass 1164425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org // 'undefined' (as we do not have the call result anymore). 1164525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 1164625530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org } else { 1164725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org return ast_context()->ReturnValue(Pop()); 1164825530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org } 11649a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11650a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11651a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11652a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast call to math functions. 11653a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) { 116543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT_EQ(2, call->arguments()->length()); 11655160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11656160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 116575f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org HValue* right = Pop(); 116585f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org HValue* left = Pop(); 11659db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HInstruction* result = NewUncasted<HPower>(left, right); 116604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 11661a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11662a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11663a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11664285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateMathLogRT(CallRuntime* call) { 116654f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org ASSERT(call->arguments()->length() == 1); 116664f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 116674f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org HValue* value = Pop(); 116684f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org HInstruction* result = NewUncasted<HUnaryMathOperation>(value, kMathLog); 116694f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 11670a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11671a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11672a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11673aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateMathSqrtRT(CallRuntime* call) { 11674e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(call->arguments()->length() == 1); 11675e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11676e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org HValue* value = Pop(); 11677f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org HInstruction* result = NewUncasted<HUnaryMathOperation>(value, kMathSqrt); 11678e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 11679a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11680a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11682a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) { 116833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(call->arguments()->length() == 1); 11684160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 1168549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org HValue* value = Pop(); 11686db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org HGetCachedArrayIndex* result = New<HGetCachedArrayIndex>(value); 116874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return ast_context()->ReturnInstruction(result, call->id()); 11688a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11689a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11690a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11691a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) { 11692594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kInlinedRuntimeFunctionFastAsciiArrayJoin); 11693a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11694a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11695a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11696ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// Support for generators. 116978a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.orgvoid HOptimizedGraphBuilder::GenerateGeneratorNext(CallRuntime* call) { 11698594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kInlinedRuntimeFunctionGeneratorNext); 11699ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 11700ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 11701ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 11702ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvoid HOptimizedGraphBuilder::GenerateGeneratorThrow(CallRuntime* call) { 11703594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Bailout(kInlinedRuntimeFunctionGeneratorThrow); 11704ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 11705ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 11706ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 1170793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.orgvoid HOptimizedGraphBuilder::GenerateDebugBreakInOptimizedCode( 1170893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org CallRuntime* call) { 11709db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org Add<HDebugBreak>(); 1171093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org return ast_context()->ReturnValue(graph()->GetConstant0()); 1171193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org} 1171293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org 1171393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org 11714f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateDebugCallbackSupportsStepping( 11715f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org CallRuntime* call) { 11716f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org ASSERT(call->arguments()->length() == 1); 11717f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org // Debugging is not supported in optimized code. 11718f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org return ast_context()->ReturnValue(graph()->GetConstantFalse()); 11719f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org} 11720f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org 11721f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org 11722a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#undef CHECK_BAILOUT 11723160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org#undef CHECK_ALIVE 11724a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11725a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11726a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHEnvironment::HEnvironment(HEnvironment* outer, 11727a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Scope* scope, 117287028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Handle<JSFunction> closure, 117297028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Zone* zone) 11730a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org : closure_(closure), 117317028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org values_(0, zone), 11732967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org frame_type_(JS_FUNCTION), 11733a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org parameter_count_(0), 1173483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org specials_count_(1), 11735a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org local_count_(0), 11736a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org outer_(outer), 1173756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org entry_(NULL), 11738a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org pop_count_(0), 11739a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org push_count_(0), 11740471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ast_id_(BailoutId::None()), 117417028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org zone_(zone) { 117421e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org Scope* declaration_scope = scope->DeclarationScope(); 117431e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org Initialize(declaration_scope->num_parameters() + 1, 117441e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org declaration_scope->num_stack_slots(), 0); 11745a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11746a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11747a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1174809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.orgHEnvironment::HEnvironment(Zone* zone, int parameter_count) 11749a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org : values_(0, zone), 11750a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org frame_type_(STUB), 1175109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org parameter_count_(parameter_count), 1175209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org specials_count_(1), 11753a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org local_count_(0), 11754a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org outer_(NULL), 11755a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org entry_(NULL), 11756a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org pop_count_(0), 11757a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org push_count_(0), 11758a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ast_id_(BailoutId::None()), 11759a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org zone_(zone) { 1176009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Initialize(parameter_count, 0, 0); 11761a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 11762a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 11763a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 117647028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgHEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) 117657028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org : values_(0, zone), 11766967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org frame_type_(JS_FUNCTION), 11767a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org parameter_count_(0), 1176894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org specials_count_(0), 11769a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org local_count_(0), 11770a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org outer_(NULL), 1177156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org entry_(NULL), 11772a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org pop_count_(0), 11773a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org push_count_(0), 117747028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ast_id_(other->ast_id()), 117757028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org zone_(zone) { 11776a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Initialize(other); 11777a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11778a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11779a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11780659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgHEnvironment::HEnvironment(HEnvironment* outer, 11781659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org Handle<JSFunction> closure, 11782967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org FrameType frame_type, 117837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org int arguments, 117847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Zone* zone) 11785659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org : closure_(closure), 117867028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org values_(arguments, zone), 11787967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org frame_type_(frame_type), 11788659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org parameter_count_(arguments), 11789b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org specials_count_(0), 11790659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org local_count_(0), 11791659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org outer_(outer), 1179256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org entry_(NULL), 11793659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org pop_count_(0), 11794659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org push_count_(0), 11795471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org ast_id_(BailoutId::None()), 117967028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org zone_(zone) { 11797659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org} 11798659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 11799659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 11800a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HEnvironment::Initialize(int parameter_count, 11801a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int local_count, 11802a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int stack_height) { 11803a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org parameter_count_ = parameter_count; 11804a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org local_count_ = local_count; 11805a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11806a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Avoid reallocating the temporaries' backing store on the first Push. 1180783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org int total = parameter_count + specials_count_ + local_count + stack_height; 118087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org values_.Initialize(total + 4, zone()); 118097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org for (int i = 0; i < total; ++i) values_.Add(NULL, zone()); 11810a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11811a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11812a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 118135d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid HEnvironment::Initialize(const HEnvironment* other) { 118145d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org closure_ = other->closure(); 118157028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org values_.AddAll(other->values_, zone()); 1181659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org assigned_variables_.Union(other->assigned_variables_, zone()); 11817967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org frame_type_ = other->frame_type_; 118185d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org parameter_count_ = other->parameter_count_; 118195d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org local_count_ = other->local_count_; 118205d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. 1182156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org entry_ = other->entry_; 118225d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org pop_count_ = other->pop_count_; 118235d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org push_count_ = other->push_count_; 1182494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org specials_count_ = other->specials_count_; 118255d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org ast_id_ = other->ast_id_; 118265d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 118275d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 118285d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 11829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { 11830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(!block->IsLoopHeader()); 11831a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(values_.length() == other->values_.length()); 11832a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11833a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int length = values_.length(); 11834a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < length; ++i) { 11835a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* value = values_[i]; 11836a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (value != NULL && value->IsPhi() && value->block() == block) { 11837a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // There is already a phi for the i'th value. 11838a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HPhi* phi = HPhi::cast(value); 11839a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Assert index is correct and that we haven't missed an incoming edge. 11840ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org ASSERT(phi->merged_index() == i || !phi->HasMergedIndex()); 11841a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(phi->OperandCount() == block->predecessors()->length()); 11842a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org phi->AddInput(other->values_[i]); 11843a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (values_[i] != other->values_[i]) { 11844a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // There is a fresh value on the incoming edge, a phi is needed. 11845a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(values_[i] != NULL && other->values_[i] != NULL); 11846ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org HPhi* phi = block->AddNewPhi(i); 11847a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* old_value = values_[i]; 11848a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int j = 0; j < block->predecessors()->length(); j++) { 11849a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org phi->AddInput(old_value); 11850a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 11851a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org phi->AddInput(other->values_[i]); 11852a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org this->values_[i] = phi; 11853a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 11854a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 11855a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11856a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11857a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 118585d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid HEnvironment::Bind(int index, HValue* value) { 118595d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org ASSERT(value != NULL); 1186059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org assigned_variables_.Add(index, zone()); 118615d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org values_[index] = value; 11862a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11863a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11864a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 118655d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgbool HEnvironment::HasExpressionAt(int index) const { 1186683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return index >= parameter_count_ + specials_count_ + local_count_; 118675d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 118685d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 118695d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 118705d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgbool HEnvironment::ExpressionStackIsEmpty() const { 11871be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org ASSERT(length() >= first_expression_index()); 11872be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org return length() == first_expression_index(); 118735d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 118745d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 118755d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 118765d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid HEnvironment::SetExpressionStackAt(int index_from_top, HValue* value) { 118775d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org int count = index_from_top + 1; 118785d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org int index = values_.length() - count; 118795d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org ASSERT(HasExpressionAt(index)); 118805d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // The push count must include at least the element in question or else 118815d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // the new value will not be included in this environment's history. 118825d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org if (push_count_ < count) { 118835d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // This is the same effect as popping then re-pushing 'count' elements. 118845d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org pop_count_ += (count - push_count_); 118855d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org push_count_ = count; 118865d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 118875d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org values_[index] = value; 118885d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 118895d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 118905d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 118915d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid HEnvironment::Drop(int count) { 118925d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org for (int i = 0; i < count; ++i) { 118935d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Pop(); 11894a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 11895a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11896a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11897a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11898a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHEnvironment* HEnvironment::Copy() const { 118997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org return new(zone()) HEnvironment(this, zone()); 11900a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11901a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11902a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11903a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHEnvironment* HEnvironment::CopyWithoutHistory() const { 11904a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HEnvironment* result = Copy(); 11905a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org result->ClearHistory(); 11906a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return result; 11907a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11908a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11909a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11910a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { 11911a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HEnvironment* new_env = Copy(); 11912a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < values_.length(); ++i) { 11913ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org HPhi* phi = loop_header->AddNewPhi(i); 11914a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org phi->AddInput(values_[i]); 11915a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org new_env->values_[i] = phi; 11916a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 11917a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org new_env->ClearHistory(); 11918a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return new_env; 11919a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11920a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11921a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11922967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgHEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, 11923967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org Handle<JSFunction> target, 11924967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org FrameType frame_type, 11925967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org int arguments) const { 119267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org HEnvironment* new_env = 119277028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org new(zone()) HEnvironment(outer, target, frame_type, 119287028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org arguments + 1, zone()); 11929967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org for (int i = 0; i <= arguments; ++i) { // Include receiver. 11930967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org new_env->Push(ExpressionStackAt(arguments - i)); 11931967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org } 11932967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org new_env->ClearHistory(); 11933967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org return new_env; 11934967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org} 11935967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 11936967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 1193740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgHEnvironment* HEnvironment::CopyForInlining( 1193840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Handle<JSFunction> target, 11939659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org int arguments, 1194040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org FunctionLiteral* function, 1194140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org HConstant* undefined, 11942e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org InliningKind inlining_kind) const { 11943967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org ASSERT(frame_type() == JS_FUNCTION); 11944659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 11945a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Outer environment is a copy of this one without the arguments. 11946a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int arity = function->scope()->num_parameters(); 11947659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 11948a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HEnvironment* outer = Copy(); 11949659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org outer->Drop(arguments + 1); // Including receiver. 11950a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org outer->ClearHistory(); 11951659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 11952471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (inlining_kind == CONSTRUCT_CALL_RETURN) { 11953967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org // Create artificial constructor stub environment. The receiver should 11954967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org // actually be the constructor function, but we pass the newly allocated 11955967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org // object instead, DoComputeConstructStubFrame() relies on that. 11956967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org outer = CreateStubEnvironment(outer, target, JS_CONSTRUCT, arguments); 11957de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } else if (inlining_kind == GETTER_CALL_RETURN) { 11958de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // We need an additional StackFrame::INTERNAL frame for restoring the 11959de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // correct context. 11960de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org outer = CreateStubEnvironment(outer, target, JS_GETTER, arguments); 11961471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else if (inlining_kind == SETTER_CALL_RETURN) { 11962471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // We need an additional StackFrame::INTERNAL frame for temporarily saving 11963471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org // the argument of the setter, see StoreStubCompiler::CompileStoreViaSetter. 11964471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org outer = CreateStubEnvironment(outer, target, JS_SETTER, arguments); 11965967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org } 11966967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 11967659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org if (arity != arguments) { 11968659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // Create artificial arguments adaptation environment. 11969967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org outer = CreateStubEnvironment(outer, target, ARGUMENTS_ADAPTOR, arguments); 11970659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 11971659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 1197274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org HEnvironment* inner = 119735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org new(zone()) HEnvironment(outer, function->scope(), target, zone()); 11974a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Get the argument values from the original environment. 119753cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org for (int i = 0; i <= arity; ++i) { // Include receiver. 11976659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org HValue* push = (i <= arguments) ? 11977659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org ExpressionStackAt(arguments - i) : undefined; 119783cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org inner->SetValueAt(i, push); 11979a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 11980d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org inner->SetValueAt(arity + 1, context()); 1198183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org for (int i = arity + 2; i < inner->length(); ++i) { 1198283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org inner->SetValueAt(i, undefined); 11983a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 11984a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11985471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org inner->set_ast_id(BailoutId::FunctionEntry()); 11986a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return inner; 11987a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 11988a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11989a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11990a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HEnvironment::PrintTo(StringStream* stream) { 119915d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org for (int i = 0; i < length(); i++) { 11992a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (i == 0) stream->Add("parameters\n"); 1199383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (i == parameter_count()) stream->Add("specials\n"); 1199483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (i == parameter_count() + specials_count()) stream->Add("locals\n"); 1199583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (i == parameter_count() + specials_count() + local_count()) { 11996659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org stream->Add("expressions\n"); 1199783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 11998a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HValue* val = values_.at(i); 11999a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org stream->Add("%d: ", i); 12000a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (val != NULL) { 12001a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org val->PrintNameTo(stream); 12002a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 12003a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org stream->Add("NULL"); 12004a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12005a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org stream->Add("\n"); 12006a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12007659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org PrintF("\n"); 12008a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 12009a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12010a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12011a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HEnvironment::PrintToStd() { 12012a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HeapStringAllocator string_allocator; 12013a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org StringStream trace(&string_allocator); 12014a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrintTo(&trace); 12015afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org PrintF("%s", trace.ToCString().get()); 12016a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 12017a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12018a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12019a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HTracer::TraceCompilation(CompilationInfo* info) { 12020a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Tag tag(this, "compilation"); 12021a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (info->IsOptimizing()) { 12022a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Handle<String> name = info->function()->debug_name(); 12023afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org PrintStringProperty("name", name->ToCString().get()); 12024f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PrintIndent(); 12025f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org trace_.Add("method \"%s:%d\"\n", 12026f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org name->ToCString().get(), 12027f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org info->optimization_id()); 12028a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 12029a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org CodeStub::Major major_key = info->code_stub()->MajorKey(); 12030a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org PrintStringProperty("name", CodeStub::MajorName(major_key, false)); 12031a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org PrintStringProperty("method", "stub"); 12032a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 12033a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis())); 12034a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 12035a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12036a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1203728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgvoid HTracer::TraceLithium(const char* name, LChunk* chunk) { 120389af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org ASSERT(!chunk->isolate()->concurrent_recompilation_enabled()); 120391fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org AllowHandleDereference allow_deref; 120401fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org AllowDeferredHandleDereference allow_deferred_deref; 12041a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Trace(name, chunk->graph(), chunk); 12042a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 12043a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12044a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12045a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HTracer::TraceHydrogen(const char* name, HGraph* graph) { 120469af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org ASSERT(!graph->isolate()->concurrent_recompilation_enabled()); 120471fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org AllowHandleDereference allow_deref; 120481fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org AllowDeferredHandleDereference allow_deferred_deref; 12049a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Trace(name, graph, NULL); 12050a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 12051a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12052a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1205328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgvoid HTracer::Trace(const char* name, HGraph* graph, LChunk* chunk) { 12054a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Tag tag(this, "cfg"); 12055a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrintStringProperty("name", name); 12056a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const ZoneList<HBasicBlock*>* blocks = graph->blocks(); 12057a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < blocks->length(); i++) { 12058a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HBasicBlock* current = blocks->at(i); 12059a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Tag block_tag(this, "block"); 12060a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrintBlockProperty("name", current->block_id()); 12061a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrintIntProperty("from_bci", -1); 12062a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrintIntProperty("to_bci", -1); 12063a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12064a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (!current->predecessors()->is_empty()) { 12065a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrintIndent(); 12066a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add("predecessors"); 12067a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int j = 0; j < current->predecessors()->length(); ++j) { 12068a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add(" \"B%d\"", current->predecessors()->at(j)->block_id()); 12069a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12070a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add("\n"); 12071a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 12072a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrintEmptyProperty("predecessors"); 12073a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12074a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 120756d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org if (current->end()->SuccessorCount() == 0) { 12076a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrintEmptyProperty("successors"); 120776d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org } else { 120786d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org PrintIndent(); 120796d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org trace_.Add("successors"); 120806d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org for (HSuccessorIterator it(current->end()); !it.Done(); it.Advance()) { 120816d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org trace_.Add(" \"B%d\"", it.Current()->block_id()); 120826d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org } 120836d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org trace_.Add("\n"); 12084a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12085a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12086a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrintEmptyProperty("xhandlers"); 120874ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org 120884ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org { 120894ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org PrintIndent(); 120904ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org trace_.Add("flags"); 120914ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org if (current->IsLoopSuccessorDominator()) { 120924ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org trace_.Add(" \"dom-loop-succ\""); 120934ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org } 120944ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org if (current->IsUnreachable()) { 120954ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org trace_.Add(" \"dead\""); 120964ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org } 120974ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org if (current->is_osr_entry()) { 120984ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org trace_.Add(" \"osr\""); 120994ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org } 121004ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org trace_.Add("\n"); 121014ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org } 12102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12103a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (current->dominator() != NULL) { 12104a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrintBlockProperty("dominator", current->dominator()->block_id()); 12105a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1210783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org PrintIntProperty("loop_depth", current->LoopNestingDepth()); 1210883e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org 12109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (chunk != NULL) { 12110a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int first_index = current->first_instruction_index(); 12111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int last_index = current->last_instruction_index(); 12112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrintIntProperty( 12113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "first_lir_id", 12114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LifetimePosition::FromInstructionIndex(first_index).Value()); 12115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrintIntProperty( 12116a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "last_lir_id", 12117a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LifetimePosition::FromInstructionIndex(last_index).Value()); 12118a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12120a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org { 12121a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Tag states_tag(this, "states"); 12122a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Tag locals_tag(this, "locals"); 12123a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int total = current->phis()->length(); 1212483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org PrintIntProperty("size", current->phis()->length()); 1212583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org PrintStringProperty("method", "None"); 12126a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int j = 0; j < total; ++j) { 12127a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HPhi* phi = current->phis()->at(j); 1212883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org PrintIndent(); 12129a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add("%d ", phi->merged_index()); 12130a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org phi->PrintNameTo(&trace_); 12131a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add(" "); 12132a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org phi->PrintTo(&trace_); 12133a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add("\n"); 12134a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12136a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12137a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org { 12138a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Tag HIR_tag(this, "HIR"); 1213993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org for (HInstructionIterator it(current); !it.Done(); it.Advance()) { 1214093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org HInstruction* instruction = it.Current(); 121413847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com int uses = instruction->UseCount(); 1214283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org PrintIndent(); 12143f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org trace_.Add("0 %d ", uses); 12144a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org instruction->PrintNameTo(&trace_); 12145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add(" "); 12146a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org instruction->PrintTo(&trace_); 12147f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (FLAG_hydrogen_track_positions && 12148f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org instruction->has_position() && 12149f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org instruction->position().raw() != 0) { 12150f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const HSourcePosition pos = instruction->position(); 12151f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org trace_.Add(" pos:"); 12152f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (pos.inlining_id() != 0) { 12153f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org trace_.Add("%d_", pos.inlining_id()); 12154f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 12155f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org trace_.Add("%d", pos.position()); 12156f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 12157a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add(" <|@\n"); 12158a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12159a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12160a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12161a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12162a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (chunk != NULL) { 12163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Tag LIR_tag(this, "LIR"); 12164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int first_index = current->first_instruction_index(); 12165a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int last_index = current->last_instruction_index(); 12166a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (first_index != -1 && last_index != -1) { 12167a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const ZoneList<LInstruction*>* instructions = chunk->instructions(); 12168a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = first_index; i <= last_index; ++i) { 12169a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LInstruction* linstr = instructions->at(i); 12170a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (linstr != NULL) { 1217183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org PrintIndent(); 12172a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add("%d ", 12173a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LifetimePosition::FromInstructionIndex(i).Value()); 12174a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org linstr->PrintTo(&trace_); 12175af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org trace_.Add(" [hir:"); 12176af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org linstr->hydrogen_value()->PrintNameTo(&trace_); 12177af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org trace_.Add("]"); 12178a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add(" <|@\n"); 12179a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12180a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12181a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12182a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12183a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12184a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 12185a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12186a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12187a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HTracer::TraceLiveRanges(const char* name, LAllocator* allocator) { 12188a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Tag tag(this, "intervals"); 12189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrintStringProperty("name", name); 12190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12191b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org const Vector<LiveRange*>* fixed_d = allocator->fixed_double_live_ranges(); 12192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < fixed_d->length(); ++i) { 121937028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org TraceLiveRange(fixed_d->at(i), "fixed", allocator->zone()); 12194a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12195a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12196b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org const Vector<LiveRange*>* fixed = allocator->fixed_live_ranges(); 12197a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < fixed->length(); ++i) { 121987028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org TraceLiveRange(fixed->at(i), "fixed", allocator->zone()); 12199a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12200a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12201a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const ZoneList<LiveRange*>* live_ranges = allocator->live_ranges(); 12202a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < live_ranges->length(); ++i) { 122037028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org TraceLiveRange(live_ranges->at(i), "object", allocator->zone()); 12204a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 12206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12207a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 122087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgvoid HTracer::TraceLiveRange(LiveRange* range, const char* type, 122097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Zone* zone) { 12210a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (range != NULL && !range->IsEmpty()) { 1221183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org PrintIndent(); 12212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add("%d %s", range->id(), type); 12213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (range->HasRegisterAssigned()) { 122147028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org LOperand* op = range->CreateAssignedOperand(zone); 12215a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int assigned_reg = op->index(); 12216a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (op->IsDoubleRegister()) { 12217a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add(" \"%s\"", 12218a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org DoubleRegister::AllocationIndexToString(assigned_reg)); 12219a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 12220a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(op->IsRegister()); 12221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg)); 12222a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (range->IsSpilled()) { 12224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LOperand* op = range->TopLevel()->GetSpillOperand(); 12225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (op->IsDoubleStackSlot()) { 12226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add(" \"double_stack:%d\"", op->index()); 12227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 12228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(op->IsStackSlot()); 12229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add(" \"stack:%d\"", op->index()); 12230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12232a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int parent_index = -1; 12233a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (range->IsChild()) { 12234a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org parent_index = range->parent()->id(); 12235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 12236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org parent_index = range->id(); 12237a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org LOperand* op = range->FirstHint(); 12239a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int hint_index = -1; 12240fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org if (op != NULL && op->IsUnallocated()) { 12241fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org hint_index = LUnallocated::cast(op)->virtual_register(); 12242fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org } 12243a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add(" %d %d", parent_index, hint_index); 12244a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org UseInterval* cur_interval = range->first_interval(); 122453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org while (cur_interval != NULL && range->Covers(cur_interval->start())) { 12246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add(" [%d, %d[", 12247a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org cur_interval->start().Value(), 12248a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org cur_interval->end().Value()); 12249a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org cur_interval = cur_interval->next(); 12250a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12251a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org UsePosition* current_pos = range->first_pos(); 12253a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org while (current_pos != NULL) { 122543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (current_pos->RegisterIsBeneficial() || FLAG_trace_all_uses) { 12255a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add(" %d M", current_pos->pos().Value()); 12256a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12257a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org current_pos = current_pos->next(); 12258a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12259a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12260a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Add(" \"\"\n"); 12261a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 12263a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12264a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12265a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HTracer::FlushToFile() { 12266afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org AppendChars(filename_.start(), trace_.ToCString().get(), trace_.length(), 12267afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org false); 12268a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org trace_.Reset(); 12269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 12270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12272b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.orgvoid HStatistics::Initialize(CompilationInfo* info) { 12273003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (info->shared_info().is_null()) return; 12274b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org source_size_ += info->shared_info()->SourceSize(); 12275b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org} 12276b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 12277b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 12278a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HStatistics::Print() { 12279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrintF("Timing results:\n"); 12280dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org TimeDelta sum; 12281dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org for (int i = 0; i < times_.length(); ++i) { 12282dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org sum += times_[i]; 12283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org for (int i = 0; i < names_.length(); ++i) { 122861510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org PrintF("%32s", names_[i]); 12287dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org double ms = times_[i].InMillisecondsF(); 12288dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org double percent = times_[i].PercentOf(sum); 122891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org PrintF(" %8.3f ms / %4.1f %% ", ms, percent); 12290c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org 12291c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org unsigned size = sizes_[i]; 12292c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org double size_percent = static_cast<double>(size) * 100 / total_size_; 12293068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org PrintF(" %9u bytes / %4.1f %%\n", size, size_percent); 12294a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 122958e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 12296068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org PrintF("----------------------------------------" 12297068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org "---------------------------------------\n"); 12298dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org TimeDelta total = create_graph_ + optimize_graph_ + generate_code_; 122991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org PrintF("%32s %8.3f ms / %4.1f %% \n", 123008e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org "Create graph", 12301dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org create_graph_.InMillisecondsF(), 12302dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org create_graph_.PercentOf(total)); 123031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org PrintF("%32s %8.3f ms / %4.1f %% \n", 123048e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org "Optimize graph", 12305dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org optimize_graph_.InMillisecondsF(), 12306dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org optimize_graph_.PercentOf(total)); 123071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org PrintF("%32s %8.3f ms / %4.1f %% \n", 123088e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org "Generate and install code", 12309dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org generate_code_.InMillisecondsF(), 12310dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org generate_code_.PercentOf(total)); 12311068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org PrintF("----------------------------------------" 12312068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org "---------------------------------------\n"); 123131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org PrintF("%32s %8.3f ms (%.1f times slower than full code gen)\n", 123148e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org "Total", 12315dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org total.InMillisecondsF(), 12316dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org total.TimesOf(full_code_gen_)); 123178e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 12318b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org double source_size_in_kb = static_cast<double>(source_size_) / 1024; 123197979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org double normalized_time = source_size_in_kb > 0 12320dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org ? total.InMillisecondsF() / source_size_in_kb 123217979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org : 0; 123228e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org double normalized_size_in_kb = source_size_in_kb > 0 123238e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org ? total_size_ / 1024 / source_size_in_kb 123247979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org : 0; 123251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org PrintF("%32s %8.3f ms %7.3f kB allocated\n", 123268e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org "Average per kB source", 123278e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org normalized_time, normalized_size_in_kb); 12328a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 12329a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12331dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid HStatistics::SaveTiming(const char* name, TimeDelta time, unsigned size) { 123321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org total_size_ += size; 123331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org for (int i = 0; i < names_.length(); ++i) { 123341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (strcmp(names_[i], name) == 0) { 12335dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org times_[i] += time; 123361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org sizes_[i] += size; 123371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return; 12338a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12339750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 123401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org names_.Add(name); 12341dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org times_.Add(time); 123421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org sizes_.Add(size); 12343a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 12344a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12345a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12346750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgHPhase::~HPhase() { 123471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (ShouldProduceTraceOutput()) { 123481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12349a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 12350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG 123521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org graph_->Verify(false); // No full verify. 12353a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif 12354a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 12355a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 12356a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} } // namespace v8::internal 12357