1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen.h" 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <algorithm> 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation-site-scopes.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/codegen.h" 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/full-codegen.h" 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hashmap.h" 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-bce.h" 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-bch.h" 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-canonicalize.h" 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-check-elimination.h" 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-dce.h" 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-dehoist.h" 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-environment-liveness.h" 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-escape-analysis.h" 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-gvn.h" 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-infer-representation.h" 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-infer-types.h" 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-load-elimination.h" 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-mark-deoptimize.h" 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-mark-unreachable.h" 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-osr.h" 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-range-analysis.h" 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-redundant-phi.h" 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-removable-simulates.h" 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-representation-changes.h" 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-sce.h" 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-store-elimination.h" 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-uint32-analysis.h" 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ic/call-optimization.h" 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ic/ic.h" 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// GetRootConstructor 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ic/ic-inl.h" 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/lithium-allocator.h" 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/parser.h" 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/runtime.h" 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/scopeinfo.h" 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/scopes.h" 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/typing.h" 47b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 48b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#if V8_TARGET_ARCH_IA32 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ia32/lithium-codegen-ia32.h" // NOLINT 50b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#elif V8_TARGET_ARCH_X64 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x64/lithium-codegen-x64.h" // NOLINT 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_ARM64 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/arm64/lithium-codegen-arm64.h" // NOLINT 54b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#elif V8_TARGET_ARCH_ARM 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/arm/lithium-codegen-arm.h" // NOLINT 5644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#elif V8_TARGET_ARCH_MIPS 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips/lithium-codegen-mips.h" // NOLINT 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_MIPS64 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips64/lithium-codegen-mips64.h" // NOLINT 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_X87 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x87/lithium-codegen-x87.h" // NOLINT 62b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#else 63b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#error Unsupported target architecture. 64b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 65b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 66b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 { 67b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal { 68b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 69b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHBasicBlock::HBasicBlock(HGraph* graph) 70b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : block_id_(graph->GetNextBlockID()), 71b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch graph_(graph), 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch phis_(4, graph->zone()), 73b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch first_(NULL), 74b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch last_(NULL), 75b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch end_(NULL), 76b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch loop_information_(NULL), 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch predecessors_(2, graph->zone()), 78b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch dominator_(NULL), 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dominated_blocks_(4, graph->zone()), 80b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch last_environment_(NULL), 81b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch argument_count_(-1), 82b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch first_instruction_index_(-1), 83b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch last_instruction_index_(-1), 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deleted_phis_(4, graph->zone()), 851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block parent_loop_header_(NULL), 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inlined_entry_block_(NULL), 873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch is_inline_return_target_(false), 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_reachable_(true), 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dominates_loop_successors_(false), 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_osr_entry_(false), 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_ordered_(false) { } 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochIsolate* HBasicBlock::isolate() const { 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return graph_->isolate(); 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HBasicBlock::MarkUnreachable() { 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_reachable_ = false; 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::AttachLoopInformation() { 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsLoopHeader()); 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_information_ = new(zone()) HLoopInformation(this, zone()); 107b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 108b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 109b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 110b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::DetachLoopInformation() { 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsLoopHeader()); 112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch loop_information_ = NULL; 113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::AddPhi(HPhi* phi) { 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsStartBlock()); 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch phis_.Add(phi, zone()); 119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phi->SetBlock(this); 120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::RemovePhi(HPhi* phi) { 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(phi->block() == this); 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(phis_.Contains(phi)); 1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch phi->Kill(); 127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phis_.RemoveElement(phi); 128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phi->SetBlock(NULL); 129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HBasicBlock::AddInstruction(HInstruction* instr, 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HSourcePosition position) { 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsStartBlock() || !IsFinished()); 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!instr->IsLinked()); 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsFinished()); 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!position.IsUnknown()) { 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->set_position(position); 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 141b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (first_ == NULL) { 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(last_environment() != NULL); 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!last_environment()->ast_id().IsNone()); 1448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HBlockEntry* entry = new(zone()) HBlockEntry(); 145b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch entry->InitializeAsFirst(this); 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!position.IsUnknown()) { 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry->set_position(position); 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!FLAG_hydrogen_track_positions || 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !graph()->info()->IsOptimizing()); 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 152e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch first_ = last_ = entry; 153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 154e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch instr->InsertAfter(last_); 155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHPhi* HBasicBlock::AddNewPhi(int merged_index) { 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (graph()->IsInsideNoSideEffectsScope()) { 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch merged_index = HPhi::kInvalidMergedIndex; 16144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhi* phi = new(zone()) HPhi(merged_index, zone()); 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddPhi(phi); 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return phi; 16544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 16644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 16744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id, 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RemovableSimulate removable) { 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(HasEnvironment()); 171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HEnvironment* environment = last_environment(); 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(ast_id.IsNone() || 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_id == BailoutId::StubEntry() || 1743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch environment->closure()->shared()->VerifyBailoutId(ast_id)); 175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int push_count = environment->push_count(); 177b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int pop_count = environment->pop_count(); 178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HSimulate* instr = 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new(zone()) HSimulate(ast_id, pop_count, zone(), removable); 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->set_closure(environment->closure()); 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Order of pushed values: newest (top of stack) first. This allows 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // HSimulate::MergeWith() to easily append additional pushed values 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // that are older (from further down the stack). 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < push_count; ++i) { 188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch instr->AddPushedValue(environment->ExpressionStackAt(i)); 189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (GrowableBitVector::Iterator it(environment->assigned_variables(), 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone()); 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !it.Done(); 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch it.Advance()) { 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = it.Current(); 195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch instr->AddAssignedValue(index, environment->Lookup(index)); 196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch environment->ClearHistory(); 198b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return instr; 199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 200b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 201b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HBasicBlock::Finish(HControlInstruction* end, HSourcePosition position) { 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsFinished()); 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(end, position); 205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch end_ = end; 2063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { 2073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch it.Current()->RegisterPredecessor(this); 208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HBasicBlock::Goto(HBasicBlock* block, 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HSourcePosition position, 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FunctionState* state, 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool add_simulate) { 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool drop_extra = state != NULL && 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch state->inlining_kind() == NORMAL_RETURN; 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 21944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (block->IsInlineReturnTarget()) { 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = last_environment(); 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = env->arguments_environment()->parameter_count(); 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(new(zone()) 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLeaveInlined(state->entry(), argument_count), 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch position); 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); 22644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (add_simulate) AddNewSimulate(BailoutId::None(), position); 2298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HGoto* instr = new(zone()) HGoto(block); 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Finish(instr, position); 231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid HBasicBlock::AddLeaveInlined(HValue* return_value, 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FunctionState* state, 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HSourcePosition position) { 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* target = state->function_return(); 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool drop_extra = state->inlining_kind() == NORMAL_RETURN; 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(target->IsInlineReturnTarget()); 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(return_value != NULL); 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = last_environment(); 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = env->arguments_environment()->parameter_count(); 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(new(zone()) HLeaveInlined(state->entry(), argument_count), 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch position); 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); 24744f0eee88ff00398ff7f715fab053374d808c90dSteve Block last_environment()->Push(return_value); 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddNewSimulate(BailoutId::None(), position); 2498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HGoto* instr = new(zone()) HGoto(target); 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Finish(instr, position); 25144f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 25244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 25344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::SetInitialEnvironment(HEnvironment* env) { 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasEnvironment()); 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(first() == NULL); 257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UpdateEnvironment(env); 258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HBasicBlock::UpdateEnvironment(HEnvironment* env) { 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_environment_ = env; 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->update_maximum_environment_size(env->first_expression_index()); 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HBasicBlock::SetJoinId(BailoutId ast_id) { 268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int length = predecessors_.length(); 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(length > 0); 270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < length; i++) { 271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* predecessor = predecessors_[i]; 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(predecessor->end()->IsGoto()); 273e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HSimulate* simulate = HSimulate::cast(predecessor->end()->previous()); 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(i != 0 || 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (predecessor->last_environment()->closure().is_null() || 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch predecessor->last_environment()->closure()->shared() 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->VerifyBailoutId(ast_id))); 2783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch simulate->set_ast_id(ast_id); 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch predecessor->last_environment()->set_ast_id(ast_id); 280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochbool HBasicBlock::Dominates(HBasicBlock* other) const { 285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* current = other->dominator(); 286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (current != NULL) { 287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (current == this) return true; 288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch current = current->dominator(); 289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return false; 291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HBasicBlock::EqualToOrDominates(HBasicBlock* other) const { 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (this == other) return true; 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Dominates(other); 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 300589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochint HBasicBlock::LoopNestingDepth() const { 301589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch const HBasicBlock* current = this; 302589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch int result = (current->IsLoopHeader()) ? 1 : 0; 303589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch while (current->parent_loop_header() != NULL) { 304589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch current = current->parent_loop_header(); 305589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch result++; 306589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 307589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return result; 308589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 309589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 310589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::PostProcessLoopHeader(IterationStatement* stmt) { 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsLoopHeader()); 313b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SetJoinId(stmt->EntryId()); 315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (predecessors()->length() == 1) { 316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // This is a degenerated loop. 317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DetachLoopInformation(); 318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return; 319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Only the first entry into the loop is from outside the loop. All other 322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // entries must be back edges. 323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 1; i < predecessors()->length(); ++i) { 324b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch loop_information()->RegisterBackEdge(predecessors()->at(i)); 325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HBasicBlock::MarkSuccEdgeUnreachable(int succ) { 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsFinished()); 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* succ_block = end()->SuccessorAt(succ); 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(succ_block->predecessors()->length() == 1); 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch succ_block->MarkUnreachable(); 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::RegisterPredecessor(HBasicBlock* pred) { 339257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (HasPredecessor()) { 340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Only loop header blocks can have a predecessor added after 341b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // instructions have been added to the block (they have phis for all 342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // values in the environment, these phis may be eliminated later). 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsLoopHeader() || first_ == NULL); 344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HEnvironment* incoming_env = pred->last_environment(); 345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (IsLoopHeader()) { 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(phis()->length() == incoming_env->length()); 347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < phis_.length(); ++i) { 348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phis_[i]->AddInput(incoming_env->values()->at(i)); 349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch last_environment()->AddIncomingEdge(this, pred->last_environment()); 352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else if (!HasEnvironment() && !IsFinished()) { 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsLoopHeader()); 355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SetInitialEnvironment(pred->last_environment()->Copy()); 356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch predecessors_.Add(pred, zone()); 359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::AddDominatedBlock(HBasicBlock* block) { 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dominated_blocks_.Contains(block)); 364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Keep the list of dominated blocks sorted such that if there is two 365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // succeeding block in this list, the predecessor is before the successor. 366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int index = 0; 367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (index < dominated_blocks_.length() && 368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch dominated_blocks_[index]->block_id() < block->block_id()) { 369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ++index; 370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dominated_blocks_.InsertAt(index, block, zone()); 372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::AssignCommonDominator(HBasicBlock* other) { 376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (dominator_ == NULL) { 377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch dominator_ = other; 378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch other->AddDominatedBlock(this); 379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else if (other->dominator() != NULL) { 380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* first = dominator_; 381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* second = other; 382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (first != second) { 384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (first->block_id() > second->block_id()) { 385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch first = first->dominator(); 386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch second = second->dominator(); 388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(first != NULL && second != NULL); 390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (dominator_ != first) { 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(dominator_->dominated_blocks_.Contains(this)); 394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch dominator_->dominated_blocks_.RemoveElement(this); 395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch dominator_ = first; 396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch first->AddDominatedBlock(this); 397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid HBasicBlock::AssignLoopSuccessorDominators() { 4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Mark blocks that dominate all subsequent reachable blocks inside their 4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // loop. Exploit the fact that blocks are sorted in reverse post order. When 4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the loop is visited in increasing block id order, if the number of 4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // non-loop-exiting successor edges at the dominator_candidate block doesn't 4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // exceed the number of previously encountered predecessor edges, there is no 4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // path from the loop header to any block with higher id that doesn't go 4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // through the dominator_candidate block. In this case, the 4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // dominator_candidate block is guaranteed to dominate all blocks reachable 4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // from it with higher ids. 4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HBasicBlock* last = loop_information()->GetLastBackEdge(); 4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int outstanding_successors = 1; // one edge from the pre-header 4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Header always dominates everything. 4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkAsLoopSuccessorDominator(); 4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int j = block_id(); j <= last->block_id(); ++j) { 4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HBasicBlock* dominator_candidate = graph_->blocks()->at(j); 4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (HPredecessorIterator it(dominator_candidate); !it.Done(); 4193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch it.Advance()) { 4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HBasicBlock* predecessor = it.Current(); 4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Don't count back edges. 4223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (predecessor->block_id() < dominator_candidate->block_id()) { 4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch outstanding_successors--; 4243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If more successors than predecessors have been seen in the loop up to 4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // now, it's not possible to guarantee that the current block dominates 4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // all of the blocks with higher IDs. In this case, assume conservatively 4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // that those paths through loop that don't go through the current block 4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // contain all of the loop's dependencies. Also be careful to record 4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // dominator information about the current loop that's being processed, 4333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // and not nested loops, which will be processed when 4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // AssignLoopSuccessorDominators gets called on their header. 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(outstanding_successors >= 0); 4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HBasicBlock* parent_loop_header = dominator_candidate->parent_loop_header(); 4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (outstanding_successors == 0 && 4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (parent_loop_header == this && !dominator_candidate->IsLoopHeader())) { 4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch dominator_candidate->MarkAsLoopSuccessorDominator(); 4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HControlInstruction* end = dominator_candidate->end(); 4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { 4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HBasicBlock* successor = it.Current(); 4443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Only count successors that remain inside the loop and don't loop back 4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // to a loop header. 4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (successor->block_id() > dominator_candidate->block_id() && 4473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch successor->block_id() <= last->block_id()) { 4483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Backwards edges must land on loop headers. 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(successor->block_id() > dominator_candidate->block_id() || 4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch successor->IsLoopHeader()); 4513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch outstanding_successors++; 4523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochint HBasicBlock::PredecessorIndexOf(HBasicBlock* predecessor) const { 459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < predecessors_.length(); ++i) { 460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (predecessors_[i] == predecessor) return i; 461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UNREACHABLE(); 463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return -1; 464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::Verify() { 469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check that every block is finished. 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsFinished()); 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(block_id() >= 0); 47244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 47344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Check that the incoming edges are in edge split form. 47444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (predecessors_.length() > 1) { 47544f0eee88ff00398ff7f715fab053374d808c90dSteve Block for (int i = 0; i < predecessors_.length(); ++i) { 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(predecessors_[i]->end()->SecondSuccessor() == NULL); 47744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 47844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HLoopInformation::RegisterBackEdge(HBasicBlock* block) { 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch this->back_edges_.Add(block, block->zone()); 485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AddBlock(block); 486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 489b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHBasicBlock* HLoopInformation::GetLastBackEdge() const { 490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int max_id = -1; 491b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* result = NULL; 492b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < back_edges_.length(); ++i) { 493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* cur = back_edges_[i]; 494b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (cur->block_id() > max_id) { 495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch max_id = cur->block_id(); 496b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result = cur; 497b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 499b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return result; 500b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 501b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 502b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 503b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HLoopInformation::AddBlock(HBasicBlock* block) { 504b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (block == loop_header()) return; 505b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (block->parent_loop_header() == loop_header()) return; 506b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (block->parent_loop_header() != NULL) { 507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AddBlock(block->parent_loop_header()); 508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 509b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch block->set_parent_loop_header(loop_header()); 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocks_.Add(block, block->zone()); 511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < block->predecessors()->length(); ++i) { 512b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AddBlock(block->predecessors()->at(i)); 513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 514b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 518b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 519b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Checks reachability of the blocks in this graph and stores a bit in 521b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// the BitVector "reachable()" for every block that can be reached 522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// from the start block of the graph. If "dont_visit" is non-null, the given 523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// block is treated as if it would not be part of the graph. "visited_count()" 524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// returns the number of reachable blocks. 525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass ReachabilityAnalyzer BASE_EMBEDDED { 526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ReachabilityAnalyzer(HBasicBlock* entry_block, 528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int block_count, 529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* dont_visit) 530b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : visited_count_(0), 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stack_(16, entry_block->zone()), 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reachable_(block_count, entry_block->zone()), 533b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch dont_visit_(dont_visit) { 534b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PushBlock(entry_block); 535b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Analyze(); 536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int visited_count() const { return visited_count_; } 539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const BitVector* reachable() const { return &reachable_; } 540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 542b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void PushBlock(HBasicBlock* block) { 543b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (block != NULL && block != dont_visit_ && 544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch !reachable_.Contains(block->block_id())) { 545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reachable_.Add(block->block_id()); 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stack_.Add(block, block->zone()); 547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch visited_count_++; 548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Analyze() { 552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (!stack_.is_empty()) { 553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HControlInstruction* end = stack_.RemoveLast()->end(); 5543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { 5553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PushBlock(it.Current()); 5563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int visited_count_; 561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ZoneList<HBasicBlock*> stack_; 562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BitVector reachable_; 563b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* dont_visit_; 564b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid HGraph::Verify(bool do_full_verify) const { 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RelocationLock relocation_lock(isolate()->heap()); 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowHandleDereference allow_deref; 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference allow_deferred_deref; 571b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < blocks_.length(); i++) { 572b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* block = blocks_.at(i); 573b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 574b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch block->Verify(); 575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 576b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check that every block contains at least one node and that only the last 577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // node is a control instruction. 578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HInstruction* current = block->first(); 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current != NULL && current->IsBlockEntry()); 580b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (current != NULL) { 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((current->next() == NULL) == current->IsControlInstruction()); 582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current->block() == block); 583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch current->Verify(); 584b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch current = current->next(); 585b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check that successors are correctly set. 588b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* first = block->end()->FirstSuccessor(); 589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* second = block->end()->SecondSuccessor(); 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(second == NULL || first != NULL); 591b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 592b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check that the predecessor array is correct. 593b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (first != NULL) { 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(first->predecessors()->Contains(block)); 595b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (second != NULL) { 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(second->predecessors()->Contains(block)); 597b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 598b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 599b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 600b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check that phis have correct arguments. 601b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int j = 0; j < block->phis()->length(); j++) { 602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HPhi* phi = block->phis()->at(j); 603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phi->Verify(); 604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 606b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check that all join blocks have predecessors that end with an 607b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // unconditional goto and agree on their environment node id. 608b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (block->predecessors()->length() >= 2) { 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId id = 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block->predecessors()->first()->last_environment()->ast_id(); 611b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int k = 0; k < block->predecessors()->length(); k++) { 612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* predecessor = block->predecessors()->at(k); 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(predecessor->end()->IsGoto() || 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch predecessor->end()->IsDeoptimize()); 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(predecessor->last_environment()->ast_id() == id); 616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 617b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 618b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 619b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 620b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check special property of first block to have no predecessors. 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(blocks_.at(0)->predecessors()->is_empty()); 622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (do_full_verify) { 6243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check that the graph is fully connected. 6253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReachabilityAnalyzer analyzer(entry_block_, blocks_.length(), NULL); 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(analyzer.visited_count() == blocks_.length()); 627b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check that entry block dominator is NULL. 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(entry_block_->dominator() == NULL); 630b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 6313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check dominators. 6323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < blocks_.length(); ++i) { 6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HBasicBlock* block = blocks_.at(i); 6343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (block->dominator() == NULL) { 6353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Only start block may have no dominator assigned to. 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(i == 0); 6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 6383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Assert that block is unreachable if dominator must not be visited. 6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReachabilityAnalyzer dominator_analyzer(entry_block_, 6403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch blocks_.length(), 6413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch block->dominator()); 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dominator_analyzer.reachable()->Contains(block->block_id())); 6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 644b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 645b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 646b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 647b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 648b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 649b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 650b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 651b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer, 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t value) { 653b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!pointer->is_set()) { 654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Can't pass GetInvalidContext() to HConstant::New, because that will 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // recursively call GetConstant 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* constant = HConstant::New(zone(), NULL, value); 657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant->InsertAfter(entry_block()->first()); 658b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch pointer->set(constant); 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return constant; 660b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReinsertConstantIfNecessary(pointer->get()); 662b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 663b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 664b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHConstant* HGraph::ReinsertConstantIfNecessary(HConstant* constant) { 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!constant->IsLinked()) { 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The constant was removed from the graph. Reinsert. 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant->ClearFlag(HValue::kIsDead); 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant->InsertAfter(entry_block()->first()); 670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return constant; 672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 674b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHConstant* HGraph::GetConstant0() { 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetConstant(&constant_0_, 0); 677b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 679b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHConstant* HGraph::GetConstant1() { 681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetConstant(&constant_1_, 1); 682b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 683b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHConstant* HGraph::GetConstantMinus1() { 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetConstant(&constant_minus1_, -1); 687b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 688b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 6893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DEFINE_GET_CONSTANT(Name, name, type, htype, boolean_value) \ 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHConstant* HGraph::GetConstant##Name() { \ 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!constant_##name##_.is_set()) { \ 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* constant = new(zone()) HConstant( \ 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Unique<Object>::CreateImmovable(isolate()->factory()->name##_value()), \ 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Unique<Map>::CreateImmovable(isolate()->factory()->type##_map()), \ 696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch false, \ 697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation::Tagged(), \ 698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch htype, \ 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch true, \ 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boolean_value, \ 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch false, \ 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ODDBALL_TYPE); \ 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant->InsertAfter(entry_block()->first()); \ 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_##name##_.set(constant); \ 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReinsertConstantIfNecessary(constant_##name##_.get()); \ 7073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 7083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_GET_CONSTANT(Undefined, undefined, undefined, HType::Undefined(), false) 711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_GET_CONSTANT(True, true, boolean, HType::Boolean(), true) 712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_GET_CONSTANT(False, false, boolean, HType::Boolean(), false) 713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_GET_CONSTANT(Hole, the_hole, the_hole, HType::None(), false) 714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_GET_CONSTANT(Null, null, null, HType::Null(), false) 715b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DEFINE_GET_CONSTANT 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DEFINE_IS_CONSTANT(Name, name) \ 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HGraph::IsConstant##Name(HConstant* constant) { \ 721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return constant_##name##_.is_set() && constant == constant_##name##_.get(); \ 722b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_IS_CONSTANT(Undefined, undefined) 724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_IS_CONSTANT(0, 0) 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_IS_CONSTANT(1, 1) 726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_IS_CONSTANT(Minus1, minus1) 727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_IS_CONSTANT(True, true) 728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_IS_CONSTANT(False, false) 729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_IS_CONSTANT(Hole, the_hole) 730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_IS_CONSTANT(Null, null) 731b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DEFINE_IS_CONSTANT 733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHConstant* HGraph::GetInvalidContext() { 736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetConstant(&constant_invalid_context_, 0xFFFFC0C7); 737b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 738b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HGraph::IsStandardConstant(HConstant* constant) { 741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstantUndefined(constant)) return true; 742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstant0(constant)) return true; 743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstant1(constant)) return true; 744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstantMinus1(constant)) return true; 745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstantTrue(constant)) return true; 746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstantFalse(constant)) return true; 747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstantHole(constant)) return true; 748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstantNull(constant)) return true; 749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 750b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 751b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 752b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraphBuilder::IfBuilder::IfBuilder() : builder_(NULL), needs_compare_(true) {} 754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder) 757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : needs_compare_(true) { 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Initialize(builder); 759b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 760b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 761b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, 763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIfContinuation* continuation) 764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : needs_compare_(false), first_true_block_(NULL), first_false_block_(NULL) { 765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeDontCreateBlocks(builder); 766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continuation->Continue(&first_true_block_, &first_false_block_); 767b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 768b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 769b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::InitializeDontCreateBlocks( 771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HGraphBuilder* builder) { 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_ = builder; 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch finished_ = false; 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_then_ = false; 775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_else_ = false; 776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_else_if_ = false; 777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_and_ = false; 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_or_ = false; 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch captured_ = false; 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pending_merge_block_ = false; 781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch split_edge_merge_block_ = NULL; 782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch merge_at_join_blocks_ = NULL; 783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch normal_merge_at_join_block_count_ = 0; 784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deopt_merge_at_join_block_count_ = 0; 785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 786b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 787b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::Initialize(HGraphBuilder* builder) { 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeDontCreateBlocks(builder); 790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = builder->environment(); 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_true_block_ = builder->CreateBasicBlock(env->Copy()); 792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_false_block_ = builder->CreateBasicBlock(env->Copy()); 793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 794b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 795b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHControlInstruction* HGraphBuilder::IfBuilder::AddCompare( 797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HControlInstruction* compare) { 798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(did_then_ == did_else_); 799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (did_else_) { 800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle if-then-elseif 801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_else_if_ = true; 802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_else_ = false; 803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_then_ = false; 804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_and_ = false; 805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_or_ = false; 806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pending_merge_block_ = false; 807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch split_edge_merge_block_ = NULL; 808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = builder()->environment(); 809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_true_block_ = builder()->CreateBasicBlock(env->Copy()); 810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_false_block_ = builder()->CreateBasicBlock(env->Copy()); 811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (split_edge_merge_block_ != NULL) { 813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = first_false_block_->last_environment(); 814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* split_edge = builder()->CreateBasicBlock(env->Copy()); 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (did_or_) { 816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare->SetSuccessorAt(0, split_edge); 817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare->SetSuccessorAt(1, first_false_block_); 818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare->SetSuccessorAt(0, first_true_block_); 820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare->SetSuccessorAt(1, split_edge); 821b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->GotoNoSimulate(split_edge, split_edge_merge_block_); 823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare->SetSuccessorAt(0, first_true_block_); 825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare->SetSuccessorAt(1, first_false_block_); 826b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->FinishCurrentBlock(compare); 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch needs_compare_ = false; 829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return compare; 830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 832b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::Or() { 834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!needs_compare_); 835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!did_and_); 836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_or_ = true; 837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = first_false_block_->last_environment(); 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (split_edge_merge_block_ == NULL) { 839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch split_edge_merge_block_ = builder()->CreateBasicBlock(env->Copy()); 840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->GotoNoSimulate(first_true_block_, split_edge_merge_block_); 841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_true_block_ = split_edge_merge_block_; 842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->set_current_block(first_false_block_); 844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_false_block_ = builder()->CreateBasicBlock(env->Copy()); 845b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 846b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 847b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::And() { 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!needs_compare_); 850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!did_or_); 851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_and_ = true; 852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = first_false_block_->last_environment(); 853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (split_edge_merge_block_ == NULL) { 854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch split_edge_merge_block_ = builder()->CreateBasicBlock(env->Copy()); 855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->GotoNoSimulate(first_false_block_, split_edge_merge_block_); 856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_false_block_ = split_edge_merge_block_; 857b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->set_current_block(first_true_block_); 859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_true_block_ = builder()->CreateBasicBlock(env->Copy()); 860b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 861b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 862b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::CaptureContinuation( 864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIfContinuation* continuation) { 865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!did_else_if_); 866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!finished_); 867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!captured_); 868b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* true_block = NULL; 870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* false_block = NULL; 871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Finish(&true_block, &false_block); 872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(true_block != NULL); 873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(false_block != NULL); 874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continuation->Capture(true_block, false_block); 875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch captured_ = true; 876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->set_current_block(NULL); 877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch End(); 878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 879b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) { 882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!did_else_if_); 883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!finished_); 884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!captured_); 885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* true_block = NULL; 886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* false_block = NULL; 887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Finish(&true_block, &false_block); 888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch merge_at_join_blocks_ = NULL; 889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (true_block != NULL && !true_block->IsFinished()) { 890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(continuation->IsTrueReachable()); 891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->GotoNoSimulate(true_block, continuation->true_branch()); 892b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (false_block != NULL && !false_block->IsFinished()) { 894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(continuation->IsFalseReachable()); 895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->GotoNoSimulate(false_block, continuation->false_branch()); 896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch captured_ = true; 898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch End(); 899b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 900b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 901b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::Then() { 903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!captured_); 904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!finished_); 905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_then_ = true; 906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (needs_compare_) { 907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle if's without any expressions, they jump directly to the "else" 908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // branch. However, we must pretend that the "then" branch is reachable, 909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // so that the graph builder visits it and sees any live range extending 910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // constructs within it. 911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* constant_false = builder()->graph()->GetConstantFalse(); 912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ToBooleanStub::Types boolean_type = ToBooleanStub::Types(); 913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boolean_type.Add(ToBooleanStub::BOOLEAN); 914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBranch* branch = builder()->New<HBranch>( 915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_false, boolean_type, first_true_block_, first_false_block_); 916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->FinishCurrentBlock(branch); 917b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->set_current_block(first_true_block_); 919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pending_merge_block_ = true; 920b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 921b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 922b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::Else() { 924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(did_then_); 925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!captured_); 926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!finished_); 927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddMergeAtJoinBlock(false); 928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->set_current_block(first_false_block_); 929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pending_merge_block_ = true; 930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_else_ = true; 931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::Deopt(const char* reason) { 935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(did_then_); 936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->Add<HDeoptimize>(reason, Deoptimizer::EAGER); 937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddMergeAtJoinBlock(true); 938b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 939b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 940b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::Return(HValue* value) { 942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* parameter_count = builder()->graph()->GetConstantMinus1(); 943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->FinishExitCurrentBlock( 944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->New<HReturn>(value, parameter_count)); 945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddMergeAtJoinBlock(false); 946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::AddMergeAtJoinBlock(bool deopt) { 950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!pending_merge_block_) return; 951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block = builder()->current_block(); 952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(block == NULL || !block->IsFinished()); 953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MergeAtJoinBlock* record = new (builder()->zone()) 954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MergeAtJoinBlock(block, deopt, merge_at_join_blocks_); 955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch merge_at_join_blocks_ = record; 956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block != NULL) { 957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(block->end() == NULL); 958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (deopt) { 959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch normal_merge_at_join_block_count_++; 960b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deopt_merge_at_join_block_count_++; 962b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 963b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->set_current_block(NULL); 965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pending_merge_block_ = false; 96669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 9673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 968b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::Finish() { 970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!finished_); 971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!did_then_) { 972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Then(); 9733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddMergeAtJoinBlock(false); 975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!did_else_) { 976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Else(); 977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddMergeAtJoinBlock(false); 978b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch finished_ = true; 980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 981b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 982b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::Finish(HBasicBlock** then_continuation, 984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock** else_continuation) { 985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Finish(); 986257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MergeAtJoinBlock* else_record = merge_at_join_blocks_; 988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (else_continuation != NULL) { 989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *else_continuation = else_record->block_; 99044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MergeAtJoinBlock* then_record = else_record->next_; 992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (then_continuation != NULL) { 993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *then_continuation = then_record->block_; 994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(then_record->next_ == NULL); 99644f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 99744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 99844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::End() { 1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (captured_) return; 1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Finish(); 100244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int total_merged_blocks = normal_merge_at_join_block_count_ + 1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deopt_merge_at_join_block_count_; 1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(total_merged_blocks >= 1); 1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* merge_block = 1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total_merged_blocks == 1 ? NULL : builder()->graph()->CreateBasicBlock(); 100844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Merge non-deopt blocks first to ensure environment has right size for 1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // padding. 1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MergeAtJoinBlock* current = merge_at_join_blocks_; 1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (current != NULL) { 1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!current->deopt_ && current->block_ != NULL) { 1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there is only one block that makes it through to the end of the 1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // if, then just set it as the current block and continue rather then 1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // creating an unnecessary merge block. 1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (total_merged_blocks == 1) { 1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->set_current_block(current->block_); 1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 102044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->GotoNoSimulate(current->block_, merge_block); 102244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current = current->next_; 102444f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 102544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Merge deopt blocks, padding when necessary. 1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current = merge_at_join_blocks_; 1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (current != NULL) { 1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current->deopt_ && current->block_ != NULL) { 1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current->block_->FinishExit(HAbnormalExit::New(builder()->zone(), NULL), 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HSourcePosition::Unknown()); 1032b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current = current->next_; 1034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->set_current_block(merge_block); 1036b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1038b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder) { 1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Initialize(builder, NULL, kWhileTrue, NULL); 1041257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1042257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1043257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, HValue* context, 1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder::Direction direction) { 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Initialize(builder, context, direction, builder->graph()->GetConstant1()); 10473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 10483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 10493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, HValue* context, 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder::Direction direction, 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* increment_amount) { 1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Initialize(builder, context, direction, increment_amount); 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch increment_amount_ = increment_amount; 10553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 10563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::LoopBuilder::Initialize(HGraphBuilder* builder, 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context, 1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Direction direction, 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* increment_amount) { 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_ = builder; 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context_ = context; 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch direction_ = direction; 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch increment_amount_ = increment_amount; 1066b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch finished_ = false; 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch header_block_ = builder->CreateLoopHeaderBlock(); 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_block_ = NULL; 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exit_block_ = NULL; 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exit_trampoline_block_ = NULL; 1072b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1073b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1074b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::LoopBuilder::BeginBody( 1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* initial, 1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* terminating, 1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::Value token) { 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(direction_ != kWhileTrue); 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = builder_->environment(); 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch phi_ = header_block_->AddNewPhi(env->values()->length()); 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch phi_->AddInput(initial); 1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Push(initial); 1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->GotoNoSimulate(header_block_); 1085b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* body_env = env->Copy(); 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* exit_env = env->Copy(); 1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remove the phi from the expression stack 1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_env->Pop(); 1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exit_env->Pop(); 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_block_ = builder_->CreateBasicBlock(body_env); 1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exit_block_ = builder_->CreateBasicBlock(exit_env); 1093b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->set_current_block(header_block_); 1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Pop(); 1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->FinishCurrentBlock(builder_->New<HCompareNumericAndBranch>( 1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch phi_, terminating, token, body_block_, exit_block_)); 1098b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->set_current_block(body_block_); 1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (direction_ == kPreIncrement || direction_ == kPreDecrement) { 1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* one = builder_->graph()->GetConstant1(); 1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (direction_ == kPreIncrement) { 1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch increment_ = HAdd::New(zone(), context_, phi_, one); 1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch increment_ = HSub::New(zone(), context_, phi_, one); 1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch increment_->ClearFlag(HValue::kCanOverflow); 1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->AddInstruction(increment_); 1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return increment_; 1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return phi_; 1112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::LoopBuilder::BeginBody(int drop_count) { 1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(direction_ == kWhileTrue); 1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = builder_->environment(); 1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->GotoNoSimulate(header_block_); 1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->set_current_block(header_block_); 1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Drop(drop_count); 1122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::LoopBuilder::Break() { 1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (exit_trampoline_block_ == NULL) { 1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Its the first time we saw a break. 1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (direction_ == kWhileTrue) { 1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = builder_->environment()->Copy(); 1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exit_trampoline_block_ = builder_->CreateBasicBlock(env); 1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = exit_block_->last_environment()->Copy(); 1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exit_trampoline_block_ = builder_->CreateBasicBlock(env); 1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->GotoNoSimulate(exit_block_, exit_trampoline_block_); 1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->GotoNoSimulate(exit_trampoline_block_); 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->set_current_block(NULL); 1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1142b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::LoopBuilder::EndBody() { 1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!finished_); 1145b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (direction_ == kPostIncrement || direction_ == kPostDecrement) { 1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (direction_ == kPostIncrement) { 1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch increment_ = HAdd::New(zone(), context_, phi_, increment_amount_); 1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch increment_ = HSub::New(zone(), context_, phi_, increment_amount_); 1151b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch increment_->ClearFlag(HValue::kCanOverflow); 1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->AddInstruction(increment_); 1154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (direction_ != kWhileTrue) { 1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Push the new increment value on the expression stack to merge into 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the phi. 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->environment()->Push(increment_); 1160b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* last_block = builder_->current_block(); 1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->GotoNoSimulate(last_block, header_block_); 1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch header_block_->loop_information()->RegisterBackEdge(last_block); 1164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (exit_trampoline_block_ != NULL) { 1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->set_current_block(exit_trampoline_block_); 1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->set_current_block(exit_block_); 1169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch finished_ = true; 1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraph* HGraphBuilder::CreateGraph() { 1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph_ = new(zone()) HGraph(info_); 1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_); 1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompilationPhase phase("H_Block building", info_); 1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(graph()->entry_block()); 1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!BuildGraph()) return NULL; 1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->FinalizeUniqueness(); 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return graph_; 1182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { 1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!FLAG_hydrogen_track_positions || 1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !position_.IsUnknown() || 1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !info_->IsOptimizing()); 1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_block()->AddInstruction(instr, source_position()); 1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (graph()->IsInsideNoSideEffectsScope()) { 1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetFlag(HValue::kHasNoObservableSideEffects); 1193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return instr; 1195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) { 1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!FLAG_hydrogen_track_positions || 1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !info_->IsOptimizing() || 1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !position_.IsUnknown()); 1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_block()->Finish(last, source_position()); 1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (last->IsReturn() || last->IsAbnormalExit()) { 1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) { 1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!FLAG_hydrogen_track_positions || !info_->IsOptimizing() || 1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !position_.IsUnknown()); 1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_block()->FinishExit(instruction, source_position()); 1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instruction->IsReturn() || instruction->IsAbnormalExit()) { 1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 1215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { 1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_native_code_counters && counter->Enabled()) { 1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* reference = Add<HConstant>(ExternalReference(counter)); 1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* old_value = Add<HLoadNamedField>( 1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reference, static_cast<HValue*>(NULL), HObjectAccess::ForCounter()); 1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1()); 1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow 1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), 1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_value, STORE_TO_INITIALIZED_ENTRY); 1228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1230b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::AddSimulate(BailoutId id, 1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RemovableSimulate removable) { 1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!graph()->IsInsideNoSideEffectsScope()); 1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_block()->AddNewSimulate(id, source_position(), removable); 1237b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1238b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1239b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { 1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* b = graph()->CreateBasicBlock(); 1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch b->SetInitialEnvironment(env); 1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return b; 1244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { 1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* header = graph()->CreateBasicBlock(); 1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); 1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch header->SetInitialEnvironment(entry_env); 1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch header->AttachLoopInformation(); 1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return header; 1253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildGetElementsKind(HValue* object) { 1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* map = Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), 1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMap()); 1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* bit_field2 = Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), 1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMapBitField2()); 1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildDecodeField<Map::ElementsKindBits>(bit_field2); 1263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1265b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { 1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (obj->type().IsHeapObject()) return obj; 1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HCheckHeapObject>(obj); 1269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::FinishExitWithHardDeoptimization(const char* reason) { 1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HDeoptimize>(reason, Deoptimizer::EAGER); 1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishExitCurrentBlock(New<HAbnormalExit>()); 1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildCheckString(HValue* string) { 1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!string->type().IsString()) { 1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!string->IsConstant() || 1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !HConstant::cast(string)->HasStringValue()); 1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(string); 1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HCheckInstanceType>(string, HCheckInstanceType::IS_STRING); 1284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return string; 1286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildWrapReceiver(HValue* object, HValue* function) { 1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object->type().IsJSObject()) return object; 1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function->IsConstant() && 1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(function)->handle(isolate())->IsJSFunction()) { 1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> f = Handle<JSFunction>::cast( 1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(function)->handle(isolate())); 1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedFunctionInfo* shared = f->shared(); 1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shared->strict_mode() == STRICT || shared->native()) return object; 1297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HWrapReceiver>(object, function); 1299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildCheckForCapacityGrow( 1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object, 1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements, 1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length, 1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key, 1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_js_array, 1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessType access_type) { 1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder length_checker(this); 1311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ; 1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.If<HCompareNumericAndBranch>(key, length, token); 1314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.Then(); 1316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* current_capacity = AddLoadFixedArrayLength(elements); 1318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder capacity_checker(this); 1320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity, 1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::GTE); 1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch capacity_checker.Then(); 1324b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap)); 1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* max_capacity = AddUncasted<HAdd>(current_capacity, max_gap); 1327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HBoundsCheck>(key, max_capacity); 1329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_capacity = BuildNewElementsCapacity(key); 1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_elements = BuildGrowElementsCapacity(object, elements, 1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind, kind, length, 1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_capacity); 1334b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(new_elements); 1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch capacity_checker.Else(); 1337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(elements); 1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch capacity_checker.End(); 1340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_js_array) { 1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_length = AddUncasted<HAdd>(key, graph_->GetConstant1()); 1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_length->ClearFlag(HValue::kCanOverflow); 1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind), 1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_length); 1347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == STORE && kind == FAST_SMI_ELEMENTS) { 1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_elements = environment()->Top(); 1351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Write zero to ensure that the new element is initialized with some smi. 1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreKeyed>(checked_elements, key, graph()->GetConstant0(), kind); 1354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.Else(); 1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HBoundsCheck>(key, length); 1358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(elements); 1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.End(); 1361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return environment()->Pop(); 1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, 1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements, 1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length) { 1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate()->factory(); 1371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder cow_checker(this); 1373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cow_checker.If<HCompareMap>(elements, factory->fixed_cow_array_map()); 1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cow_checker.Then(); 1376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* capacity = AddLoadFixedArrayLength(elements); 1378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_elements = BuildGrowElementsCapacity(object, elements, kind, 1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind, length, capacity); 1381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(new_elements); 1383257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cow_checker.Else(); 1385257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(elements); 1387257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cow_checker.End(); 1389257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return environment()->Pop(); 1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1392257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1393257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildTransitionElementsKind(HValue* object, 1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* map, 1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind from_kind, 1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind to_kind, 1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_jsarray) { 1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsFastHoleyElementsKind(from_kind) || 1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsFastHoleyElementsKind(to_kind)); 1401257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) { 1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HTrapAllocationMemento>(object); 1404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsSimpleMapChangeTransition(from_kind, to_kind)) { 1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* elements = AddLoadElements(object); 1408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* empty_fixed_array = Add<HConstant>( 1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->empty_fixed_array()); 1411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_builder(this); 1413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array); 1415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_builder.Then(); 1417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* elements_length = AddLoadFixedArrayLength(elements); 1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* array_length = is_jsarray 1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), 1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForArrayLength(from_kind)) 1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : elements_length; 1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildGrowElementsCapacity(object, elements, from_kind, to_kind, 1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array_length, elements_length); 1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_builder.End(); 1429b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map); 1432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildJSObjectCheck(HValue* receiver, 1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bit_field_mask) { 1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that the object isn't a smi. 1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckHeapObject>(receiver); 1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Get the map of the receiver. 1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), 1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMap()); 1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check the instance type and if an access check is needed, this can be 1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // done with a single load, since both bytes are adjacent in the map. 1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access(HObjectAccess::ForMapInstanceTypeAndBitField()); 1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* instance_type_and_bit_field = 1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), access); 1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* mask = Add<HConstant>(0x00FF | (bit_field_mask << 8)); 1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* and_result = AddUncasted<HBitwise>(Token::BIT_AND, 1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instance_type_and_bit_field, 1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mask); 1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* sub_result = AddUncasted<HSub>(and_result, 1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(JS_OBJECT_TYPE)); 1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HBoundsCheck>(sub_result, 1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(LAST_JS_OBJECT_TYPE + 1 - JS_OBJECT_TYPE)); 1458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildKeyedIndexCheck(HValue* key, 1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIfContinuation* join_continuation) { 1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The sometimes unintuitively backward ordering of the ifs below is 1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // convoluted, but necessary. All of the paths must guarantee that the 1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // if-true of the continuation returns a smi element index and the if-false of 1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the continuation returns either a symbol or a unique string key. All other 1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // object types cause a deopt to fall back to the runtime. 1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder key_smi_if(this); 1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key_smi_if.If<HIsSmiAndBranch>(key); 1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key_smi_if.Then(); 1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(key); // Nothing to do, just continue to true of continuation. 1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key_smi_if.Else(); 1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* map = Add<HLoadNamedField>(key, static_cast<HValue*>(NULL), 1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMap()); 1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* instance_type = 1480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), 1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMapInstanceType()); 1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Non-unique string, check for a string with a hash code that is actually 1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // an index. 1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(LAST_UNIQUE_NAME_TYPE == FIRST_NONSTRING_TYPE); 1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder not_string_or_name_if(this); 1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch not_string_or_name_if.If<HCompareNumericAndBranch>( 1488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instance_type, 1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(LAST_UNIQUE_NAME_TYPE), 1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::GT); 1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch not_string_or_name_if.Then(); 1493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Non-smi, non-Name, non-String: Try to convert to smi in case of 1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // HeapNumber. 1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(danno): This could call some variant of ToString 1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(AddUncasted<HForceRepresentation>(key, Representation::Smi())); 1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch not_string_or_name_if.Else(); 1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // String or Name: check explicitly for Name, they can short-circuit 1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // directly to unique non-index key path. 1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder not_symbol_if(this); 1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch not_symbol_if.If<HCompareNumericAndBranch>( 1505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instance_type, 1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(SYMBOL_TYPE), 1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::NE); 1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch not_symbol_if.Then(); 1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // String: check whether the String is a String of an index. If it is, 1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // extract the index value from the hash. 1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* hash = 1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadNamedField>(key, static_cast<HValue*>(NULL), 1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForNameHashField()); 1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* not_index_mask = Add<HConstant>(static_cast<int>( 1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String::kContainsCachedArrayIndexMask)); 1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* not_index_test = AddUncasted<HBitwise>( 1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, hash, not_index_mask); 1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder string_index_if(this); 1523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch string_index_if.If<HCompareNumericAndBranch>(not_index_test, 1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0(), 1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::EQ); 1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch string_index_if.Then(); 1527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // String with index in hash: extract string and merge to index path. 1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(BuildDecodeField<String::ArrayIndexValueBits>(hash)); 15305d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 1531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch string_index_if.Else(); 1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Key is a non-index String, check for uniqueness/internalization. 1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If it's not internalized yet, internalize it now. 1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* not_internalized_bit = AddUncasted<HBitwise>( 1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, 1537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instance_type, 1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int>(kIsNotInternalizedMask))); 1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder internalized(this); 1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch internalized.If<HCompareNumericAndBranch>(not_internalized_bit, 1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0(), 1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::EQ); 1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch internalized.Then(); 1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(key); 1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch internalized.Else(); 1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(key); 1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* intern_key = Add<HCallRuntime>( 1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->empty_string(), 1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::FunctionForId(Runtime::kInternalizeString), 1); 1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(intern_key); 1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch internalized.End(); 1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Key guaranteed to be a unique string 15563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch string_index_if.JoinContinuation(join_continuation); 1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch not_symbol_if.Else(); 1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(key); // Key is symbol 1562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch not_symbol_if.JoinContinuation(join_continuation); 1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch not_string_or_name_if.JoinContinuation(join_continuation); 1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key_smi_if.JoinContinuation(join_continuation); 1568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildNonGlobalObjectCheck(HValue* receiver) { 1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Get the the instance type of the receiver, and make sure that it is 1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // not one of the global object types. 1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), 1575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMap()); 1576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* instance_type = 1577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), 1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMapInstanceType()); 1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(JS_BUILTINS_OBJECT_TYPE == JS_GLOBAL_OBJECT_TYPE + 1); 1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* min_global_type = Add<HConstant>(JS_GLOBAL_OBJECT_TYPE); 1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* max_global_type = Add<HConstant>(JS_BUILTINS_OBJECT_TYPE); 1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_global_object(this); 1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_global_object.If<HCompareNumericAndBranch>(instance_type, 1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_global_type, 1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::LTE); 1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_global_object.And(); 1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_global_object.If<HCompareNumericAndBranch>(instance_type, 1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch min_global_type, 1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::GTE); 1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_global_object.ThenDeopt("receiver was a global object"); 1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_global_object.End(); 1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildTestForDictionaryProperties( 1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object, 1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIfContinuation* continuation) { 1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* properties = Add<HLoadNamedField>( 1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, static_cast<HValue*>(NULL), 1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForPropertiesPointer()); 1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* properties_map = 1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadNamedField>(properties, static_cast<HValue*>(NULL), 1604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMap()); 1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* hash_map = Add<HLoadRoot>(Heap::kHashTableMapRootIndex); 1606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder builder(this); 1607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder.If<HCompareObjectEqAndBranch>(properties_map, hash_map); 1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder.CaptureContinuation(continuation); 1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildKeyedLookupCacheHash(HValue* object, 1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key) { 1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the map of the receiver, compute the keyed lookup cache hash 1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // based on 32 bits of the map pointer and the string hash. 1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object_map = 1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), 1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMapAsInteger32()); 1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* shifted_map = AddUncasted<HShr>( 1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_map, Add<HConstant>(KeyedLookupCache::kMapHashShift)); 1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* string_hash = 1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadNamedField>(key, static_cast<HValue*>(NULL), 1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForStringHashField()); 1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* shifted_hash = AddUncasted<HShr>( 1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch string_hash, Add<HConstant>(String::kHashShift)); 1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* xor_result = AddUncasted<HBitwise>(Token::BIT_XOR, shifted_map, 1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shifted_hash); 1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask); 1629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddUncasted<HBitwise>(Token::BIT_AND, xor_result, 1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(mask)); 1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildElementIndexHash(HValue* index) { 1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t seed_value = static_cast<uint32_t>(isolate()->heap()->HashSeed()); 1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* seed = Add<HConstant>(seed_value); 1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, index, seed); 1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // hash = ~hash + (hash << 15); 1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* shifted_hash = AddUncasted<HShl>(hash, Add<HConstant>(15)); 1641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* not_hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash, 1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstantMinus1()); 1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hash = AddUncasted<HAdd>(shifted_hash, not_hash); 1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // hash = hash ^ (hash >> 12); 1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(12)); 1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); 1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // hash = hash + (hash << 2); 1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shifted_hash = AddUncasted<HShl>(hash, Add<HConstant>(2)); 1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hash = AddUncasted<HAdd>(hash, shifted_hash); 1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // hash = hash ^ (hash >> 4); 1654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(4)); 1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); 1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // hash = hash * 2057; 1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hash = AddUncasted<HMul>(hash, Add<HConstant>(2057)); 1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hash->ClearFlag(HValue::kCanOverflow); 1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // hash = hash ^ (hash >> 16); 1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(16)); 1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); 1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver, 1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements, 1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key, 1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* hash) { 1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* capacity = Add<HLoadKeyed>( 1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, 1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(NameDictionary::kCapacityIndex), 1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<HValue*>(NULL), 1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FAST_ELEMENTS); 1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1()); 1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mask->ChangeRepresentation(Representation::Integer32()); 1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mask->ClearFlag(HValue::kCanOverflow); 1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* entry = hash; 1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* count = graph()->GetConstant1(); 1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(entry); 1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(count); 1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIfContinuation return_or_loop_continuation(graph()->CreateBasicBlock(), 1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->CreateBasicBlock()); 1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIfContinuation found_key_match_continuation(graph()->CreateBasicBlock(), 1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->CreateBasicBlock()); 1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder probe_loop(this); 1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch probe_loop.BeginBody(2); // Drop entry, count from last environment to 1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // appease live range building without simulates. 1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch count = Pop(); 1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry = Pop(); 1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry = AddUncasted<HBitwise>(Token::BIT_AND, entry, mask); 1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int entry_size = SeededNumberDictionary::kEntrySize; 1698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* base_index = AddUncasted<HMul>(entry, Add<HConstant>(entry_size)); 1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base_index->ClearFlag(HValue::kCanOverflow); 1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int start_offset = SeededNumberDictionary::kElementsStartIndex; 1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key_index = 1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset)); 1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key_index->ClearFlag(HValue::kCanOverflow); 1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* candidate_key = Add<HLoadKeyed>( 1706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, key_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_undefined(this); 1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_undefined.If<HCompareObjectEqAndBranch>(candidate_key, 1709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstantUndefined()); 1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_undefined.Then(); 1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // element == undefined means "not found". Call the runtime. 1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(jkummerow): walk the prototype chain instead. 1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(receiver, key); 1715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Add<HCallRuntime>(isolate()->factory()->empty_string(), 1716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::FunctionForId(Runtime::kKeyedGetProperty), 1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2)); 1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_undefined.Else(); 1720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_match(this); 1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_match.If<HCompareObjectEqAndBranch>(candidate_key, key); 1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_match.Then(); 1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_match.Else(); 1725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update non-internalized string in the dictionary with internalized key? 1727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_update_with_internalized(this); 1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* smi_check = 1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.IfNot<HIsSmiAndBranch>(candidate_key); 1730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.And(); 1731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* map = AddLoadMap(candidate_key, smi_check); 1732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* instance_type = Add<HLoadNamedField>( 1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map, static_cast<HValue*>(NULL), HObjectAccess::ForMapInstanceType()); 1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* not_internalized_bit = AddUncasted<HBitwise>( 1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, instance_type, 1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int>(kIsNotInternalizedMask))); 1737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.If<HCompareNumericAndBranch>( 1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch not_internalized_bit, graph()->GetConstant0(), Token::NE); 1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.And(); 1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.IfNot<HCompareObjectEqAndBranch>( 1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch candidate_key, graph()->GetConstantHole()); 1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.AndIf<HStringCompareAndBranch>(candidate_key, 1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key, Token::EQ); 1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.Then(); 1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Replace a key that is a non-internalized string by the equivalent 1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // internalized string for faster further lookups. 1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreKeyed>(elements, key_index, key, FAST_ELEMENTS); 1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.Else(); 1749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.JoinContinuation(&found_key_match_continuation); 1751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_match.JoinContinuation(&found_key_match_continuation); 1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder found_key_match(this, &found_key_match_continuation); 1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch found_key_match.Then(); 1755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Key at current probe matches. Relevant bits in the |details| field must 1756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // be zero, otherwise the dictionary element requires special handling. 1757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* details_index = 1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 2)); 1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch details_index->ClearFlag(HValue::kCanOverflow); 1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* details = Add<HLoadKeyed>( 1761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, details_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int details_mask = PropertyDetails::TypeField::kMask | 1763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyDetails::DeletedField::kMask; 1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch details = AddUncasted<HBitwise>(Token::BIT_AND, details, 1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(details_mask)); 1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder details_compare(this); 1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch details_compare.If<HCompareNumericAndBranch>( 1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch details, graph()->GetConstant0(), Token::EQ); 1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch details_compare.Then(); 1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result_index = 1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 1)); 1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result_index->ClearFlag(HValue::kCanOverflow); 1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Add<HLoadKeyed>(elements, result_index, static_cast<HValue*>(NULL), 1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FAST_ELEMENTS)); 1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch details_compare.Else(); 1776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(receiver, key); 1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Add<HCallRuntime>(isolate()->factory()->empty_string(), 1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::FunctionForId(Runtime::kKeyedGetProperty), 1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2)); 1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch details_compare.End(); 1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch found_key_match.Else(); 1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch found_key_match.JoinContinuation(&return_or_loop_continuation); 1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_undefined.JoinContinuation(&return_or_loop_continuation); 1786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder return_or_loop(this, &return_or_loop_continuation); 1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return_or_loop.Then(); 1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch probe_loop.Break(); 1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return_or_loop.Else(); 1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry = AddUncasted<HAdd>(entry, count); 1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry->ClearFlag(HValue::kCanOverflow); 1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch count = AddUncasted<HAdd>(count, graph()->GetConstant1()); 1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch count->ClearFlag(HValue::kCanOverflow); 1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(entry); 1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(count); 1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch probe_loop.EndBody(); 1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return_or_loop.End(); 1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Pop(); 1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildRegExpConstructResult(HValue* length, 1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index, 1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* input) { 1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope scope(this); 1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* max_length = Add<HConstant>(JSObject::kInitialMaxFastElementArray); 1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HBoundsCheck>(length, max_length); 1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generate size calculation code here in order to make it dominate 1815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the JSRegExpResult allocation. 1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind = FAST_ELEMENTS; 1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* size = BuildCalculateElementsSize(elements_kind, length); 1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate the JSRegExpResult and the FixedArray in one step. 1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result = Add<HAllocate>( 1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(JSRegExpResult::kSize), HType::JSArray(), 1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NOT_TENURED, JS_ARRAY_TYPE); 1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize the JSRegExpResult header. 1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* global_object = Add<HLoadNamedField>( 1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context(), static_cast<HValue*>(NULL), 1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* native_context = Add<HLoadNamedField>( 1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_object, static_cast<HValue*>(NULL), 1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForGlobalObjectNativeContext()); 1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, HObjectAccess::ForMap(), 1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadNamedField>( 1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch native_context, static_cast<HValue*>(NULL), 1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForContextSlot(Context::REGEXP_RESULT_MAP_INDEX))); 1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* empty_fixed_array = 1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(isolate()->factory()->empty_fixed_array()); 1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, HObjectAccess::ForJSArrayOffset(JSArray::kPropertiesOffset), 1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch empty_fixed_array); 1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset), 1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch empty_fixed_array); 1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, HObjectAccess::ForJSArrayOffset(JSArray::kLengthOffset), length); 1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize the additional fields. 1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kIndexOffset), 1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch index); 1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kInputOffset), 1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch input); 1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate and initialize the elements header. 1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocate* elements = BuildAllocateElements(elements_kind, size); 1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildInitializeElementsHeader(elements, elements_kind, length); 1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!elements->has_size_upper_bound()) { 1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* size_in_bytes_upper_bound = EstablishElementsAllocationSize( 1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind, max_length->Integer32Value()); 1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements->set_size_upper_bound(size_in_bytes_upper_bound); 1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset), 1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements); 1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize the elements contents with undefined. 1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildFillElementsWithValue( 1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, elements_kind, graph()->GetConstant0(), length, 1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstantUndefined()); 1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1876b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildNumberToString(HValue* object, Type* type) { 1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope scope(this); 1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert constant numbers at compile time. 1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object->IsConstant() && HConstant::cast(object)->HasNumberValue()) { 1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> number = HConstant::cast(object)->handle(isolate()); 1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> result = isolate()->factory()->NumberToString(number); 1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HConstant>(result); 1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create a joinable continuation. 1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIfContinuation found(graph()->CreateBasicBlock(), 1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->CreateBasicBlock()); 1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the number string cache. 1893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* number_string_cache = 1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadRoot>(Heap::kNumberStringCacheRootIndex); 1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make the hash mask from the length of the number string cache. It 1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // contains two elements (number and string) for each cache entry. 1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* mask = AddLoadFixedArrayLength(number_string_cache); 1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mask->set_type(HType::Smi()); 1900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mask = AddUncasted<HSar>(mask, graph()->GetConstant1()); 1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mask = AddUncasted<HSub>(mask, graph()->GetConstant1()); 1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check whether object is a smi. 1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_objectissmi(this); 1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectissmi.If<HIsSmiAndBranch>(object); 1906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectissmi.Then(); 1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute hash for smi similar to smi_get_hash(). 1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* hash = AddUncasted<HBitwise>(Token::BIT_AND, object, mask); 1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the key. 1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); 1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, 1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<HValue*>(NULL), 1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FAST_ELEMENTS, ALLOW_RETURN_HOLE); 1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if object == key. 1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_objectiskey(this); 1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectiskey.If<HCompareObjectEqAndBranch>(object, key); 1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectiskey.Then(); 1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make the key_index available. 1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(key_index); 1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectiskey.JoinContinuation(&found); 1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectissmi.Else(); 1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type->Is(Type::SignedSmall())) { 1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectissmi.Deopt("Expected smi"); 1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if the object is a heap number. 1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_objectisnumber(this); 1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* objectisnumber = if_objectisnumber.If<HCompareMap>( 1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, isolate()->factory()->heap_number_map()); 1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectisnumber.Then(); 1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute hash for heap number similar to double_get_hash(). 1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* low = Add<HLoadNamedField>( 1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, objectisnumber, 1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForHeapNumberValueLowestBits()); 1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* high = Add<HLoadNamedField>( 1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, objectisnumber, 1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForHeapNumberValueHighestBits()); 1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, low, high); 1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hash = AddUncasted<HBitwise>(Token::BIT_AND, hash, mask); 1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the key. 1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); 1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, 1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<HValue*>(NULL), 1952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FAST_ELEMENTS, ALLOW_RETURN_HOLE); 1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if the key is a heap number and compare it with the object. 1955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_keyisnotsmi(this); 1956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* keyisnotsmi = if_keyisnotsmi.IfNot<HIsSmiAndBranch>(key); 1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_keyisnotsmi.Then(); 1958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_keyisheapnumber(this); 1960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_keyisheapnumber.If<HCompareMap>( 1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key, isolate()->factory()->heap_number_map()); 1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_keyisheapnumber.Then(); 1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if values of key and object match. 1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_keyeqobject(this); 1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_keyeqobject.If<HCompareNumericAndBranch>( 1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadNamedField>(key, keyisnotsmi, 1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForHeapNumberValue()), 1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadNamedField>(object, objectisnumber, 1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForHeapNumberValue()), 1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::EQ); 1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_keyeqobject.Then(); 1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make the key_index available. 1975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(key_index); 1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_keyeqobject.JoinContinuation(&found); 19783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_keyisheapnumber.JoinContinuation(&found); 19803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_keyisnotsmi.JoinContinuation(&found); 1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectisnumber.Else(); 1984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type->Is(Type::Number())) { 1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectisnumber.Deopt("Expected heap number"); 19873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1988b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectisnumber.JoinContinuation(&found); 1990b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1991b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectissmi.JoinContinuation(&found); 1993b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check for cache hit. 1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_found(this, &found); 1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_found.Then(); 1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count number to string operation in native code. 1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddIncrementCounter(isolate()->counters()->number_to_string_native()); 20001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the value in case of cache hit. 2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key_index = Pop(); 2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1()); 2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Add<HLoadKeyed>(number_string_cache, value_index, 2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<HValue*>(NULL), 2006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FAST_ELEMENTS, ALLOW_RETURN_HOLE)); 2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_found.Else(); 2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Cache miss, fallback to runtime. 2011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(object); 2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Add<HCallRuntime>( 2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->empty_string(), 2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::FunctionForId(Runtime::kNumberToStringSkipCache), 2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1)); 2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_found.End(); 2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Pop(); 2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHAllocate* HGraphBuilder::BuildAllocate( 2024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object_size, 2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HType type, 2026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstanceType instance_type, 2027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocationMode allocation_mode) { 2028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the effective allocation size. 2029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* size = object_size; 2030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (allocation_mode.CreateAllocationMementos()) { 2031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size = AddUncasted<HAdd>(size, Add<HConstant>(AllocationMemento::kSize)); 2032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size->ClearFlag(HValue::kCanOverflow); 2033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Perform the actual allocation. 2036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocate* object = Add<HAllocate>( 2037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size, type, allocation_mode.GetPretenureMode(), 2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instance_type, allocation_mode.feedback_site()); 2039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Setup the allocation memento. 2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (allocation_mode.CreateAllocationMementos()) { 2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCreateAllocationMemento( 2043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, object_size, allocation_mode.current_site()); 2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return object; 2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildAddStringLengths(HValue* left_length, 2051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right_length) { 2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the combined string length and check against max string length. 2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length = AddUncasted<HAdd>(left_length, right_length); 2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that length <= kMaxLength <=> length < MaxLength + 1. 2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* max_length = Add<HConstant>(String::kMaxLength + 1); 2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HBoundsCheck>(length, max_length); 2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return length; 2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildCreateConsString( 2062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length, 2063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left, 2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right, 2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocationMode allocation_mode) { 2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Determine the string instance types. 2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* left_instance_type = AddLoadStringInstanceType(left); 2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* right_instance_type = AddLoadStringInstanceType(right); 2069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate the cons string object. HAllocate does not care whether we 2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pass CONS_STRING_TYPE or CONS_ONE_BYTE_STRING_TYPE here, so we just use 2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // CONS_STRING_TYPE here. Below we decide whether the cons string is 2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // one-byte or two-byte and set the appropriate map. 2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(HAllocate::CompatibleInstanceTypes(CONS_STRING_TYPE, 2075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CONS_ONE_BYTE_STRING_TYPE)); 2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocate* result = BuildAllocate(Add<HConstant>(ConsString::kSize), 2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HType::String(), CONS_STRING_TYPE, 2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_mode); 2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute intersection and difference of instance types. 2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* anded_instance_types = AddUncasted<HBitwise>( 2082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, left_instance_type, right_instance_type); 2083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* xored_instance_types = AddUncasted<HBitwise>( 2084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_XOR, left_instance_type, right_instance_type); 2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We create a one-byte cons string if 2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 1. both strings are one-byte, or 2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2. at least one of the strings is two-byte, but happens to contain only 2089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // one-byte characters. 2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // To do this, we check 2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 1. if both strings are one-byte, or if the one-byte data hint is set in 2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // both strings, or 2093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2. if one of the strings has the one-byte data hint set and the other 2094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // string is one-byte. 2095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_onebyte(this); 2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kOneByteStringTag != 0); 2097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kOneByteDataHintMask != 0); 2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.If<HCompareNumericAndBranch>( 2099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HBitwise>( 2100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, anded_instance_types, 2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>( 2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kStringEncodingMask | kOneByteDataHintMask))), 2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0(), Token::NE); 2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.Or(); 2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kOneByteStringTag != 0 && 2106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kOneByteDataHintTag != 0 && 2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kOneByteDataHintTag != kOneByteStringTag); 2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.If<HCompareNumericAndBranch>( 2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HBitwise>( 2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, xored_instance_types, 2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>( 2112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kOneByteStringTag | kOneByteDataHintTag))), 2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>( 2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kOneByteStringTag | kOneByteDataHintTag)), Token::EQ); 2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.Then(); 2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We can safely skip the write barrier for storing the map here. 2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, HObjectAccess::ForMap(), 2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(isolate()->factory()->cons_one_byte_string_map())); 2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.Else(); 2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We can safely skip the write barrier for storing the map here. 2125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, HObjectAccess::ForMap(), 2127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(isolate()->factory()->cons_string_map())); 2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.End(); 2130e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize the cons string fields. 2132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(), 2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(String::kEmptyHashField)); 2134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length); 2135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForConsStringFirst(), left); 2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForConsStringSecond(), right); 2137e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count the native string addition. 2139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddIncrementCounter(isolate()->counters()->string_add_native()); 2140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 2142b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildCopySeqStringChars(HValue* src, 2146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* src_offset, 2147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String::Encoding src_encoding, 2148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dst, 2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dst_offset, 2150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String::Encoding dst_encoding, 2151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length) { 2152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(dst_encoding != String::ONE_BYTE_ENCODING || 2153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch src_encoding == String::ONE_BYTE_ENCODING); 2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); 2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT); 2156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* src_index = AddUncasted<HAdd>(src_offset, index); 2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = 2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HSeqStringGetChar>(src_encoding, src, src_index); 2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dst_index = AddUncasted<HAdd>(dst_offset, index); 2161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSeqStringSetChar>(dst_encoding, dst, dst_index, value); 2162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.EndBody(); 2164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildObjectSizeAlignment( 2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* unaligned_size, int header_size) { 2169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((header_size & kObjectAlignmentMask) == 0); 2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* size = AddUncasted<HAdd>( 2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unaligned_size, Add<HConstant>(static_cast<int32_t>( 2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch header_size + kObjectAlignmentMask))); 2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size->ClearFlag(HValue::kCanOverflow); 2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddUncasted<HBitwise>( 2175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>( 2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~kObjectAlignmentMask))); 2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildUncheckedStringAdd( 2181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left, 2182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right, 2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocationMode allocation_mode) { 2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Determine the string lengths. 2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left_length = AddLoadStringLength(left); 2186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right_length = AddLoadStringLength(right); 2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the combined string length. 2189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length = BuildAddStringLengths(left_length, right_length); 2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Do some manual constant folding here. 2192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (left_length->IsConstant()) { 2193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* c_left_length = HConstant::cast(left_length); 2194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NE(0, c_left_length->Integer32Value()); 2195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (c_left_length->Integer32Value() + 1 >= ConsString::kMinLength) { 2196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The right string contains at least one character. 2197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildCreateConsString(length, left, right, allocation_mode); 2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (right_length->IsConstant()) { 2200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* c_right_length = HConstant::cast(right_length); 2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NE(0, c_right_length->Integer32Value()); 2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (c_right_length->Integer32Value() + 1 >= ConsString::kMinLength) { 2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The left string contains at least one character. 2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildCreateConsString(length, left, right, allocation_mode); 2205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if we should create a cons string. 2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_createcons(this); 2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_createcons.If<HCompareNumericAndBranch>( 2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length, Add<HConstant>(ConsString::kMinLength), Token::GTE); 2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_createcons.Then(); 2213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create a cons string. 2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(BuildCreateConsString(length, left, right, allocation_mode)); 2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_createcons.Else(); 2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Determine the string instance types. 2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left_instance_type = AddLoadStringInstanceType(left); 2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right_instance_type = AddLoadStringInstanceType(right); 2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute union and difference of instance types. 2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* ored_instance_types = AddUncasted<HBitwise>( 2225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_OR, left_instance_type, right_instance_type); 2226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* xored_instance_types = AddUncasted<HBitwise>( 2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_XOR, left_instance_type, right_instance_type); 2228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if both strings have the same encoding and both are 2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // sequential. 2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_sameencodingandsequential(this); 2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_sameencodingandsequential.If<HCompareNumericAndBranch>( 2233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HBitwise>( 2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, xored_instance_types, 2235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))), 2236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0(), Token::EQ); 2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_sameencodingandsequential.And(); 2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kSeqStringTag == 0); 2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_sameencodingandsequential.If<HCompareNumericAndBranch>( 2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HBitwise>( 2241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, ored_instance_types, 2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>(kStringRepresentationMask))), 2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0(), Token::EQ); 2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_sameencodingandsequential.Then(); 2245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* string_map = 2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(isolate()->factory()->string_map()); 2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* one_byte_string_map = 2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(isolate()->factory()->one_byte_string_map()); 2250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Determine map and size depending on whether result is one-byte string. 2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_onebyte(this); 2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kOneByteStringTag != 0); 2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.If<HCompareNumericAndBranch>( 2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HBitwise>( 2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, ored_instance_types, 2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))), 2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0(), Token::NE); 2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.Then(); 2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate sequential one-byte string object. 2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(length); 2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(one_byte_string_map); 2264257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.Else(); 2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate sequential two-byte string object. 2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* size = AddUncasted<HShl>(length, graph()->GetConstant1()); 2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size->ClearFlag(HValue::kCanOverflow); 2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size->SetFlag(HValue::kUint32); 2271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(size); 2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(string_map); 2273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.End(); 2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* map = Pop(); 2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calculate the number of bytes needed for the characters in the 2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // string while observing object alignment. 2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0); 2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* size = BuildObjectSizeAlignment(Pop(), SeqString::kHeaderSize); 2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate the string object. HAllocate does not care whether we pass 2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // STRING_TYPE or ONE_BYTE_STRING_TYPE here, so we just use STRING_TYPE. 2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocate* result = BuildAllocate( 2285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size, HType::String(), STRING_TYPE, allocation_mode); 2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForMap(), map); 2287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize the string fields. 2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(), 2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(String::kEmptyHashField)); 2291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length); 2292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy characters to the result string. 2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_twobyte(this); 2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_twobyte.If<HCompareObjectEqAndBranch>(map, string_map); 2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_twobyte.Then(); 2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy characters from the left string. 2299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCopySeqStringChars( 2300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left, graph()->GetConstant0(), String::TWO_BYTE_ENCODING, 2301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, graph()->GetConstant0(), String::TWO_BYTE_ENCODING, 2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left_length); 2303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy characters from the right string. 2305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCopySeqStringChars( 2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right, graph()->GetConstant0(), String::TWO_BYTE_ENCODING, 2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, left_length, String::TWO_BYTE_ENCODING, 2308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right_length); 2309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_twobyte.Else(); 2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy characters from the left string. 2313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCopySeqStringChars( 2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left, graph()->GetConstant0(), String::ONE_BYTE_ENCODING, 2315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, graph()->GetConstant0(), String::ONE_BYTE_ENCODING, 2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left_length); 2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy characters from the right string. 2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCopySeqStringChars( 2320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right, graph()->GetConstant0(), String::ONE_BYTE_ENCODING, 2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, left_length, String::ONE_BYTE_ENCODING, 2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right_length); 2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_twobyte.End(); 2325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count the native string addition. 2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddIncrementCounter(isolate()->counters()->string_add_native()); 2328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the sequential string. 2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(result); 2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_sameencodingandsequential.Else(); 2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fallback to the runtime to add the two strings. 2335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(left, right); 2336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Add<HCallRuntime>( 2337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->empty_string(), 2338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::FunctionForId(Runtime::kStringAdd), 2339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2)); 2340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_sameencodingandsequential.End(); 2342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_createcons.End(); 2344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Pop(); 2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildStringAdd( 2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left, 2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right, 2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocationMode allocation_mode) { 2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 2354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Determine string lengths. 2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left_length = AddLoadStringLength(left); 2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right_length = AddLoadStringLength(right); 2358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if left string is empty. 2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_leftempty(this); 2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_leftempty.If<HCompareNumericAndBranch>( 2362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left_length, graph()->GetConstant0(), Token::EQ); 2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_leftempty.Then(); 2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count the native string addition. 2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddIncrementCounter(isolate()->counters()->string_add_native()); 23678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Just return the right string. 2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(right); 2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_leftempty.Else(); 2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if right string is empty. 2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_rightempty(this); 2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_rightempty.If<HCompareNumericAndBranch>( 2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right_length, graph()->GetConstant0(), Token::EQ); 2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_rightempty.Then(); 2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count the native string addition. 2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddIncrementCounter(isolate()->counters()->string_add_native()); 2381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Just return the left string. 2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(left); 2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_rightempty.Else(); 2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Add the two non-empty strings. 2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(BuildUncheckedStringAdd(left, right, allocation_mode)); 2389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_rightempty.End(); 2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_leftempty.End(); 2393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Pop(); 2395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( 2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_object, 2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key, 2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* val, 2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_js_array, 2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind, 2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessType access_type, 2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadKeyedHoleMode load_mode, 2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch KeyedAccessStoreMode store_mode) { 2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((!IsExternalArrayElementsKind(elements_kind) && 2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !IsFixedTypedArrayElementsKind(elements_kind)) || 2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !is_js_array); 2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // No GVNFlag is necessary for ElementsKind if there is an explicit dependency 2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // on a HElementsTransition instruction. The flag can also be removed if the 2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // map to check has FAST_HOLEY_ELEMENTS, since there can be no further 2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ElementsKind transitions. Finally, the dependency can be removed for stores 2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the 2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // generated store code. 2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((elements_kind == FAST_HOLEY_ELEMENTS) || 2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (elements_kind == FAST_ELEMENTS && access_type == STORE)) { 2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object->ClearDependsOnFlag(kElementsKind); 2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); 2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool fast_elements = IsFastObjectElementsKind(elements_kind); 2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements = AddLoadElements(checked_object); 2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == STORE && (fast_elements || fast_smi_only_elements) && 2425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCheckMaps* check_cow_map = Add<HCheckMaps>( 2427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, isolate()->factory()->fixed_array_map()); 2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch check_cow_map->ClearDependsOnFlag(kElementsKind); 2429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* length = NULL; 2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_js_array) { 2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length = Add<HLoadNamedField>( 2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object->ActualValue(), checked_object, 2434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForArrayLength(elements_kind)); 2435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length = AddLoadFixedArrayLength(elements); 2437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length->set_type(HType::Smi()); 2439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_key = NULL; 2440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsExternalArrayElementsKind(elements_kind) || 2441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsFixedTypedArrayElementsKind(elements_kind)) { 2442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* backing_store; 2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsExternalArrayElementsKind(elements_kind)) { 2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch backing_store = Add<HLoadNamedField>( 2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, static_cast<HValue*>(NULL), 2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForExternalArrayExternalPointer()); 2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch backing_store = elements; 2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 2451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder length_checker(this); 2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); 2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.Then(); 2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder negative_checker(this); 2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( 2457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key, graph()->GetConstant0(), Token::GTE); 2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negative_checker.Then(); 2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = AddElementAccess( 2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch backing_store, key, val, bounds_check, elements_kind, access_type); 2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negative_checker.ElseDeopt("Negative key encountered"); 2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negative_checker.End(); 2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.End(); 2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(store_mode == STANDARD_STORE); 2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_key = Add<HBoundsCheck>(key, length); 2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddElementAccess( 2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch backing_store, checked_key, val, 2470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object, elements_kind, access_type); 2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fast_smi_only_elements || 2474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fast_elements || 2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsFastDoubleElementsKind(elements_kind)); 2476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // In case val is stored into a fast smi array, assure that the value is a smi 2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // before manipulating the backing store. Otherwise the actual store may 2479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // deopt, leaving the backing store in an invalid state. 2480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == STORE && IsFastSmiElementsKind(elements_kind) && 2481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !val->type().IsSmi()) { 2482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch val = AddUncasted<HForceRepresentation>(val, Representation::Smi()); 2483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsGrowStoreMode(store_mode)) { 2486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 2487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation representation = HStoreKeyed::RequiredValueRepresentation( 2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind, STORE_TO_INITIALIZED_ENTRY); 2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch val = AddUncasted<HForceRepresentation>(val, representation); 2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements = BuildCheckForCapacityGrow(checked_object, elements, 2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind, length, key, 2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_js_array, access_type); 2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_key = key; 2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_key = Add<HBoundsCheck>(key, length); 2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == STORE && (fast_elements || fast_smi_only_elements)) { 2498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { 2499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 2500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements = BuildCopyElementsOnWrite(checked_object, elements, 2501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind, length); 2502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCheckMaps* check_cow_map = Add<HCheckMaps>( 2504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, isolate()->factory()->fixed_array_map()); 2505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch check_cow_map->ClearDependsOnFlag(kElementsKind); 2506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 25073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddElementAccess(elements, checked_key, val, checked_object, 2510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind, access_type, load_mode); 2511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2512b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildAllocateArrayFromLength( 2515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSArrayBuilder* array_builder, 2516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length_argument) { 2517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (length_argument->IsConstant() && 2518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(length_argument)->HasSmiValue()) { 2519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int array_length = HConstant::cast(length_argument)->Integer32Value(); 2520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (array_length == 0) { 2521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return array_builder->AllocateEmptyArray(); 2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return array_builder->AllocateArray(length_argument, 2524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array_length, 2525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_argument); 2526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* constant_zero = graph()->GetConstant0(); 2530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* max_alloc_length = 2531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(JSObject::kInitialMaxFastElementArray); 2532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* checked_length = Add<HBoundsCheck>(length_argument, 2533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_alloc_length); 2534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_builder(this); 2535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_builder.If<HCompareNumericAndBranch>(checked_length, constant_zero, 2536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::EQ); 2537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_builder.Then(); 2538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int initial_capacity = JSArray::kPreallocatedArrayElements; 2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* initial_capacity_node = Add<HConstant>(initial_capacity); 2540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(initial_capacity_node); // capacity 2541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(constant_zero); // length 2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_builder.Else(); 2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!(top_info()->IsStub()) && 2544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsFastPackedElementsKind(array_builder->kind())) { 2545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We'll come back later with better (holey) feedback. 2546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_builder.Deopt("Holey array despite packed elements_kind feedback"); 2547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(checked_length); // capacity 2549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(checked_length); // length 2550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_builder.End(); 2552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Figure out total size 2554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length = Pop(); 2555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* capacity = Pop(); 2556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return array_builder->AllocateArray(capacity, max_alloc_length, length); 2557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildCalculateElementsSize(ElementsKind kind, 2561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* capacity) { 2562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int elements_size = IsFastDoubleElementsKind(kind) 2563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? kDoubleSize 2564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : kPointerSize; 2565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* elements_size_value = Add<HConstant>(elements_size); 2567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* mul = HMul::NewImul(zone(), context(), 2568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch capacity->ActualValue(), 2569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_size_value); 2570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(mul); 2571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mul->ClearFlag(HValue::kCanOverflow); 2572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize); 2574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); 2576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* total_size = AddUncasted<HAdd>(mul, header_size); 2577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total_size->ClearFlag(HValue::kCanOverflow); 2578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return total_size; 2579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHAllocate* HGraphBuilder::AllocateJSArrayObject(AllocationSiteMode mode) { 2583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int base_size = JSArray::kSize; 2584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode == TRACK_ALLOCATION_SITE) { 2585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base_size += AllocationMemento::kSize; 2586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* size_in_bytes = Add<HConstant>(base_size); 2588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HAllocate>( 2589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_in_bytes, HType::JSArray(), NOT_TENURED, JS_OBJECT_TYPE); 2590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2591b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2592b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHConstant* HGraphBuilder::EstablishElementsAllocationSize( 2594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 2595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int capacity) { 2596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int base_size = IsFastDoubleElementsKind(kind) 2597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? FixedDoubleArray::SizeFor(capacity) 2598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : FixedArray::SizeFor(capacity); 2599b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HConstant>(base_size); 2601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHAllocate* HGraphBuilder::BuildAllocateElements(ElementsKind kind, 2605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* size_in_bytes) { 2606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstanceType instance_type = IsFastDoubleElementsKind(kind) 2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? FIXED_DOUBLE_ARRAY_TYPE 2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : FIXED_ARRAY_TYPE; 2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HAllocate>(size_in_bytes, HType::HeapObject(), NOT_TENURED, 2611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instance_type); 2612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2613589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 2614589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, 2616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* capacity) { 2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate()->factory(); 2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = IsFastDoubleElementsKind(kind) 2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? factory->fixed_double_array_map() 2621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : factory->fixed_array_map(); 2622589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 2623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(elements, HObjectAccess::ForMap(), Add<HConstant>(map)); 2624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), 2625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch capacity); 2626b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2627b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2628b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( 2630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 2631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* capacity) { 2632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The HForceRepresentation is to prevent possible deopt on int-smi 2633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // conversion after allocation but before the new object fields are set. 2634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi()); 2635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* size_in_bytes = BuildCalculateElementsSize(kind, capacity); 2636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_elements = BuildAllocateElements(kind, size_in_bytes); 2637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildInitializeElementsHeader(new_elements, kind, capacity); 2638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new_elements; 2639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2640b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2641b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildJSArrayHeader(HValue* array, 2643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* array_map, 2644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements, 2645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteMode mode, 2646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind, 2647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* allocation_site_payload, 2648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length_field) { 2649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map); 2650b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* empty_fixed_array = 2652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(isolate()->factory()->empty_fixed_array()); 2653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 2655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array, HObjectAccess::ForPropertiesPointer(), empty_fixed_array); 2656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 2658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array, HObjectAccess::ForElementsPointer(), 2659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements != NULL ? elements : empty_fixed_array); 2660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 2662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array, HObjectAccess::ForArrayLength(elements_kind), length_field); 2663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode == TRACK_ALLOCATION_SITE) { 2665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCreateAllocationMemento( 2666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array, Add<HConstant>(JSArray::kSize), allocation_site_payload); 2667257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2669257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::AddElementAccess( 2672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements, 2673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_key, 2674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* val, 2675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dependency, 2676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind, 2677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessType access_type, 2678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadKeyedHoleMode load_mode) { 2679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == STORE) { 2680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(val != NULL); 2681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS || 2682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind == UINT8_CLAMPED_ELEMENTS) { 2683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch val = Add<HClampToUint8>(val); 2684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HStoreKeyed>(elements, checked_key, val, elements_kind, 2686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STORE_TO_INITIALIZED_ENTRY); 2687b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2688b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(access_type == LOAD); 2690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(val == NULL); 2691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoadKeyed* load = Add<HLoadKeyed>( 2692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, checked_key, dependency, elements_kind, load_mode); 2693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_opt_safe_uint32_operations && 2694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (elements_kind == EXTERNAL_UINT32_ELEMENTS || 2695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind == UINT32_ELEMENTS)) { 2696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->RecordUint32Instruction(load); 2697b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return load; 2699b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2700b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2701b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHLoadNamedField* HGraphBuilder::AddLoadMap(HValue* object, 2703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dependency) { 2704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HLoadNamedField>(object, dependency, HObjectAccess::ForMap()); 2705b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2706b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2707b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, 2709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dependency) { 2710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HLoadNamedField>( 2711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, dependency, HObjectAccess::ForElementsPointer()); 2712b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2713b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2714b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength( 2716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* array, 2717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dependency) { 2718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HLoadNamedField>( 2719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array, dependency, HObjectAccess::ForFixedArrayLength()); 2720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2721b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2722b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHLoadNamedField* HGraphBuilder::AddLoadArrayLength(HValue* array, 2724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 2725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dependency) { 2726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HLoadNamedField>( 2727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array, dependency, HObjectAccess::ForArrayLength(kind)); 2728b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2729b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2730b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildNewElementsCapacity(HValue* old_capacity) { 2732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* half_old_capacity = AddUncasted<HShr>(old_capacity, 2733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph_->GetConstant1()); 2734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_capacity = AddUncasted<HAdd>(half_old_capacity, old_capacity); 2736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_capacity->ClearFlag(HValue::kCanOverflow); 2737b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* min_growth = Add<HConstant>(16); 2739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_capacity = AddUncasted<HAdd>(new_capacity, min_growth); 2741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_capacity->ClearFlag(HValue::kCanOverflow); 2742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new_capacity; 2744b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2745b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2746b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, 2748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements, 2749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 2750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind new_kind, 2751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length, 2752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_capacity) { 2753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HBoundsCheck>(new_capacity, Add<HConstant>( 2754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (Page::kMaxRegularHeapObjectSize - FixedArray::kHeaderSize) >> 2755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKindToShiftSize(new_kind))); 2756257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_elements = BuildAllocateElementsAndInitializeElementsHeader( 2758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_kind, new_capacity); 2759b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCopyElements(elements, kind, new_elements, 2761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_kind, length, new_capacity); 2762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 2764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_elements); 2765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new_elements; 2767b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2768b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2769b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildFillElementsWithValue(HValue* elements, 2771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind, 2772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* from, 2773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* to, 2774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value) { 2775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (to == NULL) { 2776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to = AddLoadFixedArrayLength(elements); 2777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Special loop unfolding case 2780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(JSArray::kPreallocatedArrayElements <= 2781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kElementLoopUnrollThreshold); 2782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int initial_capacity = -1; 2783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (from->IsInteger32Constant() && to->IsInteger32Constant()) { 2784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int constant_from = from->GetInteger32Constant(); 2785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int constant_to = to->GetInteger32Constant(); 2786b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (constant_from == 0 && constant_to <= kElementLoopUnrollThreshold) { 2788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch initial_capacity = constant_to; 2789b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2790b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Since we're about to store a hole value, the store instruction below must 2793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // assume an elements kind that supports heap object values. 2794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFastSmiOrObjectElementsKind(elements_kind)) { 2795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind = FAST_HOLEY_ELEMENTS; 2796b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2797b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (initial_capacity >= 0) { 2799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < initial_capacity; i++) { 2800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* key = Add<HConstant>(i); 2801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreKeyed>(elements, key, value, elements_kind); 2802b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Carefully loop backwards so that the "from" remains live through the loop 2805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // rather than the to. This often corresponds to keeping length live rather 2806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // then capacity, which helps register allocation, since length is used more 2807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // other than capacity after filling with holes. 2808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); 2809b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = builder.BeginBody(to, from, Token::GT); 2811b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* adjusted_key = AddUncasted<HSub>(key, graph()->GetConstant1()); 2813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch adjusted_key->ClearFlag(HValue::kCanOverflow); 2814b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreKeyed>(elements, adjusted_key, value, elements_kind); 2816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder.EndBody(); 28187d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch } 28197d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch} 28207d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch 28217d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch 2822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildFillElementsWithHole(HValue* elements, 2823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind, 2824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* from, 2825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* to) { 2826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fast elements kinds need to be initialized in case statements below cause a 2827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // garbage collection. 2828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate()->factory(); 2829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double nan_double = FixedDoubleArray::hole_nan_as_double(); 2831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) 2832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? Add<HConstant>(factory->the_hole_value()) 2833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Add<HConstant>(nan_double); 2834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildFillElementsWithValue(elements, elements_kind, from, to, hole); 28367d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch} 28377d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch 28387d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch 2839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildCopyElements(HValue* from_elements, 2840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind from_elements_kind, 2841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* to_elements, 2842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind to_elements_kind, 2843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length, 2844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* capacity) { 2845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int constant_capacity = -1; 2846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (capacity != NULL && 2847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch capacity->IsConstant() && 2848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(capacity)->HasInteger32Value()) { 2849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int constant_candidate = HConstant::cast(capacity)->Integer32Value(); 2850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (constant_candidate <= kElementLoopUnrollThreshold) { 2851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_capacity = constant_candidate; 28521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 28531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 28541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool pre_fill_with_holes = 2856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsFastDoubleElementsKind(from_elements_kind) && 2857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsFastObjectElementsKind(to_elements_kind); 2858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (pre_fill_with_holes) { 2859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the copy might trigger a GC, make sure that the FixedArray is 2860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pre-initialized with holes to make sure that it's always in a 2861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // consistent state. 2862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildFillElementsWithHole(to_elements, to_elements_kind, 2863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0(), NULL); 2864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 28651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (constant_capacity != -1) { 2867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Unroll the loop for small elements kinds. 2868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < constant_capacity; i++) { 2869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key_constant = Add<HConstant>(i); 2870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* value = Add<HLoadKeyed>(from_elements, key_constant, 2871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<HValue*>(NULL), 2872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch from_elements_kind); 2873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreKeyed>(to_elements, key_constant, value, to_elements_kind); 2874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!pre_fill_with_holes && 2877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (capacity == NULL || !length->Equals(capacity))) { 2878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildFillElementsWithHole(to_elements, to_elements_kind, 2879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length, NULL); 2880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (capacity == NULL) { 2883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch capacity = AddLoadFixedArrayLength(to_elements); 2884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); 2887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = builder.BeginBody(length, graph()->GetConstant0(), 2889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::GT); 2890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key = AddUncasted<HSub>(key, graph()->GetConstant1()); 2892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key->ClearFlag(HValue::kCanOverflow); 2893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* element = Add<HLoadKeyed>(from_elements, key, 2895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<HValue*>(NULL), 2896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch from_elements_kind, 2897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOW_RETURN_HOLE); 2898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind = (IsHoleyElementsKind(from_elements_kind) && 2900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsFastSmiElementsKind(to_elements_kind)) 2901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? FAST_HOLEY_ELEMENTS : to_elements_kind; 2902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsHoleyElementsKind(from_elements_kind) && 2904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch from_elements_kind != to_elements_kind) { 2905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_hole(this); 2906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_hole.If<HCompareHoleAndBranch>(element); 2907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_hole.Then(); 2908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* hole_constant = IsFastDoubleElementsKind(to_elements_kind) 2909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? Add<HConstant>(FixedDoubleArray::hole_nan_as_double()) 2910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : graph()->GetConstantHole(); 2911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreKeyed>(to_elements, key, hole_constant, kind); 2912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_hole.Else(); 2913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind); 2914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store->SetFlag(HValue::kAllowUndefinedAsNaN); 2915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_hole.End(); 2916e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 2917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind); 2918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store->SetFlag(HValue::kAllowUndefinedAsNaN); 2919e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder.EndBody(); 2922e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2923e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Counters* counters = isolate()->counters(); 2925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddIncrementCounter(counters->inlined_copied_elements()); 2926e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 2927e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2928e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildCloneShallowArrayCow(HValue* boilerplate, 2930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* allocation_site, 2931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteMode mode, 2932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind) { 2933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocate* array = AllocateJSArrayObject(mode); 2934e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* map = AddLoadMap(boilerplate); 2936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements = AddLoadElements(boilerplate); 2937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length = AddLoadArrayLength(boilerplate, kind); 2938e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildJSArrayHeader(array, 2940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map, 2941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, 2942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode, 2943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FAST_ELEMENTS, 2944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_site, 2945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length); 2946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return array; 2947b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2948b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2949b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildCloneShallowArrayEmpty(HValue* boilerplate, 2951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* allocation_site, 2952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteMode mode) { 2953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocate* array = AllocateJSArrayObject(mode); 2954b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* map = AddLoadMap(boilerplate); 2956b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildJSArrayHeader(array, 2958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map, 2959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL, // set elements to empty fixed array 2960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode, 2961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FAST_ELEMENTS, 2962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_site, 2963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0()); 2964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return array; 2965b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2966b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2967b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildCloneShallowArrayNonEmpty(HValue* boilerplate, 2969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* allocation_site, 2970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteMode mode, 2971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind) { 2972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* boilerplate_elements = AddLoadElements(boilerplate); 2973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* capacity = AddLoadFixedArrayLength(boilerplate_elements); 2974b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generate size calculation code here in order to make it dominate 2976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the JSArray allocation. 2977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements_size = BuildCalculateElementsSize(kind, capacity); 2978b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create empty JSArray object for now, store elimination should remove 2980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // redundant initialization of elements and length fields and at the same 2981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // time the object will be fully prepared for GC if it happens during 2982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // elements allocation. 2983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result = BuildCloneShallowArrayEmpty( 2984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate, allocation_site, mode); 2985b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocate* elements = BuildAllocateElements(kind, elements_size); 2987b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This function implicitly relies on the fact that the 2989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // FastCloneShallowArrayStub is called only for literals shorter than 2990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JSObject::kInitialMaxFastElementArray. 2991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Can't add HBoundsCheck here because otherwise the stub will eager a frame. 2992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* size_upper_bound = EstablishElementsAllocationSize( 2993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind, JSObject::kInitialMaxFastElementArray); 2994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements->set_size_upper_bound(size_upper_bound); 2995b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForElementsPointer(), elements); 2997b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The allocation for the cloned array above causes register pressure on 2999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // machines with low register counts. Force a reload of the boilerplate 3000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // elements here to free up a register for the allocation to avoid unnecessary 3001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // spillage. 3002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate_elements = AddLoadElements(boilerplate); 3003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate_elements->SetFlag(HValue::kCantBeReplaced); 3004b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy the elements array header. 3006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { 3007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); 3008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(elements, access, 3009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadNamedField>(boilerplate_elements, 3010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<HValue*>(NULL), access)); 3011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3012b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // And the result of the length 3014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length = AddLoadArrayLength(boilerplate, kind); 3015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForArrayLength(kind), length); 3016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCopyElements(boilerplate_elements, kind, elements, 3018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind, length, NULL); 3019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 3020b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3021b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3022b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildCompareNil( 3024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value, 3025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* type, 3026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIfContinuation* continuation) { 3027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_nil(this); 3028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool some_case_handled = false; 3029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool some_case_missing = false; 30303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type->Maybe(Type::Null())) { 3032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (some_case_handled) if_nil.Or(); 3033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull()); 3034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch some_case_handled = true; 3035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch some_case_missing = true; 3037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 30383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type->Maybe(Type::Undefined())) { 3040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (some_case_handled) if_nil.Or(); 3041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_nil.If<HCompareObjectEqAndBranch>(value, 3042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstantUndefined()); 3043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch some_case_handled = true; 3044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch some_case_missing = true; 3046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type->Maybe(Type::Undetectable())) { 3049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (some_case_handled) if_nil.Or(); 3050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_nil.If<HIsUndetectableAndBranch>(value); 3051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch some_case_handled = true; 3052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch some_case_missing = true; 3054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (some_case_missing) { 3057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_nil.Then(); 3058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_nil.Else(); 3059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type->NumClasses() == 1) { 3060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(value); 3061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For ICs, the map checked below is a sentinel map that gets replaced by 3062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the monomorphic map when the code is used as a template to generate a 3063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // new IC. For optimized functions, there is no sentinel map, the map 3064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // emitted below is the actual monomorphic map. 3065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckMaps>(value, type->Classes().Current()); 3066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_nil.Deopt("Too many undetectable types"); 3068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_nil.CaptureContinuation(continuation); 3072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildCreateAllocationMemento( 3076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* previous_object, 3077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* previous_object_size, 3078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* allocation_site) { 3079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(allocation_site != NULL); 3080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInnerAllocatedObject* allocation_memento = Add<HInnerAllocatedObject>( 3081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch previous_object, previous_object_size, HType::HeapObject()); 3082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddStoreMapConstant( 3083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_memento, isolate()->factory()->allocation_memento_map()); 3084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 3085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_memento, 3086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForAllocationMementoSite(), 3087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_site); 3088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_allocation_site_pretenuring) { 3089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* memento_create_count = Add<HLoadNamedField>( 3090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_site, static_cast<HValue*>(NULL), 3091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForAllocationSiteOffset( 3092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSite::kPretenureCreateCountOffset)); 3093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memento_create_count = AddUncasted<HAdd>( 3094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memento_create_count, graph()->GetConstant1()); 3095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This smi value is reset to zero after every gc, overflow isn't a problem 3096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // since the counter is bounded by the new space size. 3097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memento_create_count->ClearFlag(HValue::kCanOverflow); 3098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 3099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_site, HObjectAccess::ForAllocationSiteOffset( 3100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSite::kPretenureCreateCountOffset), memento_create_count); 3101257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 3102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::BuildGetNativeContext(HValue* closure) { 3106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Get the global context, then the native context 3107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* context = 3108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadNamedField>(closure, static_cast<HValue*>(NULL), 3109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForFunctionContextPointer()); 3110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* global_object = Add<HLoadNamedField>( 3111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context, static_cast<HValue*>(NULL), 3112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 3113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( 3114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GlobalObject::kNativeContextOffset); 3115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HLoadNamedField>( 3116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_object, static_cast<HValue*>(NULL), access); 31173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 31183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 31193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::BuildGetNativeContext() { 3121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Get the global context, then the native context 3122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* global_object = Add<HLoadNamedField>( 3123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context(), static_cast<HValue*>(NULL), 3124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 3125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HLoadNamedField>( 3126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_object, static_cast<HValue*>(NULL), 3127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForObservableJSObjectOffset( 3128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GlobalObject::kNativeContextOffset)); 3129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::BuildGetArrayFunction() { 3133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* native_context = BuildGetNativeContext(); 3134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* index = 3135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX)); 3136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HLoadKeyed>( 3137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 31383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 31393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 31403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, 3142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 3143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* allocation_site_payload, 3144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* constructor_function, 3145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteOverrideMode override_mode) : 3146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_(builder), 3147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind_(kind), 3148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_site_payload_(allocation_site_payload), 3149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constructor_function_(constructor_function) { 3150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!allocation_site_payload->IsConstant() || 3151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(allocation_site_payload)->handle( 3152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->isolate())->IsAllocationSite()); 3153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode_ = override_mode == DISABLE_ALLOCATION_SITES 3154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? DONT_TRACK_ALLOCATION_SITE 3155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : AllocationSite::GetMode(kind); 3156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, 3160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 3161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* constructor_function) : 3162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_(builder), 3163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind_(kind), 3164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode_(DONT_TRACK_ALLOCATION_SITE), 3165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_site_payload_(NULL), 3166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constructor_function_(constructor_function) { 3167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() { 3171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!builder()->top_info()->IsStub()) { 3172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // A constant map is fine. 3173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map(builder()->isolate()->get_initial_js_array_map(kind_), 3174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->isolate()); 3175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return builder()->Add<HConstant>(map); 3176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (constructor_function_ != NULL && kind_ == GetInitialFastElementsKind()) { 3179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // No need for a context lookup if the kind_ matches the initial 3180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // map, because we can just load the map in that case. 3181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 3182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return builder()->Add<HLoadNamedField>( 3183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constructor_function_, static_cast<HValue*>(NULL), access); 3184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3185053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block 3186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(mvstanton): we should always have a constructor function if we 3187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // are creating a stub. 3188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* native_context = constructor_function_ != NULL 3189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? builder()->BuildGetNativeContext(constructor_function_) 3190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : builder()->BuildGetNativeContext(); 3191053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block 3192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* index = builder()->Add<HConstant>( 3193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); 3194b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* map_array = builder()->Add<HLoadKeyed>( 3196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 3197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* kind_index = builder()->Add<HConstant>(kind_); 3199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return builder()->Add<HLoadKeyed>( 3201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 3202b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3203b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3204b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { 3206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find the map near the constructor function 3207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 3208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return builder()->Add<HLoadNamedField>( 3209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constructor_function_, static_cast<HValue*>(NULL), access); 3210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHAllocate* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { 3214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); 3215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AllocateArray(capacity, 3216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch capacity, 3217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->graph()->GetConstant0()); 3218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3219b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( 3222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* capacity, 3223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* capacity_upper_bound, 3224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length_field, 3225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FillMode fill_mode) { 3226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AllocateArray(capacity, 3227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch capacity_upper_bound->GetInteger32Constant(), 3228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_field, 3229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fill_mode); 32308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch} 32318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 32328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 3233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( 3234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* capacity, 3235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int capacity_upper_bound, 3236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length_field, 3237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FillMode fill_mode) { 3238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* elememts_size_upper_bound = capacity->IsInteger32Constant() 3239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? HConstant::cast(capacity) 3240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : builder()->EstablishElementsAllocationSize(kind_, capacity_upper_bound); 32418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 3242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocate* array = AllocateArray(capacity, length_field, fill_mode); 3243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!elements_location_->has_size_upper_bound()) { 3244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_location_->set_size_upper_bound(elememts_size_upper_bound); 3245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return array; 3247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( 3251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* capacity, 3252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length_field, 3253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FillMode fill_mode) { 3254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // These HForceRepresentations are because we store these as fields in the 3255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // objects we construct, and an int32-to-smi HChange could deopt. Accept 3256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the deopt possibility now, before allocation occurs. 3257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch capacity = 3258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->AddUncasted<HForceRepresentation>(capacity, 3259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation::Smi()); 3260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_field = 3261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->AddUncasted<HForceRepresentation>(length_field, 3262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation::Smi()); 3263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generate size calculation code here in order to make it dominate 3265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the JSArray allocation. 3266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements_size = 3267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->BuildCalculateElementsSize(kind_, capacity); 3268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate (dealing with failure appropriately) 3270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocate* array_object = builder()->AllocateJSArrayObject(mode_); 3271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fill in the fields: map, properties, length 3273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* map; 3274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (allocation_site_payload_ == NULL) { 3275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map = EmitInternalMapCode(); 3276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map = EmitMapCode(); 3278e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 3279e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->BuildJSArrayHeader(array_object, 3281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map, 3282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL, // set elements to empty fixed array 3283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode_, 3284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind_, 3285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_site_payload_, 3286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_field); 3287e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate and initialize the elements 3289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_location_ = builder()->BuildAllocateElements(kind_, elements_size); 3290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity); 32923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set the elements 3294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->Add<HStoreNamedField>( 3295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array_object, HObjectAccess::ForElementsPointer(), elements_location_); 32963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (fill_mode == FILL_WITH_HOLE) { 3298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->BuildFillElementsWithHole(elements_location_, kind_, 3299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0(), capacity); 3300589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 33013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return array_object; 3303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 33045d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 3305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin) { 3307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* global_object = Add<HLoadNamedField>( 3308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context(), static_cast<HValue*>(NULL), 3309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 3310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( 3311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GlobalObject::kBuiltinsOffset); 3312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* builtins = Add<HLoadNamedField>( 3313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_object, static_cast<HValue*>(NULL), access); 3314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess function_access = HObjectAccess::ForObservableJSObjectOffset( 3315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSBuiltinsObject::OffsetOfFunctionWithId(builtin)); 3316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HLoadNamedField>( 3317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builtins, static_cast<HValue*>(NULL), function_access); 3318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) 3322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : HGraphBuilder(info), 3323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state_(NULL), 3324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch initial_function_state_(this, info, NORMAL_RETURN, 0), 3325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context_(NULL), 3326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_scope_(NULL), 3327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inlined_count_(0), 3328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch globals_(10, info->zone()), 3329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr_(new(info->zone()) HOsrBuilder(this)) { 3330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This is not initialized in the initializer list because the 3331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // constructor for the initial state relies on function_state_ == NULL 3332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to know it's the initial state. 3333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state_= &initial_function_state_; 3334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeAstVisitor(info->zone()); 3335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_hydrogen_track_positions) { 3336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetSourcePosition(info->shared_info()->start_position()); 3337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 334069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HOptimizedGraphBuilder::CreateJoin(HBasicBlock* first, 3342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* second, 3343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId join_id) { 3344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (first == NULL) { 3345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return second; 3346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (second == NULL) { 3347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return first; 3348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join_block = graph()->CreateBasicBlock(); 3350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(first, join_block); 3351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(second, join_block); 3352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch join_block->SetJoinId(join_id); 3353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return join_block; 3354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 335669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 33577d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch 3358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HOptimizedGraphBuilder::JoinContinue(IterationStatement* statement, 3359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* exit_block, 3360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* continue_block) { 3361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (continue_block != NULL) { 3362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (exit_block != NULL) Goto(exit_block, continue_block); 3363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue_block->SetJoinId(statement->ContinueId()); 3364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return continue_block; 3365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return exit_block; 3367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HOptimizedGraphBuilder::CreateLoop(IterationStatement* statement, 3371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_entry, 3372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* body_exit, 3373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_successor, 3374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* break_block) { 3375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (body_exit != NULL) Goto(body_exit, loop_entry); 3376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_entry->PostProcessLoopHeader(statement); 3377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (break_block != NULL) { 3378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (loop_successor != NULL) Goto(loop_successor, break_block); 3379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_block->SetJoinId(statement->ExitId()); 3380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return break_block; 33817d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch } 3382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return loop_successor; 33837d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch} 33847d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch 33857d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch 3386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Build a new loop header block and set it as the current block. 3387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry() { 3388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_entry = CreateLoopHeaderBlock(); 3389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(loop_entry); 3390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(loop_entry); 3391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return loop_entry; 3392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry( 3396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IterationStatement* statement) { 3397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_entry = osr()->HasOsrEntryAt(statement) 3398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? osr()->BuildOsrLoopEntry(statement) 3399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : BuildLoopEntry(); 3400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return loop_entry; 3401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HBasicBlock::FinishExit(HControlInstruction* instruction, 3405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HSourcePosition position) { 3406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Finish(instruction, position); 3407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearEnvironment(); 3408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOStream& operator<<(OStream& os, const HBasicBlock& b) { 3412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return os << "B" << b.block_id(); 3413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraph::HGraph(CompilationInfo* info) 3417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : isolate_(info->isolate()), 3418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_block_id_(0), 3419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_block_(NULL), 3420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocks_(8, info->zone()), 3421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values_(16, info->zone()), 3422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch phi_list_(NULL), 3423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_instructions_(NULL), 3424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr_(NULL), 3425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info_(info), 3426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone_(info->zone()), 3427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_recursive_(false), 3428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_optimistic_licm_(false), 3429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch depends_on_empty_array_proto_elements_(false), 3430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch type_change_checksum_(0), 3431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch maximum_environment_size_(0), 3432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch no_side_effects_scope_count_(0), 3433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch disallow_adding_new_values_(false), 3434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_inline_id_(0), 3435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inlined_functions_(5, info->zone()) { 3436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->IsStub()) { 3437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallInterfaceDescriptor descriptor = 3438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->code_stub()->GetCallInterfaceDescriptor(); 3439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch start_environment_ = new (zone_) 3440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment(zone_, descriptor.GetEnvironmentParameterCount()); 3441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInlinedFunction(info->shared_info(), HSourcePosition::Unknown()); 3443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch start_environment_ = 3444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); 3445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch start_environment_->set_ast_id(BailoutId::FunctionEntry()); 3447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_block_ = CreateBasicBlock(); 3448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_block_->SetInitialEnvironment(start_environment_); 3449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HGraph::CreateBasicBlock() { 3453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* result = new(zone()) HBasicBlock(this); 3454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocks_.Add(result, zone()); 3455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 3456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 34573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3458257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraph::FinalizeUniqueness() { 3460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 3461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); 3462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < blocks()->length(); ++i) { 3463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { 3464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch it.Current()->FinalizeUniqueness(); 3465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3469257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint HGraph::TraceInlinedFunction( 3471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<SharedFunctionInfo> shared, 3472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HSourcePosition position) { 3473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_hydrogen_track_positions) { 3474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return 0; 3475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int id = 0; 3478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (; id < inlined_functions_.length(); id++) { 3479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (inlined_functions_[id].shared().is_identical_to(shared)) { 3480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 3481e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 34823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (id == inlined_functions_.length()) { 3485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inlined_functions_.Add(InlinedFunctionInfo(shared), zone()); 3486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!shared->script()->IsUndefined()) { 3488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Script> script(Script::cast(shared->script())); 3489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!script->source()->IsUndefined()) { 3490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeTracer::Scope tracing_scopex(isolate()->GetCodeTracer()); 3491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(tracing_scopex.file()); 3492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << "--- FUNCTION SOURCE (" << shared->DebugName()->ToCString().get() 3493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch << ") id{" << info()->optimization_id() << "," << id << "} ---\n"; 3494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 3495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConsStringIteratorOp op; 3496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StringCharacterStream stream(String::cast(script->source()), 3497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &op, 3498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared->start_position()); 3499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // fun->end_position() points to the last character in the stream. We 3500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // need to compensate by adding one to calculate the length. 3501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int source_len = 3502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared->end_position() - shared->start_position() + 1; 3503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < source_len; i++) { 3504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stream.HasMore()) { 3505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << AsReversiblyEscapedUC16(stream.GetNext()); 3506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3509b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << "\n--- END ---\n"; 3511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3514b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int inline_id = next_inline_id_++; 3516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (inline_id != 0) { 3518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); 3519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(tracing_scope.file()); 3520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << "INLINE (" << shared->DebugName()->ToCString().get() << ") id{" 3521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch << info()->optimization_id() << "," << id << "} AS " << inline_id 3522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch << " AT " << position << endl; 3523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return inline_id; 3526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint HGraph::SourcePositionToScriptPosition(HSourcePosition pos) { 3530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_hydrogen_track_positions || pos.IsUnknown()) { 3531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return pos.raw(); 3532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return inlined_functions_[pos.inlining_id()].start_position() + 3535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pos.position(); 3536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Block ordering was implemented with two mutually recursive methods, 3540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// HGraph::Postorder and HGraph::PostorderLoopBlocks. 3541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The recursion could lead to stack overflow so the algorithm has been 3542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// implemented iteratively. 3543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// At a high level the algorithm looks like this: 3544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Postorder(block, loop_header) : { 3546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// if (block has already been visited or is of another loop) return; 3547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// mark block as visited; 3548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// if (block is a loop header) { 3549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// VisitLoopMembers(block, loop_header); 3550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// VisitSuccessorsOfLoopHeader(block); 3551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } else { 3552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// VisitSuccessors(block) 3553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 3554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// put block in result list; 3555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 3556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// VisitLoopMembers(block, outer_loop_header) { 3558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// foreach (block b in block loop members) { 3559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// VisitSuccessorsOfLoopMember(b, outer_loop_header); 3560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// if (b is loop header) VisitLoopMembers(b); 3561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 3562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 3563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// VisitSuccessorsOfLoopMember(block, outer_loop_header) { 3565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// foreach (block b in block successors) Postorder(b, outer_loop_header) 3566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 3567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// VisitSuccessorsOfLoopHeader(block) { 3569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// foreach (block b in block successors) Postorder(b, block) 3570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 3571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// VisitSuccessors(block, loop_header) { 3573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// foreach (block b in block successors) Postorder(b, loop_header) 3574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 3575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The ordering is started calling Postorder(entry, NULL). 3577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Each instance of PostorderProcessor represents the "stack frame" of the 3579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// recursion, and particularly keeps the state of the loop (iteration) of the 3580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// "Visit..." function it represents. 3581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// To recycle memory we keep all the frames in a double linked list but 3582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// this means that we cannot use constructors to initialize the frames. 3583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PostorderProcessor : public ZoneObject { 3585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 3586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Back link (towards the stack bottom). 3587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* parent() {return father_; } 3588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Forward link (towards the stack top). 3589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* child() {return child_; } 3590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block() { return block_; } 3591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoopInformation* loop() { return loop_; } 3592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_header() { return loop_header_; } 3593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static PostorderProcessor* CreateEntryProcessor(Zone* zone, 3595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block) { 3596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* result = new(zone) PostorderProcessor(NULL); 3597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result->SetupSuccessors(zone, block, NULL); 3598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* PerformStep(Zone* zone, 3601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<HBasicBlock*>* order) { 3602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* next = 3603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PerformNonBacktrackingStep(zone, order); 3604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (next != NULL) { 3605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return next; 3606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Backtrack(zone, order); 3608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3610b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 3612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit PostorderProcessor(PostorderProcessor* father) 3613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : father_(father), child_(NULL), successor_iterator(NULL) { } 3614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Each enum value states the cycle whose state is kept by this instance. 3616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum LoopKind { 3617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NONE, 3618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SUCCESSORS, 3619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SUCCESSORS_OF_LOOP_HEADER, 3620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOOP_MEMBERS, 3621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SUCCESSORS_OF_LOOP_MEMBER 3622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 3623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Each "Setup..." method is like a constructor for a cycle state. 3625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* SetupSuccessors(Zone* zone, 3626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block, 3627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_header) { 3628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block == NULL || block->IsOrdered() || 3629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block->parent_loop_header() != loop_header) { 3630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind_ = NONE; 3631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_ = NULL; 3632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_ = NULL; 3633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_header_ = NULL; 3634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return this; 3635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_ = block; 3637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_ = NULL; 3638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block->MarkAsOrdered(); 3639b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block->IsLoopHeader()) { 3641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind_ = SUCCESSORS_OF_LOOP_HEADER; 3642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_header_ = block; 3643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeSuccessors(); 3644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* result = Push(zone); 3645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result->SetupLoopMembers(zone, block, block->loop_information(), 3646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_header); 3647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(block->IsFinished()); 3649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind_ = SUCCESSORS; 3650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_header_ = loop_header; 3651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeSuccessors(); 3652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return this; 3653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3656b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* SetupLoopMembers(Zone* zone, 3658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block, 3659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoopInformation* loop, 3660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_header) { 3661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind_ = LOOP_MEMBERS; 3662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_ = block; 3663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_ = loop; 3664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_header_ = loop_header; 3665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeLoopMembers(); 3666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return this; 3667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* SetupSuccessorsOfLoopMember( 3670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block, 3671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoopInformation* loop, 3672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_header) { 3673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind_ = SUCCESSORS_OF_LOOP_MEMBER; 3674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_ = block; 3675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_ = loop; 3676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_header_ = loop_header; 3677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeSuccessors(); 3678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return this; 3679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This method "allocates" a new stack frame. 3682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* Push(Zone* zone) { 3683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (child_ == NULL) { 3684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch child_ = new(zone) PostorderProcessor(this); 3685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return child_; 3687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClosePostorder(ZoneList<HBasicBlock*>* order, Zone* zone) { 3690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(block_->end()->FirstSuccessor() == NULL || 3691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch order->Contains(block_->end()->FirstSuccessor()) || 3692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_->end()->FirstSuccessor()->IsLoopHeader()); 3693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(block_->end()->SecondSuccessor() == NULL || 3694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch order->Contains(block_->end()->SecondSuccessor()) || 3695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_->end()->SecondSuccessor()->IsLoopHeader()); 3696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch order->Add(block_, zone); 3697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This method is the basic block to walk up the stack. 3700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* Pop(Zone* zone, 3701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<HBasicBlock*>* order) { 3702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (kind_) { 3703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case SUCCESSORS: 3704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case SUCCESSORS_OF_LOOP_HEADER: 3705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClosePostorder(order, zone); 3706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return father_; 3707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LOOP_MEMBERS: 3708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return father_; 3709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case SUCCESSORS_OF_LOOP_MEMBER: 3710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block()->IsLoopHeader() && block() != loop_->loop_header()) { 3711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // In this case we need to perform a LOOP_MEMBERS cycle so we 3712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // initialize it and return this instead of father. 3713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SetupLoopMembers(zone, block(), 3714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block()->loop_information(), loop_header_); 3715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return father_; 3717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case NONE: 3719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return father_; 3720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 3722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 3723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3724b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Walks up the stack. 3726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* Backtrack(Zone* zone, 3727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<HBasicBlock*>* order) { 3728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* parent = Pop(zone, order); 3729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (parent != NULL) { 3730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* next = 3731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch parent->PerformNonBacktrackingStep(zone, order); 3732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (next != NULL) { 3733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return next; 3734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch parent = parent->Pop(zone, order); 3736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3737257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 3738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 3739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3740b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* PerformNonBacktrackingStep( 3742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone, 3743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<HBasicBlock*>* order) { 3744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* next_block; 3745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (kind_) { 3746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case SUCCESSORS: 3747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_block = AdvanceSuccessors(); 3748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (next_block != NULL) { 3749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* result = Push(zone); 3750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result->SetupSuccessors(zone, next_block, loop_header_); 3751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 3753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case SUCCESSORS_OF_LOOP_HEADER: 3754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_block = AdvanceSuccessors(); 3755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (next_block != NULL) { 3756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* result = Push(zone); 3757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result->SetupSuccessors(zone, next_block, block()); 3758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 3760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LOOP_MEMBERS: 3761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_block = AdvanceLoopMembers(); 3762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (next_block != NULL) { 3763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* result = Push(zone); 3764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result->SetupSuccessorsOfLoopMember(next_block, 3765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_, loop_header_); 3766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 3768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case SUCCESSORS_OF_LOOP_MEMBER: 3769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_block = AdvanceSuccessors(); 3770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (next_block != NULL) { 3771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* result = Push(zone); 3772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result->SetupSuccessors(zone, next_block, loop_header_); 3773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 3775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case NONE: 3776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 3777257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 3778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 3779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3780b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The following two methods implement a "foreach b in successors" cycle. 3782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void InitializeSuccessors() { 3783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_index = 0; 3784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_length = 0; 3785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch successor_iterator = HSuccessorIterator(block_->end()); 3786b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3787b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* AdvanceSuccessors() { 3789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!successor_iterator.Done()) { 3790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* result = successor_iterator.Current(); 3791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch successor_iterator.Advance(); 3792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 3793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 3795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3796b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The following two methods implement a "foreach b in loop members" cycle. 3798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void InitializeLoopMembers() { 3799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_index = 0; 3800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_length = loop_->blocks()->length(); 3801e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 38023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* AdvanceLoopMembers() { 3804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (loop_index < loop_length) { 3805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* result = loop_->blocks()->at(loop_index); 3806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_index++; 3807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 3808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 3810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 38113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopKind kind_; 3814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* father_; 3815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* child_; 3816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoopInformation* loop_; 3817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block_; 3818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_header_; 3819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int loop_index; 3820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int loop_length; 3821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HSuccessorIterator successor_iterator; 3822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 3823e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3824e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraph::OrderBlocks() { 3826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompilationPhase phase("H_Block ordering", info()); 3827e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 3829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initially the blocks must not be ordered. 3830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < blocks_.length(); ++i) { 3831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!blocks_[i]->IsOrdered()); 3832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 3834e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* postorder = 3836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor::CreateEntryProcessor(zone(), blocks_[0]); 3837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocks_.Rewind(0); 3838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (postorder) { 3839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch postorder = postorder->PerformStep(zone(), &blocks_); 3840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3841b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 3843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Now all blocks must be marked as ordered. 3844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < blocks_.length(); ++i) { 3845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(blocks_[i]->IsOrdered()); 3846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 3848b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Reverse block list and assign block IDs. 3850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0, j = blocks_.length(); --j >= i; ++i) { 3851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* bi = blocks_[i]; 3852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* bj = blocks_[j]; 3853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bi->set_block_id(j); 3854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bj->set_block_id(i); 3855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocks_[i] = bj; 3856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocks_[j] = bi; 3857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3858b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3859b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3860b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraph::AssignDominators() { 3862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhase phase("H_Assign dominators", this); 3863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < blocks_.length(); ++i) { 3864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block = blocks_[i]; 3865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block->IsLoopHeader()) { 3866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Only the first predecessor of a loop header is from outside the loop. 3867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // All others are back edges, and thus cannot dominate the loop header. 3868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block->AssignCommonDominator(block->predecessors()->first()); 3869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block->AssignLoopSuccessorDominators(); 3870b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 3871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int j = blocks_[i]->predecessors()->length() - 1; j >= 0; --j) { 3872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j)); 3873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3874b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3875b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3876b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3877b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3878b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HGraph::CheckArgumentsPhiUses() { 3880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int block_count = blocks_.length(); 3881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < block_count; ++i) { 3882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int j = 0; j < blocks_[i]->phis()->length(); ++j) { 3883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhi* phi = blocks_[i]->phis()->at(j); 3884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We don't support phi uses of arguments for now. 3885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (phi->CheckFlag(HValue::kIsArguments)) return false; 3886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 3889b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3890b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3891b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HGraph::CheckConstPhiUses() { 3893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int block_count = blocks_.length(); 3894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < block_count; ++i) { 3895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int j = 0; j < blocks_[i]->phis()->length(); ++j) { 3896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhi* phi = blocks_[i]->phis()->at(j); 3897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check for the hole value (from an uninitialized const). 3898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int k = 0; k < phi->OperandCount(); k++) { 3899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (phi->OperandAt(k) == GetConstantHole()) return false; 3900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 390244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 3903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 3904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 390544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3906b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraph::CollectPhis() { 3908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int block_count = blocks_.length(); 3909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch phi_list_ = new(zone()) ZoneList<HPhi*>(block_count, zone()); 3910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < block_count; ++i) { 3911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int j = 0; j < blocks_[i]->phis()->length(); ++j) { 3912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhi* phi = blocks_[i]->phis()->at(j); 3913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch phi_list_->Add(phi, zone()); 3914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 39173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Implementation of utility class to encapsulate the translation state for 3920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// a (possibly inlined) function. 3921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochFunctionState::FunctionState(HOptimizedGraphBuilder* owner, 3922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompilationInfo* info, 3923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InliningKind inlining_kind, 3924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int inlining_id) 3925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : owner_(owner), 3926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compilation_info_(info), 3927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call_context_(NULL), 3928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inlining_kind_(inlining_kind), 3929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_return_(NULL), 3930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch test_context_(NULL), 3931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_(NULL), 3932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_object_(NULL), 3933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_elements_(NULL), 3934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inlining_id_(inlining_id), 3935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer_source_position_(HSourcePosition::Unknown()), 3936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer_(owner->function_state()) { 3937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (outer_ != NULL) { 3938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // State for an inline function. 3939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (owner->ast_context()->IsTest()) { 3940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); 3941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); 3942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_true->MarkAsInlineReturnTarget(owner->current_block()); 3943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_false->MarkAsInlineReturnTarget(owner->current_block()); 3944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestContext* outer_test_context = TestContext::cast(owner->ast_context()); 3945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* cond = outer_test_context->condition(); 3946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The AstContext constructor pushed on the context stack. This newed 3947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instance is the reason that AstContext can't be BASE_EMBEDDED. 3948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch test_context_ = new TestContext(owner, cond, if_true, if_false); 3949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_return_ = owner->graph()->CreateBasicBlock(); 3951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_return()->MarkAsInlineReturnTarget(owner->current_block()); 3952b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set this after possibly allocating a new TestContext above. 3954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call_context_ = owner->ast_context(); 39553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3956592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 3957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Push on the state stack. 3958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner->set_function_state(this); 3959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_hydrogen_track_positions) { 3961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer_source_position_ = owner->source_position(); 3962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner->EnterInlinedSource( 3963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->shared_info()->start_position(), 3964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inlining_id); 3965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner->SetSourcePosition(info->shared_info()->start_position()); 3966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 39683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochFunctionState::~FunctionState() { 3971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete test_context_; 3972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner_->set_function_state(outer_); 39733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_hydrogen_track_positions) { 3975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner_->set_source_position(outer_source_position_); 3976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner_->EnterInlinedSource( 3977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer_->compilation_info()->shared_info()->start_position(), 3978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer_->inlining_id()); 39793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 39813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3982b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Implementation of utility classes to represent an expression's context in 3984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the AST. 3985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) 3986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : owner_(owner), 3987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind_(kind), 3988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer_(owner->ast_context()), 3989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for_typeof_(false) { 3990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner->set_ast_context(this); // Push. 3991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 3992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(owner->environment()->frame_type() == JS_FUNCTION); 3993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch original_length_ = owner->environment()->length(); 3994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 3995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 39963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstContext::~AstContext() { 3999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner_->set_ast_context(outer_); // Pop. 4000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 40013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochEffectContext::~EffectContext() { 4004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(owner()->HasStackOverflow() || 4005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->current_block() == NULL || 4006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (owner()->environment()->length() == original_length_ && 4007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->environment()->frame_type() == JS_FUNCTION)); 4008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 40093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochValueContext::~ValueContext() { 4012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(owner()->HasStackOverflow() || 4013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->current_block() == NULL || 4014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (owner()->environment()->length() == original_length_ + 1 && 4015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->environment()->frame_type() == JS_FUNCTION)); 4016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 401744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 401844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 4019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid EffectContext::ReturnValue(HValue* value) { 4020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The value is simply ignored. 4021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 40223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ValueContext::ReturnValue(HValue* value) { 4025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The value is tracked in the bailout environment, and communicated 4026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // through the environment as the result of the expression. 4027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!arguments_allowed() && value->CheckFlag(HValue::kIsArguments)) { 4028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Bailout(kBadValueContextForArgumentsValue); 4029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Push(value); 4031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 403244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 4033b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid TestContext::ReturnValue(HValue* value) { 4035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildBranch(value); 4036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid EffectContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 4040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!instr->IsControlInstruction()); 4041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->AddInstruction(instr); 4042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 4043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 4044b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4046b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid EffectContext::ReturnControl(HControlInstruction* instr, 4049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id) { 4050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!instr->HasObservableSideEffects()); 4051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); 4052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); 4053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetSuccessorAt(0, empty_true); 4054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetSuccessorAt(1, empty_false); 4055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->FinishCurrentBlock(instr); 4056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id); 4057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(join); 4058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid EffectContext::ReturnContinuation(HIfContinuation* continuation, 4062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id) { 4063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* true_branch = NULL; 4064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* false_branch = NULL; 4065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continuation->Continue(&true_branch, &false_branch); 4066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!continuation->IsTrueReachable()) { 4067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(false_branch); 4068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (!continuation->IsFalseReachable()) { 4069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(true_branch); 4070b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 4071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = owner()->CreateJoin(true_branch, false_branch, ast_id); 4072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(join); 4073b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4074b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4075b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 407644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 4077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 4078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!instr->IsControlInstruction()); 4079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 4080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return owner()->Bailout(kBadValueContextForArgumentsObjectValue); 4081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->AddInstruction(instr); 4083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Push(instr); 4084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 4085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 4086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4087b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4088b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4089b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { 4091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!instr->HasObservableSideEffects()); 4092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 4093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return owner()->Bailout(kBadValueContextForArgumentsObjectValue); 4094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock(); 4096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock(); 4097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetSuccessorAt(0, materialize_true); 4098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetSuccessorAt(1, materialize_false); 4099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->FinishCurrentBlock(instr); 4100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(materialize_true); 4101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Push(owner()->graph()->GetConstantTrue()); 4102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(materialize_false); 4103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Push(owner()->graph()->GetConstantFalse()); 4104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = 4105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->CreateJoin(materialize_true, materialize_false, ast_id); 4106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(join); 4107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4108b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4109b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ValueContext::ReturnContinuation(HIfContinuation* continuation, 4111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id) { 4112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* materialize_true = NULL; 4113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* materialize_false = NULL; 4114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continuation->Continue(&materialize_true, &materialize_false); 4115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (continuation->IsTrueReachable()) { 4116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(materialize_true); 4117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Push(owner()->graph()->GetConstantTrue()); 4118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(materialize_true); 4119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (continuation->IsFalseReachable()) { 4121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(materialize_false); 4122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Push(owner()->graph()->GetConstantFalse()); 4123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(materialize_false); 4124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (continuation->TrueAndFalseReachable()) { 4126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = 4127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->CreateJoin(materialize_true, materialize_false, ast_id); 4128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(join); 4129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 41323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 4134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!instr->IsControlInstruction()); 4135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HOptimizedGraphBuilder* builder = owner(); 4136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder->AddInstruction(instr); 4137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We expect a simulate after every expression with side effects, though 4138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this one isn't actually needed (and wouldn't work if it were targeted). 4139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 4140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder->Push(instr); 4141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 4142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder->Pop(); 41435d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 4144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildBranch(instr); 4145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 41465d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 4147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { 4149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!instr->HasObservableSideEffects()); 4150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); 4151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); 4152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetSuccessorAt(0, empty_true); 4153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetSuccessorAt(1, empty_false); 4154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->FinishCurrentBlock(instr); 4155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Goto(empty_true, if_true(), owner()->function_state()); 4156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Goto(empty_false, if_false(), owner()->function_state()); 4157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(NULL); 4158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid TestContext::ReturnContinuation(HIfContinuation* continuation, 4162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id) { 4163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* true_branch = NULL; 4164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* false_branch = NULL; 4165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continuation->Continue(&true_branch, &false_branch); 4166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (continuation->IsTrueReachable()) { 4167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Goto(true_branch, if_true(), owner()->function_state()); 41683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (continuation->IsFalseReachable()) { 4170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Goto(false_branch, if_false(), owner()->function_state()); 4171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(NULL); 4173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 41743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid TestContext::BuildBranch(HValue* value) { 4177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We expect the graph to be in edge-split form: there is no edge that 4178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // connects a branch node to a join node. We conservatively ensure that 4179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // property by always adding an empty block on the outgoing edges of this 4180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // branch. 4181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HOptimizedGraphBuilder* builder = owner(); 4182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { 4183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder->Bailout(kArgumentsObjectValueInATestContext); 4184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ToBooleanStub::Types expected(condition()->to_boolean_types()); 4186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ReturnControl(owner()->New<HBranch>(value, expected), BailoutId::None()); 4187b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// HOptimizedGraphBuilder infrastructure for bailing out and checking bailouts. 4191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define CHECK_BAILOUT(call) \ 4192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch do { \ 4193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call; \ 4194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasStackOverflow()) return; \ 4195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } while (false) 4196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define CHECK_ALIVE(call) \ 4199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch do { \ 4200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call; \ 4201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasStackOverflow() || current_block() == NULL) return; \ 4202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } while (false) 4203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define CHECK_ALIVE_OR_RETURN(call, value) \ 4206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch do { \ 4207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call; \ 4208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasStackOverflow() || current_block() == NULL) return value; \ 4209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } while (false) 4210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::Bailout(BailoutReason reason) { 4213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_info()->AbortOptimization(reason); 4214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetStackOverflow(); 42153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 42163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 42173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitForEffect(Expression* expr) { 4219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EffectContext for_effect(this); 4220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(expr); 4221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4222e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitForValue(Expression* expr, 4225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArgumentsAllowedFlag flag) { 4226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ValueContext for_value(this, flag); 4227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(expr); 4228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4230b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitForTypeOf(Expression* expr) { 4232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); 4233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for_value.set_for_typeof(true); 4234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(expr); 4235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 42363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4237e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitForControl(Expression* expr, 4239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* true_block, 4240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* false_block) { 4241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestContext for_test(this, expr, true_block, false_block); 4242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(expr); 4243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4244e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitExpressions( 4247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Expression*>* exprs) { 4248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < exprs->length(); ++i) { 4249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(exprs->at(i))); 4250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::BuildGraph() { 4255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_info()->function()->is_generator()) { 4256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bailout(kFunctionIsAGenerator); 4257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 4258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* scope = current_info()->scope(); 4260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (scope->HasIllegalRedeclaration()) { 4261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bailout(kFunctionWithIllegalRedeclaration); 4262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 4263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (scope->calls_eval()) { 4265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bailout(kFunctionCallsEval); 4266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 4267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetUpScope(scope); 4269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Add an edge to the body entry. This is warty: the graph's start 4271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // environment will be used by the Lithium translation as the initial 4272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // environment on graph entry, but it has now been mutated by the 4273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Hydrogen translation of the instructions in the start block. This 4274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // environment uses values which have not been defined yet. These 4275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Hydrogen instructions will then be replayed by the Lithium 4276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // translation, so they cannot have an environment effect. The edge to 4277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the body's entry block (along with some special logic for the start 4278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // block in HInstruction::InsertAfter) seals the start block from 4279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // getting unwanted instructions inserted. 4280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 4281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(kmillikin): Fix this. Stop mutating the initial environment. 4282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make the Hydrogen instructions in the initial block into Hydrogen 4283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // values (but not instructions), present in the initial environment and 4284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // not replayed by the Lithium translation. 4285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* initial_env = environment()->CopyWithoutHistory(); 4286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* body_entry = CreateBasicBlock(initial_env); 4287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(body_entry); 4288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_entry->SetJoinId(BailoutId::FunctionEntry()); 4289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(body_entry); 4290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle implicit declaration of the function name in named function 4292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // expressions before other declarations. 4293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (scope->is_function_scope() && scope->function() != NULL) { 4294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitVariableDeclaration(scope->function()); 4295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitDeclarations(scope->declarations()); 4297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(BailoutId::Declarations()); 4298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStackCheck>(HStackCheck::kFunctionEntry); 4300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitStatements(current_info()->function()->body()); 4302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasStackOverflow()) return false; 4303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4304257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (current_block() != NULL) { 4305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HReturn>(graph()->GetConstantUndefined()); 4306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 4307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the checksum of the number of type info changes is the same as the 4310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // last time this function was compiled, then this recompile is likely not 4311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // due to missing/inadequate type feedback, but rather too aggressive 4312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // optimization. Disable optimistic LICM in that case. 4313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> unoptimized_code(current_info()->shared_info()->code()); 4314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(unoptimized_code->kind() == Code::FUNCTION); 4315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<TypeFeedbackInfo> type_info( 4316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); 4317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int checksum = type_info->own_type_change_checksum(); 4318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int composite_checksum = graph()->update_type_change_checksum(checksum); 4319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->set_use_optimistic_licm( 4320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !type_info->matches_inlined_type_change_checksum(composite_checksum)); 4321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch type_info->set_inlined_type_change_checksum(composite_checksum); 4322e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Perform any necessary OSR-specific cleanups or changes to the graph. 4324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr()->FinishGraph(); 4325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 4327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HGraph::Optimize(BailoutReason* bailout_reason) { 4331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OrderBlocks(); 4332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssignDominators(); 43333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We need to create a HConstant "zero" now so that GVN will fold every 4335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // zero-valued constant in the graph together. 4336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The constant is needed to make idef-based bounds check work: the pass 4337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // evaluates relations with "zero" and that zero cannot be created after GVN. 4338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetConstant0(); 4339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 4341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Do a full verify after building the graph and computing dominators. 4342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Verify(true); 4343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 43443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_analyze_environment_liveness && maximum_environment_size() != 0) { 4346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HEnvironmentLivenessAnalysisPhase>(); 43473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 43483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!CheckConstPhiUses()) { 4350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *bailout_reason = kUnsupportedPhiUseOfConstVariable; 4351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 4352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HRedundantPhiEliminationPhase>(); 4354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!CheckArgumentsPhiUses()) { 4355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *bailout_reason = kUnsupportedPhiUseOfArguments; 4356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 43573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 43583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find and mark unreachable code to simplify optimizations, especially gvn, 4360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // where unreachable code could unnecessarily defeat LICM. 4361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HMarkUnreachableBlocksPhase>(); 43623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>(); 4364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_use_escape_analysis) Run<HEscapeAnalysisPhase>(); 43653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_load_elimination) Run<HLoadEliminationPhase>(); 43673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CollectPhis(); 43693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (has_osr()) osr()->FinishOsrValues(); 43713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HInferRepresentationPhase>(); 43733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remove HSimulate instructions that have turned out not to be needed 4375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // after all by folding them into the following HSimulate. 4376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This must happen after inferring representations. 4377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HMergeRemovableSimulatesPhase>(); 43783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HMarkDeoptimizeOnUndefinedPhase>(); 4380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HRepresentationChangesPhase>(); 43813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HInferTypesPhase>(); 43833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Must be performed before canonicalization to ensure that Canonicalize 4385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with 4386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // zero. 4387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_opt_safe_uint32_operations) Run<HUint32AnalysisPhase>(); 43883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_use_canonicalizing) Run<HCanonicalizePhase>(); 43903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_use_gvn) Run<HGlobalValueNumberingPhase>(); 43923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_check_elimination) Run<HCheckEliminationPhase>(); 43943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_store_elimination) Run<HStoreEliminationPhase>(); 43963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HRangeAnalysisPhase>(); 43983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HComputeChangeUndefinedToNaN>(); 44003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Eliminate redundant stack checks on backwards branches. 4402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HStackCheckEliminationPhase>(); 44033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_array_bounds_checks_elimination) Run<HBoundsCheckEliminationPhase>(); 4405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_array_bounds_checks_hoisting) Run<HBoundsCheckHoistingPhase>(); 4406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_array_index_dehoisting) Run<HDehoistIndexComputationsPhase>(); 4407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>(); 44083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RestoreActualValues(); 4410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find unreachable code a second time, GVN and other optimizations may have 4412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // made blocks unreachable that were previously reachable. 4413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HMarkUnreachableBlocksPhase>(); 4414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 4416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraph::RestoreActualValues() { 4420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhase phase("H_Restore actual values", this); 4421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int block_index = 0; block_index < blocks()->length(); block_index++) { 4423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block = blocks()->at(block_index); 44248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 4426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < block->phis()->length(); i++) { 4427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhi* phi = block->phis()->at(i); 4428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(phi->ActualValue() == phi); 4429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 44318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (HInstructionIterator it(block); !it.Done(); it.Advance()) { 4433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instruction = it.Current(); 4434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instruction->ActualValue() == instruction) continue; 4435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instruction->CheckFlag(HValue::kIsDead)) { 4436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The instruction was marked as deleted but left in the graph 4437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // as a control flow dependency point for subsequent 4438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instructions. 4439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instruction->DeleteAndReplaceWith(instruction->ActualValue()); 4440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(instruction->IsInformativeDefinition()); 4442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instruction->IsPurelyInformativeDefinition()) { 4443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); 4444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instruction->ReplaceAllUsesWith(instruction->ActualValue()); 4446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 44478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 44488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 44498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 4450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::PushArgumentsFromEnvironment(int count) { 4454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<HValue*> arguments(count, zone()); 4455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < count; ++i) { 4456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments.Add(Pop(), zone()); 44578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 4458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPushArguments* push_args = New<HPushArguments>(); 4460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!arguments.is_empty()) { 4461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch push_args->AddInput(arguments.RemoveLast()); 4462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(push_args); 4464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <class Instruction> 4468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { 4469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(call->argument_count()); 4470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return call; 4471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4473b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::SetUpScope(Scope* scope) { 4475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // First special is HContext. 4476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* context = Add<HContext>(); 4477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->BindContext(context); 4478e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create an arguments object containing the initial parameters. Set the 4480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // initial values of parameters including "this" having parameter index 0. 4481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(scope->num_parameters() + 1, environment()->parameter_count()); 4482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HArgumentsObject* arguments_object = 4483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HArgumentsObject>(environment()->parameter_count()); 4484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < environment()->parameter_count(); ++i) { 4485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* parameter = Add<HParameter>(i); 4486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_object->AddArgument(parameter, zone()); 4487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Bind(i, parameter); 4488257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(arguments_object); 4490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->SetArgumentsObject(arguments_object); 4491e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* undefined_constant = graph()->GetConstantUndefined(); 4493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize specials and locals to undefined. 4494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = environment()->parameter_count() + 1; 4495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i < environment()->length(); 4496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++i) { 4497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Bind(i, undefined_constant); 4498257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4499e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle the arguments and arguments shadow variables specially (they do 4501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // not have declarations). 4502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (scope->arguments() != NULL) { 4503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!scope->arguments()->IsStackAllocated()) { 4504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kContextAllocatedArguments); 4505257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Bind(scope->arguments(), 4508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetArgumentsObject()); 450944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 4510b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4512b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochType* HOptimizedGraphBuilder::ToType(Handle<Map> map) { 4514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return IC::MapToType<Type>(map, zone()); 45151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 45161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 45171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { 4519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < statements->length(); i++) { 4520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Statement* stmt = statements->at(i); 4521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(Visit(stmt)); 4522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stmt->IsJump()) break; 45231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 4524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitBlock(Block* stmt) { 4528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4531b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* outer_scope = scope(); 4533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* scope = stmt->scope(); 4534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueInfo break_info(stmt, outer_scope); 4535589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 4536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { BreakAndContinueScope push(&break_info, this); 4537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (scope != NULL) { 4538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the function object. 4539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* declaration_scope = scope->DeclarationScope(); 4540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* function; 4541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* outer_context = environment()->context(); 4542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (declaration_scope->is_global_scope() || 4543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch declaration_scope->is_eval_scope()) { 4544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function = new(zone()) HLoadContextSlot( 4545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer_context, Context::CLOSURE_INDEX, HLoadContextSlot::kNoCheck); 4546589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } else { 4547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function = New<HThisFunction>(); 4548589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 4549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(function); 4550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate a block context and store it to the stack frame. 4551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* inner_context = Add<HAllocateBlockContext>( 4552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer_context, function, scope->GetScopeInfo()); 4553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = Add<HStoreFrameContext>(inner_context); 4554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 4555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSimulate(stmt->EntryId(), REMOVABLE_SIMULATE); 4556589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 4557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_scope(scope); 4558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->BindContext(inner_context); 4559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitDeclarations(scope->declarations()); 4560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSimulate(stmt->DeclsId(), REMOVABLE_SIMULATE); 4561589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 4562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitStatements(stmt->statements())); 4563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_scope(outer_scope); 4565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (scope != NULL && current_block() != NULL) { 4566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* inner_context = environment()->context(); 4567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* outer_context = Add<HLoadNamedField>( 4568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inner_context, static_cast<HValue*>(NULL), 4569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 4570589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 4571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = Add<HStoreFrameContext>(outer_context); 4572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 4573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSimulate(stmt->ExitId(), REMOVABLE_SIMULATE); 4574b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->BindContext(outer_context); 4576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* break_block = break_info.break_block(); 4578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (break_block != NULL) { 4579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_block() != NULL) Goto(break_block); 4580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_block->SetJoinId(stmt->ExitId()); 4581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(break_block); 4582b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4584b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4585b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitExpressionStatement( 4587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExpressionStatement* stmt) { 4588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForEffect(stmt->expression()); 4592b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4593b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4594b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) { 4596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4599b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4600b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4601b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) { 4603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stmt->condition()->ToBooleanIsTrue()) { 4607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(stmt->ThenId()); 4608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(stmt->then_statement()); 4609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (stmt->condition()->ToBooleanIsFalse()) { 4610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(stmt->ElseId()); 4611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(stmt->else_statement()); 4612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* cond_true = graph()->CreateBasicBlock(); 4614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* cond_false = graph()->CreateBasicBlock(); 4615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitForControl(stmt->condition(), cond_true, cond_false)); 46163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cond_true->HasPredecessor()) { 4618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_true->SetJoinId(stmt->ThenId()); 4619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(cond_true); 4620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(Visit(stmt->then_statement())); 4621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_true = current_block(); 46223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 4623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_true = NULL; 46243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 46253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cond_false->HasPredecessor()) { 4627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_false->SetJoinId(stmt->ElseId()); 4628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(cond_false); 4629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(Visit(stmt->else_statement())); 4630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_false = current_block(); 4631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_false = NULL; 46333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 46343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId()); 4636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(join); 4637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 46383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 46393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get( 4642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakableStatement* stmt, 4643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakType type, 4644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope** scope, 4645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int* drop_extra) { 4646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *drop_extra = 0; 4647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueScope* current = this; 4648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (current != NULL && current->info()->target() != stmt) { 4649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *drop_extra += current->info()->drop_extra(); 4650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current = current->next(); 4651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current != NULL); // Always found (unless stack is malformed). 4653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *scope = current->info()->scope(); 46543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type == BREAK) { 4656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *drop_extra += current->info()->drop_extra(); 46573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 46583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block = NULL; 4660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (type) { 4661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case BREAK: 4662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block = current->info()->break_block(); 4663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block == NULL) { 4664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block = current->owner()->graph()->CreateBasicBlock(); 4665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current->info()->set_break_block(block); 4666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 4668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CONTINUE: 4670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block = current->info()->continue_block(); 4671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block == NULL) { 4672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block = current->owner()->graph()->CreateBasicBlock(); 4673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current->info()->set_continue_block(block); 4674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 4676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4677b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return block; 4679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4680b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4681b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitContinueStatement( 4683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ContinueStatement* stmt) { 4684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* outer_scope = NULL; 4688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* inner_scope = scope(); 4689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int drop_extra = 0; 4690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* continue_block = break_scope()->Get( 4691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stmt->target(), BreakAndContinueScope::CONTINUE, 4692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &outer_scope, &drop_extra); 4693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = environment()->context(); 4694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(drop_extra); 4695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int context_pop_count = inner_scope->ContextChainLength(outer_scope); 4696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (context_pop_count > 0) { 4697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (context_pop_count-- > 0) { 4698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* context_instruction = Add<HLoadNamedField>( 4699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context, static_cast<HValue*>(NULL), 4700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 4701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context = context_instruction; 4702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = Add<HStoreFrameContext>(context); 4704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 4705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSimulate(stmt->target()->EntryId(), REMOVABLE_SIMULATE); 4706b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->BindContext(context); 4708b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 470944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 4710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(continue_block); 4711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 4712b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4713b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4714b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { 4716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* outer_scope = NULL; 4720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* inner_scope = scope(); 4721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int drop_extra = 0; 4722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* break_block = break_scope()->Get( 4723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stmt->target(), BreakAndContinueScope::BREAK, 4724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &outer_scope, &drop_extra); 4725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = environment()->context(); 4726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(drop_extra); 4727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int context_pop_count = inner_scope->ContextChainLength(outer_scope); 4728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (context_pop_count > 0) { 4729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (context_pop_count-- > 0) { 4730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* context_instruction = Add<HLoadNamedField>( 4731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context, static_cast<HValue*>(NULL), 4732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 4733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context = context_instruction; 47343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = Add<HStoreFrameContext>(context); 4736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 4737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSimulate(stmt->target()->ExitId(), REMOVABLE_SIMULATE); 47383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->BindContext(context); 47403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(break_block); 4742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 4743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 47443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 47453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { 4747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FunctionState* state = function_state(); 4751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AstContext* context = call_context(); 4752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (context == NULL) { 4753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Not an inlined return, so an actual one. 4754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(stmt->expression())); 4755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result = environment()->Pop(); 4756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HReturn>(result); 4757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { 4758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return from an inlined construct call. In a test context the return value 4759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // will always evaluate to true, in a value context the return value needs 4760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to be a JSObject. 4761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (context->IsTest()) { 4762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestContext* test = TestContext::cast(context); 4763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForEffect(stmt->expression())); 4764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(test->if_true(), state); 4765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (context->IsEffect()) { 4766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForEffect(stmt->expression())); 4767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(function_return(), state); 4768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(context->IsValue()); 4770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(stmt->expression())); 4771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* return_value = Pop(); 4772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver = environment()->arguments_environment()->Lookup(0); 4773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HHasInstanceTypeAndBranch* typecheck = 4774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HHasInstanceTypeAndBranch>(return_value, 4775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FIRST_SPEC_OBJECT_TYPE, 4776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LAST_SPEC_OBJECT_TYPE); 4777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_spec_object = graph()->CreateBasicBlock(); 4778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* not_spec_object = graph()->CreateBasicBlock(); 4779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typecheck->SetSuccessorAt(0, if_spec_object); 4780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typecheck->SetSuccessorAt(1, not_spec_object); 4781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(typecheck); 4782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddLeaveInlined(if_spec_object, return_value, state); 4783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddLeaveInlined(not_spec_object, receiver, state); 4784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (state->inlining_kind() == SETTER_CALL_RETURN) { 4786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return from an inlined setter call. The returned value is never used, the 4787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // value of an assignment is always the value of the RHS of the assignment. 4788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForEffect(stmt->expression())); 4789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (context->IsTest()) { 4790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* rhs = environment()->arguments_environment()->Lookup(1); 4791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context->ReturnValue(rhs); 4792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (context->IsEffect()) { 4793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(function_return(), state); 4794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(context->IsValue()); 4796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* rhs = environment()->arguments_environment()->Lookup(1); 4797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddLeaveInlined(rhs, state); 4798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 47993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 4800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return from a normal inlined function. Visit the subexpression in the 4801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // expression context of the call. 4802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (context->IsTest()) { 4803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestContext* test = TestContext::cast(context); 4804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForControl(stmt->expression(), test->if_true(), test->if_false()); 4805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (context->IsEffect()) { 4806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Visit in value context and ignore the result. This is needed to keep 4807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // environment in sync with full-codegen since some visitors (e.g. 4808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // VisitCountOperation) use the operand stack differently depending on 4809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // context. 4810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(stmt->expression())); 4811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(); 4812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(function_return(), state); 4813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(context->IsValue()); 4815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(stmt->expression())); 4816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddLeaveInlined(Pop(), state); 48173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4818b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 4820b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4821b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4822b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitWithStatement(WithStatement* stmt) { 4824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kWithStatement); 4828b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4829b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4830b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { 4832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4835b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<CaseClause*>* clauses = stmt->cases(); 4837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int clause_count = clauses->length(); 4838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<HBasicBlock*> body_blocks(clause_count, zone()); 4839b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(stmt->tag())); 4841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(stmt->EntryId()); 4842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* tag_value = Top(); 4843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* tag_type = stmt->tag()->bounds().lower; 4844b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 1. Build all the tests, with dangling true branches 4846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId default_id = BailoutId::None(); 4847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < clause_count; ++i) { 4848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CaseClause* clause = clauses->at(i); 4849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (clause->is_default()) { 4850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_blocks.Add(NULL, zone()); 4851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (default_id.IsNone()) default_id = clause->EntryId(); 4852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue; 4853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 48543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generate a compare and branch. 4856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(clause->label())); 4857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* label_value = Pop(); 48583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* label_type = clause->label()->bounds().lower; 4860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* combined_type = clause->compare_type(); 4861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HControlInstruction* compare = BuildCompareInstruction( 4862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::EQ_STRICT, tag_value, label_value, tag_type, label_type, 4863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch combined_type, 4864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScriptPositionToSourcePosition(stmt->tag()->position()), 4865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScriptPositionToSourcePosition(clause->label()->position()), 4866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PUSH_BEFORE_SIMULATE, clause->id()); 48673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* next_test_block = graph()->CreateBasicBlock(); 4869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* body_block = graph()->CreateBasicBlock(); 4870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_blocks.Add(body_block, zone()); 4871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare->SetSuccessorAt(0, body_block); 4872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare->SetSuccessorAt(1, next_test_block); 4873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(compare); 48743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(body_block); 4876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // tag_value 48775d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 4878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(next_test_block); 4879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 48805d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 4881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Save the current block to use for the default or to join with the 4882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // exit. 4883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* last_block = current_block(); 4884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // tag_value 4885b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2. Loop over the clauses and the linked list of tests in lockstep, 4887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // translating the clause bodies. 4888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* fall_through_block = NULL; 4889b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueInfo break_info(stmt, scope()); 4891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { BreakAndContinueScope push(&break_info, this); 4892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < clause_count; ++i) { 4893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CaseClause* clause = clauses->at(i); 4894b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Identify the block where normal (non-fall-through) control flow 4896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // goes to. 4897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* normal_block = NULL; 4898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (clause->is_default()) { 4899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (last_block == NULL) continue; 4900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch normal_block = last_block; 4901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_block = NULL; // Cleared to indicate we've handled it. 4902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch normal_block = body_blocks[i]; 4904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4905b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (fall_through_block == NULL) { 4907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(normal_block); 4908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = CreateJoin(fall_through_block, 4910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch normal_block, 4911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch clause->EntryId()); 4912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(join); 4913e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 4914e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitStatements(clause->statements())); 4916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fall_through_block = current_block(); 4917b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4918b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4919b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create an up-to-3-way join. Use the break block if it exists since 4921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // it's already a join block. 4922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* break_block = break_info.break_block(); 4923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (break_block == NULL) { 4924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(CreateJoin(fall_through_block, 4925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_block, 4926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stmt->ExitId())); 4927e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 4928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (fall_through_block != NULL) Goto(fall_through_block, break_block); 4929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (last_block != NULL) Goto(last_block, break_block); 4930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_block->SetJoinId(stmt->ExitId()); 4931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(break_block); 4932b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4933b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4934b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4935b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, 4937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_entry) { 4938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(stmt->StackCheckId()); 4939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStackCheck* stack_check = 4940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStackCheck::cast(Add<HStackCheck>(HStackCheck::kBackwardsBranch)); 4941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(loop_entry->IsLoopHeader()); 4942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_entry->loop_information()->set_stack_check(stack_check); 4943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(Visit(stmt->body())); 4944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4945b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4946b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 4948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_entry = BuildLoopEntry(stmt); 4953b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueInfo break_info(stmt, scope()); 4955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 4956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueScope push(&break_info, this); 4957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); 4958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* body_exit = 4960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JoinContinue(stmt, current_block(), break_info.continue_block()); 4961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_successor = NULL; 4962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { 4963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(body_exit); 4964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor = graph()->CreateBasicBlock(); 4965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stmt->cond()->ToBooleanIsFalse()) { 4966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_entry->loop_information()->stack_check()->Eliminate(); 4967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(loop_successor); 4968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit = NULL; 4969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The block for a true condition, the actual predecessor block of the 4971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // back edge. 4972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit = graph()->CreateBasicBlock(); 4973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitForControl(stmt->cond(), body_exit, loop_successor)); 4974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (body_exit != NULL && body_exit->HasPredecessor()) { 4976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit->SetJoinId(stmt->BackEdgeId()); 4977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit = NULL; 4979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (loop_successor->HasPredecessor()) { 4981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor->SetJoinId(stmt->ExitId()); 4982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor = NULL; 4984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_exit = CreateLoop(stmt, 4987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_entry, 4988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit, 4989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor, 4990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_info.break_block()); 4991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(loop_exit); 4992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4993b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4994b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { 4996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_entry = BuildLoopEntry(stmt); 5001b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the condition is constant true, do not generate a branch. 5003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_successor = NULL; 5004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!stmt->cond()->ToBooleanIsTrue()) { 5005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* body_entry = graph()->CreateBasicBlock(); 5006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor = graph()->CreateBasicBlock(); 5007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); 5008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (body_entry->HasPredecessor()) { 5009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_entry->SetJoinId(stmt->BodyId()); 5010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(body_entry); 5011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (loop_successor->HasPredecessor()) { 5013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor->SetJoinId(stmt->ExitId()); 5014b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 5015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor = NULL; 5016b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 5017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5018b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueInfo break_info(stmt, scope()); 5020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_block() != NULL) { 5021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueScope push(&break_info, this); 5022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); 5023b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 5024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* body_exit = 5025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JoinContinue(stmt, current_block(), break_info.continue_block()); 5026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_exit = CreateLoop(stmt, 5027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_entry, 5028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit, 5029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor, 5030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_info.break_block()); 5031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(loop_exit); 5032b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 5033b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) { 5036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stmt->init() != NULL) { 5040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(Visit(stmt->init())); 5041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_entry = BuildLoopEntry(stmt); 5044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_successor = NULL; 5046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stmt->cond() != NULL) { 5047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* body_entry = graph()->CreateBasicBlock(); 5048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor = graph()->CreateBasicBlock(); 5049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); 5050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (body_entry->HasPredecessor()) { 5051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_entry->SetJoinId(stmt->BodyId()); 5052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(body_entry); 5053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (loop_successor->HasPredecessor()) { 5055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor->SetJoinId(stmt->ExitId()); 5056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor = NULL; 5058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueInfo break_info(stmt, scope()); 5062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_block() != NULL) { 5063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueScope push(&break_info, this); 5064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); 5065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* body_exit = 5067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JoinContinue(stmt, current_block(), break_info.continue_block()); 5068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stmt->next() != NULL && body_exit != NULL) { 5070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(body_exit); 5071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(Visit(stmt->next())); 5072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit = current_block(); 5073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_exit = CreateLoop(stmt, 5076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_entry, 5077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit, 5078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor, 5079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_info.break_block()); 5080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(loop_exit); 5081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { 5085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_optimize_for_in) { 5090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kForInStatementOptimizationIsDisabled); 5091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stmt->for_in_type() != ForInStatement::FAST_FOR_IN) { 5094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kForInStatementIsNotFastCase); 5095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!stmt->each()->IsVariableProxy() || 5098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) { 5099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kForInStatementWithNonLocalEachVariable); 5100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* each_var = stmt->each()->AsVariableProxy()->var(); 5103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(stmt->enumerable())); 5105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* enumerable = Top(); // Leave enumerable at the top. 5106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* map = Add<HForInPrepareMap>(enumerable); 5108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(stmt->PrepareId()); 5109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* array = Add<HForInCacheArray>( 5111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex); 5112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* enum_length = Add<HMapEnumLength>(map); 5114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* start_index = Add<HConstant>(0); 5116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(map); 5118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(array); 5119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(enum_length); 5120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(start_index); 5121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* index_cache = Add<HForInCacheArray>( 5123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enumerable, map, DescriptorArray::kEnumCacheBridgeIndicesCacheIndex); 5124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HForInCacheArray::cast(array)->set_index_cache( 5125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HForInCacheArray::cast(index_cache)); 5126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_entry = BuildLoopEntry(stmt); 5128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = environment()->ExpressionStackAt(0); 5130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* limit = environment()->ExpressionStackAt(1); 5131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that we still have more keys. 5133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCompareNumericAndBranch* compare_index = 5134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HCompareNumericAndBranch>(index, limit, Token::LT); 5135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_index->set_observed_input_representation( 5136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation::Smi(), Representation::Smi()); 5137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_body = graph()->CreateBasicBlock(); 5139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_successor = graph()->CreateBasicBlock(); 5140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_index->SetSuccessorAt(0, loop_body); 5142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_index->SetSuccessorAt(1, loop_successor); 5143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(compare_index); 5144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(loop_successor); 5146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(5); 5147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(loop_body); 5149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = Add<HLoadKeyed>( 5151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->ExpressionStackAt(2), // Enum cache. 5152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->ExpressionStackAt(0), // Iteration index. 5153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->ExpressionStackAt(0), 5154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FAST_ELEMENTS); 5155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if the expected map still matches that of the enumerable. 5157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If not just deoptimize. 5158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckMapValue>(environment()->ExpressionStackAt(4), 5159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->ExpressionStackAt(3)); 5160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bind(each_var, key); 5162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueInfo break_info(stmt, scope(), 5); 5164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 5165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueScope push(&break_info, this); 5166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); 5167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* body_exit = 5170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JoinContinue(stmt, current_block(), break_info.continue_block()); 5171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (body_exit != NULL) { 5173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(body_exit); 5174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* current_index = Pop(); 5176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(AddUncasted<HAdd>(current_index, graph()->GetConstant1())); 5177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit = current_block(); 5178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_exit = CreateLoop(stmt, 5181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_entry, 5182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit, 5183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor, 5184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_info.break_block()); 5185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(loop_exit); 5187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { 5191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kForOfStatement); 5195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { 5199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kTryCatchStatement); 5203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitTryFinallyStatement( 5207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TryFinallyStatement* stmt) { 5208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kTryFinallyStatement); 5212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { 5216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kDebuggerStatement); 5220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitCaseClause(CaseClause* clause) { 5224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 5225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { 5229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<SharedFunctionInfo> shared_info = expr->shared_info(); 5233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shared_info.is_null()) { 5234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared_info = 5235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Compiler::BuildFunctionInfo(expr, current_info()->script(), top_info()); 5236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We also have a stack overflow if the recursive compilation did. 5238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasStackOverflow()) return; 5239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HFunctionLiteral* instr = 5240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HFunctionLiteral>(shared_info, expr->pretenure()); 5241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 5242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitClassLiteral(ClassLiteral* lit) { 5246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kClassLiteral); 5250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitNativeFunctionLiteral( 5254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NativeFunctionLiteral* expr) { 5255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kNativeFunctionLiteral); 5259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitConditional(Conditional* expr) { 5263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* cond_true = graph()->CreateBasicBlock(); 5267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* cond_false = graph()->CreateBasicBlock(); 5268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitForControl(expr->condition(), cond_true, cond_false)); 5269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Visit the true and false subexpressions in the same AST context as the 5271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // whole expression. 5272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cond_true->HasPredecessor()) { 5273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_true->SetJoinId(expr->ThenId()); 5274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(cond_true); 5275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(Visit(expr->then_expression())); 5276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_true = current_block(); 5277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_true = NULL; 5279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cond_false->HasPredecessor()) { 5282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_false->SetJoinId(expr->ElseId()); 5283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(cond_false); 5284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(Visit(expr->else_expression())); 5285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_false = current_block(); 5286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_false = NULL; 5288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsTest()) { 5291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id()); 5292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(join); 5293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (join != NULL && !ast_context()->IsEffect()) { 5294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 5295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHOptimizedGraphBuilder::GlobalPropertyAccess 5301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHOptimizedGraphBuilder::LookupGlobalProperty(Variable* var, LookupIterator* it, 5302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessType access_type) { 5303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (var->is_this() || !current_info()->has_global_object()) { 5304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kUseGeneric; 5305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (it->state()) { 5308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::ACCESSOR: 5309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::ACCESS_CHECK: 5310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::INTERCEPTOR: 5311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::NOT_FOUND: 5312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kUseGeneric; 5313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::DATA: 5314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == STORE && it->IsReadOnly()) return kUseGeneric; 5315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kUseCell; 5316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::JSPROXY: 5317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::TRANSITION: 5318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 5319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 5321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kUseGeneric; 5322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { 5326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(var->IsContextSlot()); 5327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = environment()->context(); 5328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length = scope()->ContextChainLength(var->scope()); 5329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (length-- > 0) { 5330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context = Add<HLoadNamedField>( 5331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context, static_cast<HValue*>(NULL), 5332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 5333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return context; 5335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 5339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->is_this()) { 5340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_info()->set_this_has_uses(true); 5341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* variable = expr->var(); 5347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (variable->location()) { 5348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::UNALLOCATED: { 5349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsLexicalVariableMode(variable->mode())) { 5350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(rossberg): should this be an DCHECK? 5351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kReferenceToGlobalLexicalVariable); 5352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle known global constants like 'undefined' specially to avoid a 5354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // load from a global cell for them. 5355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> constant_value = 5356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->GlobalConstantFor(variable->name()); 5357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!constant_value.is_null()) { 5358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* instr = New<HConstant>(constant_value); 5359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 5360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<GlobalObject> global(current_info()->global_object()); 5363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupIterator it(global, variable->name(), 5364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupIterator::OWN_SKIP_INTERCEPTOR); 5365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD); 5366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type == kUseCell) { 5368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<PropertyCell> cell = it.GetPropertyCell(); 5369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cell->type()->IsConstant()) { 5370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyCell::AddDependentCompilationInfo(cell, top_info()); 5371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> constant_object = cell->type()->AsConstant()->Value(); 5372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (constant_object->IsConsString()) { 5373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_object = 5374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String::Flatten(Handle<String>::cast(constant_object)); 5375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* constant = New<HConstant>(constant_object); 5377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(constant, expr->id()); 5378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoadGlobalCell* instr = 5380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HLoadGlobalCell>(cell, it.property_details()); 5381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 5382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* global_object = Add<HLoadNamedField>( 5385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context(), static_cast<HValue*>(NULL), 5386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 5387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoadGlobalGeneric* instr = 5388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HLoadGlobalGeneric>(global_object, 5389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch variable->name(), 5390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->is_for_typeof()); 5391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_vector_ics) { 5392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<SharedFunctionInfo> current_shared = 5393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state()->compilation_info()->shared_info(); 5394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetVectorAndSlot( 5395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle(current_shared->feedback_vector(), isolate()), 5396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->VariableFeedbackSlot()); 5397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 5399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::PARAMETER: 5403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::LOCAL: { 5404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = LookupAndMakeLive(variable); 5405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value == graph()->GetConstantHole()) { 5406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsDeclaredVariableMode(variable->mode()) && 5407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch variable->mode() != VAR); 5408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kReferenceToUninitializedVariable); 5409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(value); 5411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::CONTEXT: { 5414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = BuildContextChainWalk(variable); 5415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoadContextSlot::Mode mode; 5416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (variable->mode()) { 5417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LET: 5418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CONST: 5419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode = HLoadContextSlot::kCheckDeoptimize; 5420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CONST_LEGACY: 5422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode = HLoadContextSlot::kCheckReturnUndefined; 5423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 5425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode = HLoadContextSlot::kNoCheck; 5426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoadContextSlot* instr = 5429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new(zone()) HLoadContextSlot(context, variable->index(), mode); 5430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 5431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::LOOKUP: 5434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kReferenceToAVariableWhichRequiresDynamicLookup); 5435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitLiteral(Literal* expr) { 5440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* instr = New<HConstant>(expr->value()); 5444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 5445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 5449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 5453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> literals(closure->literals()); 5454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HRegExpLiteral* instr = New<HRegExpLiteral>(literals, 5455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->pattern(), 5456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->flags(), 5457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->literal_index()); 5458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 5459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool CanInlinePropertyAccess(Type* type) { 5463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type->Is(Type::NumberOrString())) return true; 5464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!type->IsClass()) return false; 5465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = type->AsClass()->Map(); 5466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return map->IsJSObjectMap() && 5467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !map->is_dictionary_map() && 5468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !map->has_named_interceptor(); 5469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Determines whether the given array or object literal boilerplate satisfies 5473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// all limits to be considered for fast deep-copying and computes the total 5474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// size of all objects that are part of the graph. 5475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool IsFastLiteral(Handle<JSObject> boilerplate, 5476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int max_depth, 5477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int* max_properties) { 5478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (boilerplate->map()->is_deprecated() && 5479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !JSObject::TryMigrateInstance(boilerplate)) { 5480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 5481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(max_depth >= 0 && *max_properties >= 0); 5484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (max_depth == 0) return false; 5485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = boilerplate->GetIsolate(); 5487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArrayBase> elements(boilerplate->elements()); 5488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (elements->length() > 0 && 5489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements->map() != isolate->heap()->fixed_cow_array_map()) { 5490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (boilerplate->HasFastObjectElements()) { 5491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); 5492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length = elements->length(); 5493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < length; i++) { 5494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((*max_properties)-- == 0) return false; 5495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> value(fast_elements->get(i), isolate); 5496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value->IsJSObject()) { 5497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> value_object = Handle<JSObject>::cast(value); 5498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsFastLiteral(value_object, 5499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_depth - 1, 5500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_properties)) { 5501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 5502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (!boilerplate->HasFastDoubleElements()) { 5506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 5507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> properties(boilerplate->properties()); 5511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (properties->length() > 0) { 5512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 5513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<DescriptorArray> descriptors( 5515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate->map()->instance_descriptors()); 5516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int limit = boilerplate->map()->NumberOfOwnDescriptors(); 5517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < limit; i++) { 5518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyDetails details = descriptors->GetDetails(i); 5519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (details.type() != FIELD) continue; 5520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = descriptors->GetFieldIndex(i); 5521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((*max_properties)-- == 0) return false; 5522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> value(boilerplate->InObjectPropertyAt(index), isolate); 5523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value->IsJSObject()) { 5524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> value_object = Handle<JSObject>::cast(value); 5525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsFastLiteral(value_object, 5526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_depth - 1, 5527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_properties)) { 5528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 5529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 5534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 5538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->BuildConstantProperties(isolate()); 5542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 5543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* literal; 5544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check whether to use fast or slow deep-copying for boilerplate. 5546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int max_properties = kMaxFastLiteralProperties; 5547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> literals_cell(closure->literals()->get(expr->literal_index()), 5548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()); 5549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> site; 5550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> boilerplate; 5551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!literals_cell->IsUndefined()) { 5552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Retrieve the boilerplate 5553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site = Handle<AllocationSite>::cast(literals_cell); 5554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()), 5555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()); 5556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!boilerplate.is_null() && 5559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) { 5560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteUsageContext usage_context(isolate(), site, false); 5561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch usage_context.EnterNewScope(); 5562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch literal = BuildFastLiteral(boilerplate, &usage_context); 5563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch usage_context.ExitScope(site, boilerplate); 5564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 5566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> closure_literals(closure->literals(), isolate()); 5567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> constant_properties = expr->constant_properties(); 5568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int literal_index = expr->literal_index(); 5569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int flags = expr->fast_elements() 5570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; 5571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch flags |= expr->has_function() 5572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; 5573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(Add<HConstant>(closure_literals), 5575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(literal_index), 5576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(constant_properties), 5577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(flags)); 5578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(mvstanton): Add a flag to turn off creation of any 5580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // AllocationMementos for this call: we are in crankshaft and should have 5581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // learned enough about transition behavior to stop emitting mementos. 5582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::FunctionId function_id = Runtime::kCreateObjectLiteral; 5583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), 5584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::FunctionForId(function_id), 5585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4); 5586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The object is expected in the bailout environment during computation 5589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of the property values and is the value of the entire expression. 5590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(literal); 5591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->CalculateEmitStore(zone()); 5593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < expr->properties()->length(); i++) { 5595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ObjectLiteral::Property* property = expr->properties()->at(i); 5596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (property->IsCompileTimeValue()) continue; 5597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Literal* key = property->key(); 5599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* value = property->value(); 5600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (property->kind()) { 5602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ObjectLiteral::Property::MATERIALIZED_LITERAL: 5603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); 5604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fall through. 5605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ObjectLiteral::Property::COMPUTED: 5606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (key->value()->IsInternalizedString()) { 5607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (property->emit_store()) { 5608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(value)); 5609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 5610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = property->GetReceiverType(); 5611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> name = property->key()->AsPropertyName(); 5612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* store; 5613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is_null()) { 5614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we don't know the monomorphic type, do a generic store. 5615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(store = BuildNamedGeneric( 5616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STORE, NULL, literal, name, value)); 5617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessInfo info(this, STORE, ToType(map), name); 5619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info.CanAccessMonomorphic()) { 5620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_literal = Add<HCheckMaps>(literal, map); 5621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!info.IsAccessor()); 5622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store = BuildMonomorphicAccess( 5623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &info, literal, checked_literal, value, 5624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId::None(), BailoutId::None()); 5625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(store = BuildNamedGeneric( 5627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STORE, NULL, literal, name, value)); 5628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(store); 5631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (store->HasObservableSideEffects()) { 5632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(key->id(), REMOVABLE_SIMULATE); 5633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForEffect(value)); 5636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fall through. 5640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ObjectLiteral::Property::PROTOTYPE: 5641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ObjectLiteral::Property::SETTER: 5642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ObjectLiteral::Property::GETTER: 5643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kObjectLiteralWithComplexProperty); 5644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: UNREACHABLE(); 5645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->has_function()) { 5649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the result of the transformation to fast properties 5650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instead of the original since this operation changes the map 5651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of the object. This makes sure that the original object won't 5652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // be used by other optimized code before it is transformed 5653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (e.g. because of code motion). 5654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HToFastProperties* result = Add<HToFastProperties>(Pop()); 5655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(result); 5656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 5658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 5663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->BuildConstantElements(isolate()); 5667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Expression*>* subexprs = expr->values(); 5668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length = subexprs->length(); 5669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* literal; 5670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> site; 5672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> literals(environment()->closure()->literals(), isolate()); 5673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool uninitialized = false; 5674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> literals_cell(literals->get(expr->literal_index()), 5675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()); 5676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> boilerplate_object; 5677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (literals_cell->IsUndefined()) { 5678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uninitialized = true; 5679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> raw_boilerplate; 5680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSIGN_RETURN_ON_EXCEPTION_VALUE( 5681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate(), raw_boilerplate, 5682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::CreateArrayLiteralBoilerplate( 5683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate(), literals, expr->constant_elements()), 5684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bailout(kArrayBoilerplateCreationFailed)); 5685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate_object = Handle<JSObject>::cast(raw_boilerplate); 5687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteCreationContext creation_context(isolate()); 5688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site = creation_context.EnterNewScope(); 5689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (JSObject::DeepWalk(boilerplate_object, &creation_context).is_null()) { 5690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kArrayBoilerplateCreationFailed); 5691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch creation_context.ExitScope(site, boilerplate_object); 5693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch literals->set(expr->literal_index(), *site); 5694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (boilerplate_object->elements()->map() == 5696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->heap()->fixed_cow_array_map()) { 5697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->counters()->cow_arrays_created_runtime()->Increment(); 5698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(literals_cell->IsAllocationSite()); 5701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site = Handle<AllocationSite>::cast(literals_cell); 5702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate_object = Handle<JSObject>( 5703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::cast(site->transition_info()), isolate()); 5704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!boilerplate_object.is_null()); 5707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(site->SitePointsToLiteral()); 5708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind boilerplate_elements_kind = 5710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate_object->GetElementsKind(); 5711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check whether to use fast or slow deep-copying for boilerplate. 5713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int max_properties = kMaxFastLiteralProperties; 5714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFastLiteral(boilerplate_object, 5715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMaxFastLiteralDepth, 5716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &max_properties)) { 5717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteUsageContext usage_context(isolate(), site, false); 5718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch usage_context.EnterNewScope(); 5719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch literal = BuildFastLiteral(boilerplate_object, &usage_context); 5720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch usage_context.ExitScope(site, boilerplate_object); 5721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 5723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Boilerplate already exists and constant elements are never accessed, 5724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pass an empty fixed array to the runtime function instead. 5725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); 5726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int literal_index = expr->literal_index(); 5727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int flags = expr->depth() == 1 5728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? ArrayLiteral::kShallowElements 5729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : ArrayLiteral::kNoFlags; 5730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch flags |= ArrayLiteral::kDisableMementos; 5731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(Add<HConstant>(literals), 5733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(literal_index), 5734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(constants), 5735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(flags)); 5736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(mvstanton): Consider a flag to turn off creation of any 5738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // AllocationMementos for this call: we are in crankshaft and should have 5739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // learned enough about transition behavior to stop emitting mementos. 5740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral; 5741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), 5742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::FunctionForId(function_id), 5743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4); 5744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // De-opt if elements kind changed from boilerplate_elements_kind. 5746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate()); 5747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch literal = Add<HCheckMaps>(literal, map); 5748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The array is expected in the bailout environment during computation 5751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of the property values and is the value of the entire expression. 5752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(literal); 5753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The literal index is on the stack, too. 5754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Add<HConstant>(expr->literal_index())); 5755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* elements = NULL; 5757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < length; i++) { 5759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* subexpr = subexprs->at(i); 5760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the subexpression is a literal or a simple materialized literal it 5761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is already set in the cloned array. 5762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 5763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(subexpr)); 5765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 5766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!Smi::IsValid(i)) return Bailout(kNonSmiKeyInArrayLiteral); 5767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements = AddLoadElements(literal); 5769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = Add<HConstant>(i); 5771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (boilerplate_elements_kind) { 5773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_SMI_ELEMENTS: 5774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_HOLEY_SMI_ELEMENTS: 5775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_ELEMENTS: 5776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_HOLEY_ELEMENTS: 5777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_DOUBLE_ELEMENTS: 5778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_HOLEY_DOUBLE_ELEMENTS: { 5779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreKeyed* instr = Add<HStoreKeyed>(elements, key, value, 5780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate_elements_kind); 5781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetUninitialized(uninitialized); 5782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 5785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 5786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->GetIdForElement(i)); 5790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // array literal index 5793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 5794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object, 5798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map) { 5799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(object); 5800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HCheckMaps>(object, map); 5801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildLoadNamedField( 5805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessInfo* info, 5806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_object) { 5807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // See if this is a load for an immutable property 5808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (checked_object->ActualValue()->IsConstant()) { 5809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> object( 5810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(checked_object->ActualValue())->handle(isolate())); 5811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object->IsJSObject()) { 5813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupIterator it(object, info->name(), 5814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupIterator::OWN_SKIP_INTERCEPTOR); 5815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> value = JSObject::GetDataProperty(&it); 5816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (it.IsFound() && it.IsReadOnly() && !it.IsConfigurable()) { 5817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HConstant>(value); 5818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = info->access(); 5823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access.representation().IsDouble()) { 5824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the heap number. 5825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object = Add<HLoadNamedField>( 5826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object, static_cast<HValue*>(NULL), 5827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch access.WithRepresentation(Representation::Tagged())); 5828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the double value from it. 5829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch access = HObjectAccess::ForHeapNumberValue(); 5830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList* map_list = info->field_maps(); 5833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map_list->length() == 0) { 5834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HLoadNamedField>(checked_object, checked_object, access); 5835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniqueSet<Map>* maps = new(zone()) UniqueSet<Map>(map_list->length(), zone()); 5838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < map_list->length(); ++i) { 5839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch maps->Add(Unique<Map>::CreateImmovable(map_list->at(i)), zone()); 5840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HLoadNamedField>( 5842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object, checked_object, access, maps, info->field_type()); 5843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( 5847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessInfo* info, 5848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_object, 5849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value) { 5850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool transition_to_field = info->IsTransition(); 5851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(verwaest): Move this logic into PropertyAccessInfo. 5852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess field_access = info->access(); 5853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreNamedField *instr; 5855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (field_access.representation().IsDouble()) { 5856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess heap_number_access = 5857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch field_access.WithRepresentation(Representation::Tagged()); 5858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (transition_to_field) { 5859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The store requires a mutable HeapNumber to be allocated. 5860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_side_effects(this); 5861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); 5862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(hpayer): Allocation site pretenuring support. 5864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* heap_number = Add<HAllocate>(heap_number_size, 5865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HType::HeapObject(), 5866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NOT_TENURED, 5867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MUTABLE_HEAP_NUMBER_TYPE); 5868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddStoreMapConstant( 5869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_number, isolate()->factory()->mutable_heap_number_map()); 5870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), 5871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value); 5872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = New<HStoreNamedField>(checked_object->ActualValue(), 5873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_number_access, 5874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_number); 5875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Already holds a HeapNumber; load the box and write its value field. 5877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* heap_number = Add<HLoadNamedField>( 5878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object, static_cast<HValue*>(NULL), heap_number_access); 5879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = New<HStoreNamedField>(heap_number, 5880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForHeapNumberValue(), 5881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value, STORE_TO_INITIALIZED_ENTRY); 5882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (field_access.representation().IsHeapObject()) { 5885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(value); 5886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info->field_maps()->is_empty()) { 5889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(field_access.representation().IsHeapObject()); 5890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value = Add<HCheckMaps>(value, info->field_maps()); 5891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This is a normal store. 5894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = New<HStoreNamedField>( 5895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object->ActualValue(), field_access, value, 5896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch transition_to_field ? INITIALIZING_STORE : STORE_TO_INITIALIZED_ENTRY); 5897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (transition_to_field) { 5900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> transition(info->transition()); 5901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!transition->is_deprecated()); 5902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetTransition(Add<HConstant>(transition)); 5903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return instr; 5905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible( 5909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessInfo* info) { 5910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!CanInlinePropertyAccess(type_)) return false; 5911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Currently only handle Type::Number as a polymorphic case. 5913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber 5914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instruction. 5915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type_->Is(Type::Number())) return false; 5916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Values are only compatible for monomorphic load if they all behave the same 5918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // regarding value wrappers. 5919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type_->Is(Type::NumberOrString())) { 5920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info->type_->Is(Type::NumberOrString())) return false; 5921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->type_->Is(Type::NumberOrString())) return false; 5923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!LookupDescriptor()) return false; 5926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsFound()) { 5928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return (!info->IsFound() || info->has_holder()) && 5929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map()->prototype() == info->map()->prototype(); 5930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mismatch if the other access info found the property in the prototype 5933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chain. 5934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->has_holder()) return false; 5935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsAccessor()) { 5937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return accessor_.is_identical_to(info->accessor_) && 5938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch api_holder_.is_identical_to(info->api_holder_); 5939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstant()) { 5942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return constant_.is_identical_to(info->constant_); 5943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsField()); 5946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info->IsField()) return false; 5947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation r = access_.representation(); 5949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsLoad()) { 5950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info->access_.representation().IsCompatibleForLoad(r)) return false; 5951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info->access_.representation().IsCompatibleForStore(r)) return false; 5953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->access_.offset() != access_.offset()) return false; 5955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->access_.IsInobject() != access_.IsInobject()) return false; 5956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsLoad()) { 5957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (field_maps_.is_empty()) { 5958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->field_maps_.Clear(); 5959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (!info->field_maps_.is_empty()) { 5960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < field_maps_.length(); ++i) { 5961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->field_maps_.AddMapIfMissing(field_maps_.at(i), info->zone()); 5962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->field_maps_.Sort(); 5964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We can only merge stores that agree on their field maps. The comparison 5967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // below is safe, since we keep the field maps sorted. 5968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (field_maps_.length() != info->field_maps_.length()) return false; 5969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < field_maps_.length(); ++i) { 5970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!field_maps_.at(i).is_identical_to(info->field_maps_.at(i))) { 5971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 5972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->GeneralizeRepresentation(r); 5976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->field_type_ = info->field_type_.Combine(field_type_); 5977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 5978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::PropertyAccessInfo::LookupDescriptor() { 5982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!type_->IsClass()) return true; 5983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map()->LookupDescriptor(NULL, *name_, &lookup_); 5984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return LoadResult(map()); 5985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) { 5989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsLoad() && IsProperty() && IsReadOnly()) { 5990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 5991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsField()) { 5994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Construct the object field access. 5995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = GetLocalFieldIndexFromMap(map); 5996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch access_ = HObjectAccess::ForField(map, index, representation(), name_); 5997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load field map for heap objects. 5999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadFieldMaps(map); 6000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (IsAccessor()) { 6001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> accessors = GetAccessorsFromMap(map); 6002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!accessors->IsAccessorPair()) return false; 6003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* raw_accessor = 6004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsLoad() ? Handle<AccessorPair>::cast(accessors)->getter() 6005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Handle<AccessorPair>::cast(accessors)->setter(); 6006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!raw_accessor->IsJSFunction()) return false; 6007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor)); 6008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (accessor->shared()->IsApiFunction()) { 6009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallOptimization call_optimization(accessor); 6010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (call_optimization.is_simple_api_call()) { 6011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallOptimization::HolderLookup holder_lookup; 6012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> receiver_map = this->map(); 6013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch api_holder_ = call_optimization.LookupHolderOfExpectedType( 6014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver_map, &holder_lookup); 6015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch accessor_ = accessor; 6018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (IsConstant()) { 6019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_ = GetConstantFromMap(map); 6020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 6023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::PropertyAccessInfo::LoadFieldMaps( 6027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map) { 6028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Clear any previously collected field maps/type. 6029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch field_maps_.Clear(); 6030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch field_type_ = HType::Tagged(); 6031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Figure out the field type from the accessor map. 6033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<HeapType> field_type = GetFieldTypeFromMap(map); 6034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Collect the (stable) maps from the field type. 6036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int num_field_maps = field_type->NumClasses(); 6037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (num_field_maps == 0) return; 6038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(access_.representation().IsHeapObject()); 6039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch field_maps_.Reserve(num_field_maps, zone()); 6040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapType::Iterator<Map> it = field_type->Classes(); 6041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!it.Done()) { 6042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> field_map = it.Current(); 6043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!field_map->is_stable()) { 6044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch field_maps_.Clear(); 6045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 6046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch field_maps_.Add(field_map, zone()); 6048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch it.Advance(); 6049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch field_maps_.Sort(); 6051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(num_field_maps, field_maps_.length()); 6052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Determine field HType from field HeapType. 6054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch field_type_ = HType::FromType<HeapType>(field_type); 6055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(field_type_.IsHeapObject()); 6056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Add dependency on the map that introduced the field. 6058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map::AddDependentCompilationInfo(GetFieldOwnerFromMap(map), 6059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DependentCode::kFieldTypeGroup, top_info()); 6060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { 6064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = this->map(); 6065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (map->prototype()->IsJSObject()) { 6067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch holder_ = handle(JSObject::cast(map->prototype())); 6068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (holder_->map()->is_deprecated()) { 6069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::TryMigrateInstance(holder_); 6070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map = Handle<Map>(holder_->map()); 6072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!CanInlinePropertyAccess(ToType(map))) { 6073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lookup_.NotFound(); 6074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 6075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->LookupDescriptor(*holder_, *name_, &lookup_); 6077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFound()) return LoadResult(map); 6078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lookup_.NotFound(); 6080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 6081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() { 6085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!CanInlinePropertyAccess(type_)) return false; 6086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsJSObjectFieldAccessor()) return IsLoad(); 6087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (this->map()->function_with_prototype() && 6088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !this->map()->has_non_instance_prototype() && 6089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch name_.is_identical_to(isolate()->factory()->prototype_string())) { 6090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return IsLoad(); 6091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!LookupDescriptor()) return false; 6093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFound()) return IsLoad() || !IsReadOnly(); 6094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!LookupInPrototypes()) return false; 6095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsLoad()) return true; 6096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsAccessor()) return true; 6098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = this->map(); 6099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->LookupTransition(NULL, *name_, &lookup_); 6100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (lookup_.IsTransitionToField() && map->unused_property_fields() > 0) { 6101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Construct the object field access. 6102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int descriptor = transition()->LastAdded(); 6103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = 6104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch transition()->instance_descriptors()->GetFieldIndex(descriptor) - 6105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->inobject_properties(); 6106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyDetails details = 6107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch transition()->instance_descriptors()->GetDetails(descriptor); 6108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation representation = details.representation(); 6109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch access_ = HObjectAccess::ForField(map, index, representation, name_); 6110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load field map for heap objects. 6112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadFieldMaps(transition()); 6113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 6114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 6116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic( 6120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList* types) { 6121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(type_->Is(ToType(types->first()))); 6122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!CanAccessMonomorphic()) return false; 6123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism); 6124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (types->length() > kMaxLoadPolymorphism) return false; 6125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = HObjectAccess::ForMap(); // bogus default 6127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (GetJSObjectFieldAccess(&access)) { 6128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 1; i < types->length(); ++i) { 6129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessInfo test_info( 6130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_, access_type_, ToType(types->at(i)), name_); 6131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess test_access = HObjectAccess::ForMap(); // bogus default 6132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!test_info.GetJSObjectFieldAccess(&test_access)) return false; 6133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!access.Equals(test_access)) return false; 6134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 6136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Currently only handle Type::Number as a polymorphic case. 6139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber 6140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instruction. 6141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type_->Is(Type::Number())) return false; 6142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Multiple maps cannot transition to the same target map. 6144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsLoad() || !IsTransition()); 6145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsTransition() && types->length() > 1) return false; 6146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 1; i < types->length(); ++i) { 6148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessInfo test_info( 6149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_, access_type_, ToType(types->at(i)), name_); 6150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!test_info.IsCompatible(this)) return false; 6151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 6154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Map> HOptimizedGraphBuilder::PropertyAccessInfo::map() { 6158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSFunction* ctor = IC::GetRootConstructor( 6159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch type_, current_info()->closure()->context()->native_context()); 6160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ctor != NULL) return handle(ctor->initial_map()); 6161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return type_->AsClass()->Map(); 6162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool NeedsWrappingFor(Type* type, Handle<JSFunction> target) { 6166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return type->Is(Type::NumberOrString()) && 6167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target->shared()->strict_mode() == SLOPPY && 6168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !target->shared()->native(); 6169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess( 6173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessInfo* info, 6174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object, 6175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_object, 6176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value, 6177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id, 6178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId return_id, 6179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool can_inline_accessor) { 6180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = HObjectAccess::ForMap(); // bogus default 6182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->GetJSObjectFieldAccess(&access)) { 6183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(info->IsLoad()); 6184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HLoadNamedField>(object, checked_object, access); 6185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->name().is_identical_to(isolate()->factory()->prototype_string()) && 6188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->map()->function_with_prototype()) { 6189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!info->map()->has_non_instance_prototype()); 6190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HLoadFunctionPrototype>(checked_object); 6191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_holder = checked_object; 6194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->has_holder()) { 6195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> prototype(JSObject::cast(info->map()->prototype())); 6196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_holder = BuildCheckPrototypeMaps(prototype, info->holder()); 6197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info->IsFound()) { 6200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(info->IsLoad()); 6201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return graph()->GetConstantUndefined(); 6202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->IsField()) { 6205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->IsLoad()) { 6206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildLoadNamedField(info, checked_holder); 6207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildStoreNamedField(info, checked_object, value); 6209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->IsTransition()) { 6213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!info->IsLoad()); 6214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildStoreNamedField(info, checked_object, value); 6215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->IsAccessor()) { 6218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(checked_object); 6219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = 1; 6220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info->IsLoad()) { 6221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch argument_count = 2; 6222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(value); 6223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (NeedsWrappingFor(info->type(), info->accessor())) { 6226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = Add<HConstant>(info->accessor()); 6227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argument_count); 6228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HCallFunction>(function, argument_count, WRAP_AND_CALL); 6229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (FLAG_inline_accessors && can_inline_accessor) { 6230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool success = info->IsLoad() 6231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) 6232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : TryInlineSetter( 6233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->accessor(), info->map(), ast_id, return_id, value); 6234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (success || HasStackOverflow()) return NULL; 6235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argument_count); 6238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildCallConstantFunction(info->accessor(), argument_count); 6239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(info->IsConstant()); 6242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->IsLoad()) { 6243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HConstant>(info->constant()); 6244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant())); 6246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( 6251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessType access_type, 6252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* expr, 6253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id, 6254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId return_id, 6255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object, 6256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value, 6257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList* types, 6258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> name) { 6259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Something did not match; must use a polymorphic load. 6260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int count = 0; 6261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = NULL; 6262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* number_block = NULL; 6263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool handled_string = false; 6264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool handle_smi = false; 6266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism); 6267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int i; 6268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { 6269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessInfo info(this, access_type, ToType(types->at(i)), name); 6270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info.type()->Is(Type::String())) { 6271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (handled_string) continue; 6272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handled_string = true; 6273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info.CanAccessMonomorphic()) { 6275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch count++; 6276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info.type()->Is(Type::Number())) { 6277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle_smi = true; 6278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 6279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i < types->length()) { 6284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch count = -1; 6285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch types->Clear(); 6286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch count = 0; 6288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HControlInstruction* smi_check = NULL; 6290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handled_string = false; 6291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { 6293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessInfo info(this, access_type, ToType(types->at(i)), name); 6294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info.type()->Is(Type::String())) { 6295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (handled_string) continue; 6296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handled_string = true; 6297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info.CanAccessMonomorphic()) continue; 6299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (count == 0) { 6301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch join = graph()->CreateBasicBlock(); 6302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (handle_smi) { 6303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); 6304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); 6305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_block = graph()->CreateBasicBlock(); 6306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch smi_check = New<HIsSmiAndBranch>( 6307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, empty_smi_block, not_smi_block); 6308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(smi_check); 6309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GotoNoSimulate(empty_smi_block, number_block); 6310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(not_smi_block); 6311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(object); 6313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++count; 6316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_true = graph()->CreateBasicBlock(); 6317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_false = graph()->CreateBasicBlock(); 6318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HUnaryControlInstruction* compare; 6319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dependency; 6321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info.type()->Is(Type::Number())) { 6322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); 6323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare = New<HCompareMap>(object, heap_number_map, if_true, if_false); 6324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dependency = smi_check; 6325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (info.type()->Is(Type::String())) { 6326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare = New<HIsStringAndBranch>(object, if_true, if_false); 6327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dependency = compare; 6328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare = New<HCompareMap>(object, info.map(), if_true, if_false); 6330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dependency = compare; 6331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(compare); 6333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info.type()->Is(Type::Number())) { 6335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GotoNoSimulate(if_true, number_block); 6336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_true = number_block; 6337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(if_true); 6340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* access = BuildMonomorphicAccess( 6342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &info, object, dependency, value, ast_id, 6343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return_id, FLAG_polymorphic_inlining); 6344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result = NULL; 6346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (access_type) { 6347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LOAD: 6348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = access; 6349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 6350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case STORE: 6351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = value; 6352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 6353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access == NULL) { 6356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasStackOverflow()) return; 6357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!access->IsLinked()) AddInstruction(access); 6359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(result); 6360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_block() != NULL) Goto(join); 6363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(if_false); 6364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Finish up. Unconditionally deoptimize if we've handled all the maps we 6367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // know about and do not want to handle ones we've never seen. Otherwise 6368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // use a generic IC. 6369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 6370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishExitWithHardDeoptimization("Uknown map in polymorphic access"); 6371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = BuildNamedGeneric(access_type, expr, object, name, 6373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value); 6374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(instr); 6375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value); 6376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (join != NULL) { 6378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(join); 6379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 6383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(join != NULL); 6387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (join->HasPredecessor()) { 6388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch join->SetJoinId(ast_id); 6389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(join); 6390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 6393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool ComputeReceiverTypes(Expression* expr, 6398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver, 6399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList** t, 6400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone) { 6401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList* types = expr->GetReceiverTypes(); 6402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *t = types; 6403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool monomorphic = expr->IsMonomorphic(); 6404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (types != NULL && receiver->HasMonomorphicJSObjectType()) { 6405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap(); 6406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch types->FilterForPossibleTransitions(root_map); 6407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch monomorphic = types->length() == 1; 6408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return monomorphic && 6410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CanInlinePropertyAccess(IC::MapToType<Type>(types->first(), zone)); 6411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool AreStringTypes(SmallMapList* types) { 6415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < types->length(); i++) { 6416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (types->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false; 6417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 6419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildStore(Expression* expr, 6423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Property* prop, 6424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id, 6425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId return_id, 6426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_uninitialized) { 6427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!prop->key()->IsPropertyName()) { 6428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keyed store. 6429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 6430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = Pop(); 6431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object = Pop(); 6432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_side_effects = false; 6433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result = HandleKeyedElementAccess( 6434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, key, value, expr, ast_id, return_id, STORE, &has_side_effects); 6435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (has_side_effects) { 6436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(value); 6437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Drop(1); 6439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (result == NULL) return; 6441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(value); 6442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Named store. 6445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 6446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object = Pop(); 6447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Literal* key = prop->key()->AsLiteral(); 6449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> name = Handle<String>::cast(key->value()); 6450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!name.is_null()); 6451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = BuildNamedAccess(STORE, ast_id, return_id, expr, 6453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, name, value, is_uninitialized); 6454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr == NULL) return; 6455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(value); 6457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(instr); 6458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 6459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Drop(1); 6462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(value); 6463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 6467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Property* prop = expr->target()->AsProperty(); 6468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(prop != NULL); 6469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(prop->obj())); 6470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!prop->key()->IsPropertyName()) { 6471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(prop->key())); 6472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->value())); 6474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildStore(expr, prop, expr->id(), 6475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->AssignmentId(), expr->IsUninitialized()); 6476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Because not every expression has a position and there is not common 6480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// superclass of Assignment and CountOperation, we cannot just pass the 6481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// owning expression instead of position and ast_id separately. 6482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::HandleGlobalVariableAssignment( 6483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* var, 6484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value, 6485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id) { 6486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<GlobalObject> global(current_info()->global_object()); 6487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupIterator it(global, var->name(), LookupIterator::OWN_SKIP_INTERCEPTOR); 6488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); 64898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (type == kUseCell) { 6490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<PropertyCell> cell = it.GetPropertyCell(); 6491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cell->type()->IsConstant()) { 6492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> constant = cell->type()->AsConstant()->Value(); 6493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value->IsConstant()) { 6494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* c_value = HConstant::cast(value); 6495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!constant.is_identical_to(c_value->handle(isolate()))) { 6496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HDeoptimize>("Constant global variable assignment", 6497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Deoptimizer::EAGER); 6498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* c_constant = Add<HConstant>(constant); 6501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder builder(this); 6502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (constant->IsNumber()) { 6503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ); 6504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder.If<HCompareObjectEqAndBranch>(value, c_constant); 6506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder.Then(); 6508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder.Else(); 6509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HDeoptimize>("Constant global variable assignment", 6510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Deoptimizer::EAGER); 6511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder.End(); 6512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 65143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HInstruction* instr = 6515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreGlobalCell>(value, cell, it.property_details()); 6516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 6517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* global_object = Add<HLoadNamedField>( 6521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context(), static_cast<HValue*>(NULL), 6522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 6523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreNamedGeneric* instr = 6524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedGeneric>(global_object, var->name(), 6525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value, function_strict_mode()); 6526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch USE(instr); 6527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(instr->HasObservableSideEffects()); 6528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 6534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* target = expr->target(); 6535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VariableProxy* proxy = target->AsVariableProxy(); 6536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Property* prop = target->AsProperty(); 6537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(proxy == NULL || prop == NULL); 6538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have a second position recorded in the FullCodeGenerator to have 6540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // type feedback for the binary operation. 6541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BinaryOperation* operation = expr->binary_operation(); 6542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (proxy != NULL) { 6544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* var = proxy->var(); 6545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (var->mode() == LET) { 6546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kUnsupportedLetCompoundAssignment); 6547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(operation)); 6550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (var->location()) { 6552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::UNALLOCATED: 6553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleGlobalVariableAssignment(var, 6554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Top(), 6555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->AssignmentId()); 6556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 6557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::PARAMETER: 6559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::LOCAL: 6560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (var->mode() == CONST_LEGACY) { 6561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kUnsupportedConstCompoundAssignment); 6562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BindIfLive(var, Top()); 6564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 6565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::CONTEXT: { 6567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bail out if we try to mutate a parameter value in a function 6568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // using the arguments object. We do not (yet) correctly handle the 6569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // arguments property of the function. 6570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_info()->scope()->arguments() != NULL) { 6571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Parameters will be allocated to context slots. We have no 6572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // direct way to detect that the variable is a parameter so we do 6573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a linear search of the parameter variables. 6574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int count = current_info()->scope()->num_parameters(); 6575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < count; ++i) { 6576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (var == current_info()->scope()->parameter(i)) { 6577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bailout(kAssignmentToParameterFunctionUsesArgumentsObject); 6578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreContextSlot::Mode mode; 6583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (var->mode()) { 6585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LET: 6586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode = HStoreContextSlot::kCheckDeoptimize; 6587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 6588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CONST: 6589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This case is checked statically so no need to 6590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // perform checks here 6591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 6592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CONST_LEGACY: 6593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 6594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 6595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode = HStoreContextSlot::kNoCheck; 6596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = BuildContextChainWalk(var); 6599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreContextSlot* instr = Add<HStoreContextSlot>( 6600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context, var->index(), mode, Top()); 6601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 6602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 6603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 6605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::LOOKUP: 6608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kCompoundAssignmentToLookupSlot); 6609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 6611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (prop != NULL) { 6613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(prop->obj())); 6614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object = Top(); 6615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = NULL; 6616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!prop->key()->IsPropertyName() || prop->IsStringAccess()) { 6617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(prop->key())); 6618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key = Top(); 6619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(PushLoad(prop, object, key)); 6622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->value())); 6624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right = Pop(); 6625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left = Pop(); 6626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(BuildBinaryOperation(operation, left, right, PUSH_BEFORE_SIMULATE)); 6628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildStore(expr, prop, expr->id(), 6630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->AssignmentId(), expr->IsUninitialized()); 6631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kInvalidLhsInCompoundAssignment); 6633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { 6638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 6639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 6640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 6641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VariableProxy* proxy = expr->target()->AsVariableProxy(); 6642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Property* prop = expr->target()->AsProperty(); 6643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(proxy == NULL || prop == NULL); 6644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->is_compound()) { 6646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleCompoundAssignment(expr); 6647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 6648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (prop != NULL) { 6651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandlePropertyAssignment(expr); 6652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (proxy != NULL) { 6653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* var = proxy->var(); 6654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (var->mode() == CONST) { 6656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->op() != Token::INIT_CONST) { 6657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kNonInitializerAssignmentToConst); 6658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (var->mode() == CONST_LEGACY) { 6660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->op() != Token::INIT_CONST_LEGACY) { 6661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->value())); 6662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 6663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (var->IsStackAllocated()) { 6666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We insert a use of the old value to detect unsupported uses of const 6667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // variables (e.g. initialization inside a loop). 6668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* old_value = environment()->Lookup(var); 6669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HUseConst>(old_value); 6670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (proxy->IsArguments()) return Bailout(kAssignmentToArguments); 6674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle the assignment. 6676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (var->location()) { 6677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::UNALLOCATED: 6678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->value())); 6679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleGlobalVariableAssignment(var, 6680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Top(), 6681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->AssignmentId()); 6682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 6683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::PARAMETER: 6685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::LOCAL: { 6686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Perform an initialization check for let declared variables 6687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // or parameters. 6688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (var->mode() == LET && expr->op() == Token::ASSIGN) { 6689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* env_value = environment()->Lookup(var); 6690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (env_value == graph()->GetConstantHole()) { 6691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kAssignmentToLetVariableBeforeInitialization); 6692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We do not allow the arguments object to occur in a context where it 6695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // may escape, but assignments to stack-allocated locals are 6696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // permitted. 6697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); 6698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 6699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BindIfLive(var, value); 6700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(value); 6701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::CONTEXT: { 6704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bail out if we try to mutate a parameter value in a function using 6705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the arguments object. We do not (yet) correctly handle the 6706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // arguments property of the function. 6707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_info()->scope()->arguments() != NULL) { 6708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Parameters will rewrite to context slots. We have no direct way 6709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to detect that the variable is a parameter. 6710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int count = current_info()->scope()->num_parameters(); 6711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < count; ++i) { 6712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (var == current_info()->scope()->parameter(i)) { 6713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kAssignmentToParameterInArgumentsObject); 6714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->value())); 6719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreContextSlot::Mode mode; 6720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->op() == Token::ASSIGN) { 6721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (var->mode()) { 6722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LET: 6723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode = HStoreContextSlot::kCheckDeoptimize; 6724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 6725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CONST: 6726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This case is checked statically so no need to 6727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // perform checks here 6728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 6729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CONST_LEGACY: 6730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 6731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 6732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode = HStoreContextSlot::kNoCheck; 6733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (expr->op() == Token::INIT_VAR || 6735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->op() == Token::INIT_LET || 6736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->op() == Token::INIT_CONST) { 6737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode = HStoreContextSlot::kNoCheck; 6738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->op() == Token::INIT_CONST_LEGACY); 6740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode = HStoreContextSlot::kCheckIgnoreAssignment; 6742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = BuildContextChainWalk(var); 6745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreContextSlot* instr = Add<HStoreContextSlot>( 6746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context, var->index(), mode, Top()); 6747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 6748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 6749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 6751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::LOOKUP: 6754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kAssignmentToLOOKUPVariable); 6755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kInvalidLeftHandSideInAssignment); 6758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitYield(Yield* expr) { 6763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generators are not optimized, so we should never get here. 6764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 6765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitThrow(Throw* expr) { 6769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 6770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 6771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 6772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) { 6773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The parser turns invalid left-hand sides in assignments into throw 6774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // statements, which may not be in effect contexts. We might still try 6775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to optimize such functions; bail out now if we do. 6776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kInvalidLeftHandSideInAssignment); 6777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->exception())); 6779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = environment()->Pop(); 6781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 6782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(value); 6783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCallRuntime>(isolate()->factory()->empty_string(), 6784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::FunctionForId(Runtime::kThrow), 1); 6785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->id()); 6786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the throw definitely exits the function, we can finish with a dummy 6788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // control flow at this point. This is not the case if the throw is inside 6789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // an inlined function which may be replaced. 6790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (call_context() == NULL) { 6791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishExitCurrentBlock(New<HAbnormalExit>()); 6792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) { 6797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (string->IsConstant()) { 6798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* c_string = HConstant::cast(string); 6799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (c_string->HasStringValue()) { 6800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HConstant>(c_string->StringValue()->map()->instance_type()); 6801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HLoadNamedField>( 6804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadNamedField>(string, static_cast<HValue*>(NULL), 6805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMap()), 6806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<HValue*>(NULL), HObjectAccess::ForMapInstanceType()); 6807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::AddLoadStringLength(HValue* string) { 6811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (string->IsConstant()) { 6812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* c_string = HConstant::cast(string); 6813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (c_string->HasStringValue()) { 6814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HConstant>(c_string->StringValue()->length()); 6815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HLoadNamedField>(string, static_cast<HValue*>(NULL), 6818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForStringLength()); 6819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( 6823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessType access_type, 6824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* expr, 6825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object, 6826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> name, 6827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value, 6828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_uninitialized) { 6829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_uninitialized) { 6830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HDeoptimize>("Insufficient type feedback for generic named access", 6831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Deoptimizer::SOFT); 6832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == LOAD) { 6834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoadNamedGeneric* result = New<HLoadNamedGeneric>(object, name); 6835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_vector_ics) { 6836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<SharedFunctionInfo> current_shared = 6837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state()->compilation_info()->shared_info(); 6838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->SetVectorAndSlot( 6839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle(current_shared->feedback_vector(), isolate()), 6840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->AsProperty()->PropertyFeedbackSlot()); 6841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 6843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HStoreNamedGeneric>(object, name, value, function_strict_mode()); 6845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric( 6851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessType access_type, 6852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* expr, 6853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object, 6854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key, 6855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value) { 6856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == LOAD) { 6857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>(object, key); 6858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_vector_ics) { 6859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<SharedFunctionInfo> current_shared = 6860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state()->compilation_info()->shared_info(); 6861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->SetVectorAndSlot( 6862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle(current_shared->feedback_vector(), isolate()), 6863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->AsProperty()->PropertyFeedbackSlot()); 6864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 6866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HStoreKeyedGeneric>(object, key, value, function_strict_mode()); 6868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) { 6873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Loads from a "stock" fast holey double arrays can elide the hole check. 6874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; 6875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && 6876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->IsFastArrayConstructorPrototypeChainIntact()) { 6877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); 6878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); 6879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckPrototypeMaps(prototype, object_prototype); 6880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch load_mode = ALLOW_RETURN_HOLE; 6881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->MarkDependsOnEmptyArrayProtoElements(); 6882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return load_mode; 6885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( 6889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object, 6890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key, 6891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* val, 6892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dependency, 6893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map, 6894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessType access_type, 6895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch KeyedAccessStoreMode store_mode) { 6896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCheckMaps* checked_object = Add<HCheckMaps>(object, map, dependency); 6897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (dependency) { 6898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object->ClearDependsOnFlag(kElementsKind); 6899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == STORE && map->prototype()->IsJSObject()) { 6902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // monomorphic stores need a prototype chain check because shape 6903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // changes could allow callbacks on elements in the chain that 6904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // aren't compatible with monomorphic keyed stores. 6905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrototypeIterator iter(map); 6906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject* holder = NULL; 6907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!iter.IsAtEnd()) { 6908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch holder = JSObject::cast(*PrototypeIterator::GetCurrent(iter)); 6909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iter.Advance(); 6910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(holder && holder->IsJSObject()); 6912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckPrototypeMaps(handle(JSObject::cast(map->prototype())), 6914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject>(holder)); 6915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); 6918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildUncheckedMonomorphicElementAccess( 6919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object, key, val, 6920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->instance_type() == JS_ARRAY_TYPE, 6921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->elements_kind(), access_type, 6922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch load_mode, store_mode); 6923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( 6927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object, 6928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key, 6929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* val, 6930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList* maps) { 6931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For polymorphic loads of similar elements kinds (i.e. all tagged or all 6932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // double), always use the "worst case" code without a transition. This is 6933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // much faster than transitioning the elements to the worst case, trading a 6934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // HTransitionElements for a HCheckMaps, and avoiding mutation of the array. 6935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_double_maps = false; 6936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_smi_or_object_maps = false; 6937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_js_array_access = false; 6938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_non_js_array_access = false; 6939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_seen_holey_elements = false; 6940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> most_general_consolidated_map; 6941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < maps->length(); ++i) { 6942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = maps->at(i); 6943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!map->IsJSObjectMap()) return NULL; 6944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Don't allow mixing of JSArrays with JSObjects. 6945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map->instance_type() == JS_ARRAY_TYPE) { 6946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (has_non_js_array_access) return NULL; 6947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch has_js_array_access = true; 6948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (has_js_array_access) { 6949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 6950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch has_non_js_array_access = true; 6952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Don't allow mixed, incompatible elements kinds. 6954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map->has_fast_double_elements()) { 6955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (has_smi_or_object_maps) return NULL; 6956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch has_double_maps = true; 6957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (map->has_fast_smi_or_object_elements()) { 6958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (has_double_maps) return NULL; 6959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch has_smi_or_object_maps = true; 6960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 6962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remember if we've ever seen holey elements. 6964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsHoleyElementsKind(map->elements_kind())) { 6965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch has_seen_holey_elements = true; 6966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remember the most general elements kind, the code for its load will 6968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // properly handle all of the more specific cases. 6969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((i == 0) || IsMoreGeneralElementsKindTransition( 6970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch most_general_consolidated_map->elements_kind(), 6971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->elements_kind())) { 6972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch most_general_consolidated_map = map; 6973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!has_double_maps && !has_smi_or_object_maps) return NULL; 6976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCheckMaps* checked_object = Add<HCheckMaps>(object, maps); 6978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // FAST_ELEMENTS is considered more general than FAST_HOLEY_SMI_ELEMENTS. 6979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we've seen both, the consolidated load must use FAST_HOLEY_ELEMENTS. 6980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind consolidated_elements_kind = has_seen_holey_elements 6981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? GetHoleyElementsKind(most_general_consolidated_map->elements_kind()) 6982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : most_general_consolidated_map->elements_kind(); 6983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = BuildUncheckedMonomorphicElementAccess( 6984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object, key, val, 6985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, 6986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch consolidated_elements_kind, 6987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOAD, NEVER_RETURN_HOLE, STANDARD_STORE); 6988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return instr; 6989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( 6993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* expr, 6994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object, 6995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key, 6996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* val, 6997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList* maps, 6998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessType access_type, 6999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch KeyedAccessStoreMode store_mode, 7000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool* has_side_effects) { 7001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *has_side_effects = false; 7002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(object); 7003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == LOAD) { 7005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* consolidated_load = 7006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TryBuildConsolidatedElementLoad(object, key, val, maps); 7007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (consolidated_load != NULL) { 7008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *has_side_effects |= consolidated_load->HasObservableSideEffects(); 7009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return consolidated_load; 7010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Elements_kind transition support. 7014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapHandleList transition_target(maps->length()); 7015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Collect possible transition targets. 7016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapHandleList possible_transitioned_maps(maps->length()); 7017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < maps->length(); ++i) { 7018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = maps->at(i); 7019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind = map->elements_kind(); 7020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFastElementsKind(elements_kind) && 7021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind != GetInitialFastElementsKind()) { 7022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch possible_transitioned_maps.Add(map); 7023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) { 7025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = BuildKeyedGeneric(access_type, expr, object, key, 7026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch val); 7027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *has_side_effects = result->HasObservableSideEffects(); 7028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddInstruction(result); 7029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Get transition target for each map (NULL == no transition). 7032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < maps->length(); ++i) { 7033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = maps->at(i); 7034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> transitioned_map = 7035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->FindTransitionedMap(&possible_transitioned_maps); 7036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch transition_target.Add(transitioned_map); 7037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapHandleList untransitionable_maps(maps->length()); 7040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HTransitionElementsKind* transition = NULL; 7041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < maps->length(); ++i) { 7042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = maps->at(i); 7043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(map->IsMap()); 7044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!transition_target.at(i).is_null()) { 7045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Map::IsValidElementsTransition( 7046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->elements_kind(), 7047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch transition_target.at(i)->elements_kind())); 7048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch transition = Add<HTransitionElementsKind>(object, map, 7049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch transition_target.at(i)); 7050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch untransitionable_maps.Add(map); 7052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If only one map is left after transitioning, handle this case 7056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // monomorphically. 7057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(untransitionable_maps.length() >= 1); 7058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (untransitionable_maps.length() == 1) { 7059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> untransitionable_map = untransitionable_maps[0]; 7060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = NULL; 7061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (untransitionable_map->has_slow_elements_kind() || 7062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !untransitionable_map->IsJSObjectMap()) { 7063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key, 7064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch val)); 7065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = BuildMonomorphicElementAccess( 7067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, key, val, transition, untransitionable_map, access_type, 7068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_mode); 7069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *has_side_effects |= instr->HasObservableSideEffects(); 7071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return access_type == STORE ? val : instr; 7072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = graph()->CreateBasicBlock(); 7075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < untransitionable_maps.length(); ++i) { 7077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = untransitionable_maps[i]; 7078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!map->IsJSObjectMap()) continue; 7079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind = map->elements_kind(); 7080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* this_map = graph()->CreateBasicBlock(); 7081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* other_map = graph()->CreateBasicBlock(); 7082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCompareMap* mapcompare = 7083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HCompareMap>(object, map, this_map, other_map); 7084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(mapcompare); 7085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(this_map); 7087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* access = NULL; 7088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsDictionaryElementsKind(elements_kind)) { 7089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch access = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key, 7090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch val)); 7091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsFastElementsKind(elements_kind) || 7093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsExternalArrayElementsKind(elements_kind) || 7094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsFixedTypedArrayElementsKind(elements_kind)); 7095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); 7096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Happily, mapcompare is a checked object. 7097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch access = BuildUncheckedMonomorphicElementAccess( 7098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mapcompare, key, val, 7099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->instance_type() == JS_ARRAY_TYPE, 7100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind, access_type, 7101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch load_mode, 7102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_mode); 7103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *has_side_effects |= access->HasObservableSideEffects(); 7105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The caller will use has_side_effects and add a correct Simulate. 7106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch access->SetFlag(HValue::kHasNoObservableSideEffects); 7107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == LOAD) { 7108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(access); 7109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope scope(this); 7111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GotoNoSimulate(join); 7112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(other_map); 7113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Ensure that we visited at least one map above that goes to join. This is 7116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // necessary because FinishExitWithHardDeoptimization does an AbnormalExit 7117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // rather than joining the join block. If this becomes an issue, insert a 7118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // generic access in the case length() == 0. 7119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(join->predecessors()->length() > 0); 7120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Deopt if none of the cases matched. 7121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope scope(this); 7122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishExitWithHardDeoptimization("Unknown map in polymorphic element access"); 7123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(join); 7124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return access_type == STORE ? val : Pop(); 7125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( 7129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* obj, HValue* key, HValue* val, Expression* expr, BailoutId ast_id, 7130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId return_id, PropertyAccessType access_type, 7131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool* has_side_effects) { 7132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (key->ActualValue()->IsConstant()) { 7133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> constant = 7134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(key->ActualValue())->handle(isolate()); 7135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t array_index; 7136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (constant->IsString() && 7137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !Handle<String>::cast(constant)->AsArrayIndex(&array_index)) { 7138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!constant->IsUniqueName()) { 7139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant = isolate()->factory()->InternalizeString( 7140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String>::cast(constant)); 7141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = 7143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildNamedAccess(access_type, ast_id, return_id, expr, obj, 7144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String>::cast(constant), val, false); 7145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr == NULL || instr->IsLinked()) { 7146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *has_side_effects = false; 7147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(instr); 7149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *has_side_effects = instr->HasObservableSideEffects(); 7150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return instr; 7152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!expr->IsPropertyName()); 7156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = NULL; 7157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList* types; 7159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone()); 7160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool force_generic = false; 7162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == STORE && 7163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (monomorphic || (types != NULL && !types->is_empty()))) { 7164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Stores can't be mono/polymorphic if their prototype chain has dictionary 7165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // elements. However a receiver map that has dictionary elements itself 7166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // should be left to normal mono/poly behavior (the other maps may benefit 7167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // from highly optimized stores). 7168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < types->length(); i++) { 7169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> current_map = types->at(i); 7170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_map->DictionaryElementsInPrototypeChainOnly()) { 7171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch force_generic = true; 7172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch monomorphic = false; 7173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 7174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (monomorphic) { 7179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = types->first(); 7180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map->has_slow_elements_kind() || !map->IsJSObjectMap()) { 7181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key, 7182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch val)); 7183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(obj); 7185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = BuildMonomorphicElementAccess( 7186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj, key, val, NULL, map, access_type, expr->GetStoreMode()); 7187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (!force_generic && (types != NULL && !types->is_empty())) { 7189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return HandlePolymorphicElementAccess( 7190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr, obj, key, val, types, access_type, 7191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->GetStoreMode(), has_side_effects); 7192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == STORE) { 7194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->IsAssignment() && 7195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->AsAssignment()->HasNoTypeInformation()) { 7196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HDeoptimize>("Insufficient type feedback for keyed store", 7197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Deoptimizer::SOFT); 7198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->AsProperty()->HasNoTypeInformation()) { 7201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HDeoptimize>("Insufficient type feedback for keyed load", 7202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Deoptimizer::SOFT); 7203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key, val)); 7206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *has_side_effects = instr->HasObservableSideEffects(); 7208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return instr; 7209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { 7213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Outermost function already has arguments on the stack. 7214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function_state()->outer() == NULL) return; 7215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function_state()->arguments_pushed()) return; 7217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Push arguments when entering inlined function. 7219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnterInlined* entry = function_state()->entry(); 7220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry->set_arguments_pushed(); 7221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HArgumentsObject* arguments = entry->arguments_object(); 7223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ZoneList<HValue*>* arguments_values = arguments->arguments_values(); 7224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* insert_after = entry; 7226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < arguments_values->length(); i++) { 7227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* argument = arguments_values->at(i); 7228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* push_argument = New<HPushArguments>(argument); 7229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch push_argument->InsertAfter(insert_after); 7230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch insert_after = push_argument; 7231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HArgumentsElements* arguments_elements = New<HArgumentsElements>(true); 7234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_elements->ClearFlag(HValue::kUseGVN); 7235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_elements->InsertAfter(insert_after); 7236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state()->set_arguments_elements(arguments_elements); 7237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { 7241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VariableProxy* proxy = expr->obj()->AsVariableProxy(); 7242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (proxy == NULL) return false; 7243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!proxy->var()->IsStackAllocated()) return false; 7244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { 7245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 7246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NULL; 7249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->key()->IsPropertyName()) { 7250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 7251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!String::Equals(name, isolate()->factory()->length_string())) { 7252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 7253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function_state()->outer() == NULL) { 7256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* elements = Add<HArgumentsElements>(false); 7257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = New<HArgumentsLength>(elements); 7258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Number of arguments without receiver. 7260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = environment()-> 7261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_environment()->parameter_count() - 1; 7262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = New<HConstant>(argument_count); 7263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(graph()->GetArgumentsObject()); 7266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE_OR_RETURN(VisitForValue(expr->key()), true); 7267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = Pop(); 7268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Arguments object. 7269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function_state()->outer() == NULL) { 7270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* elements = Add<HArgumentsElements>(false); 7271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* length = Add<HArgumentsLength>(elements); 7272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* checked_key = Add<HBoundsCheck>(key, length); 7273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = New<HAccessArgumentsAt>(elements, length, checked_key); 7274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnsureArgumentsArePushedForAccess(); 7276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Number of arguments without receiver. 7278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* elements = function_state()->arguments_elements(); 7279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = environment()-> 7280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_environment()->parameter_count() - 1; 7281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* length = Add<HConstant>(argument_count); 7282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* checked_key = Add<HBoundsCheck>(key, length); 7283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = New<HAccessArgumentsAt>(elements, length, checked_key); 7284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(result, expr->id()); 7287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 7288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildNamedAccess( 7292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessType access, 7293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id, 7294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId return_id, 7295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* expr, 7296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object, 7297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> name, 7298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value, 7299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_uninitialized) { 7300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList* types; 7301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ComputeReceiverTypes(expr, object, &types, zone()); 7302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(types != NULL); 7303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (types->length() > 0) { 7305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessInfo info(this, access, ToType(types->first()), name); 7306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info.CanAccessAsMonomorphic(types)) { 7307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandlePolymorphicNamedFieldAccess( 7308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch access, expr, ast_id, return_id, object, value, types, name); 7309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 7310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_object; 7313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Type::Number() is only supported by polymorphic load/call handling. 7314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!info.type()->Is(Type::Number())); 7315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(object); 7316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (AreStringTypes(types)) { 7317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object = 7318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); 7319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object = Add<HCheckMaps>(object, types); 7321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildMonomorphicAccess( 7323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &info, object, checked_object, value, ast_id, return_id); 7324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildNamedGeneric(access, expr, object, name, value, is_uninitialized); 7327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::PushLoad(Property* expr, 7331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object, 7332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key) { 7333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); 7334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(object); 7335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (key != NULL) Push(key); 7336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildLoad(expr, expr->LoadId()); 7337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildLoad(Property* expr, 7341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id) { 7342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = NULL; 7343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->IsStringAccess()) { 7344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = Pop(); 7345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* string = Pop(); 7346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* char_code = BuildStringCharCodeAt(string, index); 7347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(char_code); 7348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = NewUncasted<HStringCharFromCode>(char_code); 7349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (expr->key()->IsPropertyName()) { 7351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 7352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object = Pop(); 7353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = BuildNamedAccess(LOAD, ast_id, expr->LoadId(), expr, 7355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, name, NULL, expr->IsUninitialized()); 7356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr == NULL) return; 7357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->IsLinked()) return ast_context()->ReturnValue(instr); 7358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 73598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else { 7360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = Pop(); 7361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* obj = Pop(); 7362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_side_effects = false; 7364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* load = HandleKeyedElementAccess( 7365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj, key, NULL, expr, ast_id, expr->LoadId(), LOAD, &has_side_effects); 7366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (has_side_effects) { 7367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ast_context()->IsEffect()) { 7368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 7369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(load); 7371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 7372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 7373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (load == NULL) return; 7376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(load); 7377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, ast_id); 7379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitProperty(Property* expr) { 7383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 7384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 7385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 7386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryArgumentsAccess(expr)) return; 7388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->obj())); 7390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!expr->key()->IsPropertyName() || expr->IsStringAccess()) { 7391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->key())); 7392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildLoad(expr, expr->id()); 7395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant) { 7399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCheckMaps* check = Add<HCheckMaps>( 7400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(constant), handle(constant->map())); 7401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch check->ClearDependsOnFlag(kElementsKind); 7402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return check; 7403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype, 7407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> holder) { 7408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrototypeIterator iter(isolate(), prototype, 7409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrototypeIterator::START_AT_RECEIVER); 7410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (holder.is_null() || 7411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !PrototypeIterator::GetCurrent(iter).is_identical_to(holder)) { 7412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildConstantMapCheck( 7413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))); 7414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iter.Advance(); 7415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (iter.IsAtEnd()) { 7416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 7417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildConstantMapCheck( 7420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))); 7421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, 7425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> receiver_map) { 7426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!holder.is_null()) { 7427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); 7428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckPrototypeMaps(prototype, holder); 7429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::NewPlainFunctionCall( 7434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* fun, int argument_count, bool pass_argument_count) { 7435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HCallJSFunction>( 7436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fun, argument_count, pass_argument_count); 7437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::NewArgumentAdaptorCall( 7441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* fun, HValue* context, 7442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count, HValue* expected_param_count) { 7443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArgumentAdaptorDescriptor descriptor(isolate()); 7444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* arity = Add<HConstant>(argument_count - 1); 7445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* op_vals[] = { context, fun, arity, expected_param_count }; 7447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> adaptor = 7449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->builtins()->ArgumentsAdaptorTrampoline(); 7450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* adaptor_value = Add<HConstant>(adaptor); 7451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HCallWithDescriptor>( 7453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch adaptor_value, argument_count, descriptor, 7454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Vector<HValue*>(op_vals, descriptor.GetEnvironmentLength())); 7455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildCallConstantFunction( 7459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> jsfun, int argument_count) { 7460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* target = Add<HConstant>(jsfun); 7461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For constant functions, we try to avoid calling the 7462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // argument adaptor and instead call the function directly 7463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int formal_parameter_count = jsfun->shared()->formal_parameter_count(); 7464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool dont_adapt_arguments = 7465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (formal_parameter_count == 7466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedFunctionInfo::kDontAdaptArgumentsSentinel); 7467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int arity = argument_count - 1; 7468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool can_invoke_directly = 7469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dont_adapt_arguments || formal_parameter_count == arity; 7470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (can_invoke_directly) { 7471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (jsfun.is_identical_to(current_info()->closure())) { 7472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->MarkRecursive(); 7473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NewPlainFunctionCall(target, argument_count, dont_adapt_arguments); 7475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* param_count_value = Add<HConstant>(formal_parameter_count); 7477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = Add<HLoadNamedField>( 7478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target, static_cast<HValue*>(NULL), 7479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForFunctionContextPointer()); 7480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NewArgumentAdaptorCall(target, context, 7481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch argument_count, param_count_value); 7482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 7484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 7485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass FunctionSorter { 7489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 7490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit FunctionSorter(int index = 0, int ticks = 0, int size = 0) 7491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : index_(index), ticks_(ticks), size_(size) {} 7492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index() const { return index_; } 7494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int ticks() const { return ticks_; } 7495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size() const { return size_; } 7496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 7498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index_; 7499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int ticks_; 7500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size_; 7501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 7502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline bool operator<(const FunctionSorter& lhs, const FunctionSorter& rhs) { 7505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int diff = lhs.ticks() - rhs.ticks(); 7506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (diff != 0) return diff > 0; 7507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return lhs.size() < rhs.size(); 7508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::HandlePolymorphicCallNamed( 7512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Call* expr, 7513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver, 7514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList* types, 7515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> name) { 7516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = expr->arguments()->length() + 1; // Includes receiver. 7517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FunctionSorter order[kMaxCallPolymorphism]; 7518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool handle_smi = false; 7520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool handled_string = false; 7521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int ordered_functions = 0; 7522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int i; 7524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (i = 0; i < types->length() && ordered_functions < kMaxCallPolymorphism; 7525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++i) { 7526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name); 7527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info.CanAccessMonomorphic() && info.IsConstant() && 7528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info.constant()->IsJSFunction()) { 7529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info.type()->Is(Type::String())) { 7530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (handled_string) continue; 7531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handled_string = true; 7532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant()); 7534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info.type()->Is(Type::Number())) { 7535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle_smi = true; 7536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->set_target(target); 7538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch order[ordered_functions++] = FunctionSorter( 7539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i, target->shared()->profiler_ticks(), InliningAstSize(target)); 7540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch std::sort(order, order + ordered_functions); 7544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i < types->length()) { 7546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch types->Clear(); 7547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ordered_functions = -1; 7548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* number_block = NULL; 7551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = NULL; 7552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handled_string = false; 7553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int count = 0; 7554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int fn = 0; fn < ordered_functions; ++fn) { 7556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int i = order[fn].index(); 7557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name); 7558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info.type()->Is(Type::String())) { 7559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (handled_string) continue; 7560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handled_string = true; 7561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Reloads the target. 7563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info.CanAccessMonomorphic(); 7564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant()); 7565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->set_target(target); 7567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (count == 0) { 7568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Only needed once. 7569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch join = graph()->CreateBasicBlock(); 7570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (handle_smi) { 7571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); 7572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); 7573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_block = graph()->CreateBasicBlock(); 7574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(New<HIsSmiAndBranch>( 7575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver, empty_smi_block, not_smi_block)); 7576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GotoNoSimulate(empty_smi_block, number_block); 7577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(not_smi_block); 7578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(receiver); 7580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++count; 7583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_true = graph()->CreateBasicBlock(); 7584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_false = graph()->CreateBasicBlock(); 7585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HUnaryControlInstruction* compare; 7586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = info.map(); 7588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info.type()->Is(Type::Number())) { 7589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); 7590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare = New<HCompareMap>(receiver, heap_number_map, if_true, if_false); 7591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (info.type()->Is(Type::String())) { 7592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare = New<HIsStringAndBranch>(receiver, if_true, if_false); 7593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare = New<HCompareMap>(receiver, map, if_true, if_false); 7595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(compare); 7597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info.type()->Is(Type::Number())) { 7599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GotoNoSimulate(if_true, number_block); 7600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_true = number_block; 7601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(if_true); 7604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddCheckPrototypeMaps(info.holder(), map); 7606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = Add<HConstant>(expr->target()); 7608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(0, function); 7609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(receiver); 7610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 7611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool needs_wrapping = NeedsWrappingFor(info.type(), target); 7612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool try_inline = FLAG_polymorphic_inlining && !needs_wrapping; 7613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_inlining && try_inline) { 7614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> caller = current_info()->closure(); 7615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmartArrayPointer<char> caller_name = 7616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch caller->shared()->DebugName()->ToCString(); 7617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Trying to inline the polymorphic call to %s from %s\n", 7618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch name->ToCString().get(), 7619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch caller_name.get()); 7620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (try_inline && TryInlineCall(expr)) { 7622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Trying to inline will signal that we should bailout from the 7623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // entire compilation by setting stack overflow on the visitor. 7624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasStackOverflow()) return; 7625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Since HWrapReceiver currently cannot actually wrap numbers and strings, 7627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // use the regular CallFunctionStub for method calls to wrap the receiver. 7628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(verwaest): Support creation of value wrappers directly in 7629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // HWrapReceiver. 7630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* call = needs_wrapping 7631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? NewUncasted<HCallFunction>( 7632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function, argument_count, WRAP_AND_CALL) 7633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : BuildCallConstantFunction(target, argument_count); 7634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argument_count); 7635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(call); 7636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Drop the function. 7637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(call); 7638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_block() != NULL) Goto(join); 7641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(if_false); 7642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Finish up. Unconditionally deoptimize if we've handled all the maps we 7645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // know about and do not want to handle ones we've never seen. Otherwise 7646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // use a generic IC. 7647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { 7648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishExitWithHardDeoptimization("Unknown map in polymorphic call"); 7649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Property* prop = expr->expression()->AsProperty(); 7651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* function = BuildNamedGeneric( 7652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOAD, prop, receiver, name, NULL, prop->IsUninitialized()); 7653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(function); 7654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(function); 7655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 7656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(1, function); 7658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(0, receiver); 7659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 7660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallFunctionFlags flags = receiver->type().IsJSObject() 7662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; 7663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* call = New<HCallFunction>( 7664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function, argument_count, flags); 7665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argument_count); 7667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Function. 7669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (join != NULL) { 7671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(call); 7672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(call); 7673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(join); 7674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(call, expr->id()); 7676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We assume that control flow is always live after an expression. So 7680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // even without predecessors to the join block, we set it as the exit 7681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // block and continue by adding instructions there. 7682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(join != NULL); 7683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (join->HasPredecessor()) { 7684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(join); 7685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch join->SetJoinId(expr->id()); 7686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); 7687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 7689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::TraceInline(Handle<JSFunction> target, 7694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> caller, 7695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* reason) { 7696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_inlining) { 7697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmartArrayPointer<char> target_name = 7698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target->shared()->DebugName()->ToCString(); 7699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmartArrayPointer<char> caller_name = 7700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch caller->shared()->DebugName()->ToCString(); 7701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reason == NULL) { 7702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Inlined %s called from %s.\n", target_name.get(), 7703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch caller_name.get()); 7704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Did not inline %s called from %s (%s).\n", 7706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target_name.get(), caller_name.get(), reason); 7707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kNotInlinable = 1000000000; 7713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint HOptimizedGraphBuilder::InliningAstSize(Handle<JSFunction> target) { 7716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_use_inlining) return kNotInlinable; 7717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Precondition: call is monomorphic and we have found a target with the 7719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // appropriate arity. 7720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> caller = current_info()->closure(); 7721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<SharedFunctionInfo> target_shared(target->shared()); 7722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Always inline builtins marked for inlining. 7724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (target->IsBuiltin()) { 7725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return target_shared->inline_builtin() ? 0 : kNotInlinable; 7726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (target_shared->IsApiFunction()) { 7729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target is api function"); 7730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kNotInlinable; 7731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Do a quick check on source code length to avoid parsing large 7734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inlining candidates. 7735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (target_shared->SourceSize() > 7736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Min(FLAG_max_inlined_source_size, kUnlimitedMaxInlinedSourceSize)) { 7737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target text too big"); 7738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kNotInlinable; 7739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Target must be inlineable. 7742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!target_shared->IsInlineable()) { 7743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target not inlineable"); 7744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kNotInlinable; 7745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (target_shared->DisableOptimizationReason() != kNoReason) { 7747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target contains unsupported syntax [early]"); 7748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kNotInlinable; 7749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int nodes_added = target_shared->ast_node_count(); 7752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return nodes_added; 7753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target, 7757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int arguments_count, 7758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* implicit_return_value, 7759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id, 7760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId return_id, 7761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InliningKind inlining_kind, 7762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HSourcePosition position) { 7763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int nodes_added = InliningAstSize(target); 7764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (nodes_added == kNotInlinable) return false; 7765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> caller = current_info()->closure(); 7767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { 7769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target AST is too large [early]"); 7770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 7771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Don't inline deeper than the maximum number of inlining levels. 7774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = environment(); 7775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int current_level = 1; 7776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (env->outer() != NULL) { 7777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_level == FLAG_max_inlining_levels) { 7778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "inline depth limit reached"); 7779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 7780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (env->outer()->frame_type() == JS_FUNCTION) { 7782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_level++; 7783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env = env->outer(); 7785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Don't inline recursive functions. 7788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (FunctionState* state = function_state(); 7789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch state != NULL; 7790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch state = state->outer()) { 7791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (*state->compilation_info()->closure() == *target) { 7792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target is recursive"); 7793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 7794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We don't want to add more than a certain number of nodes from inlining. 7798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (inlined_count_ > Min(FLAG_max_inlined_nodes_cumulative, 7799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kUnlimitedMaxInlinedNodesCumulative)) { 7800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "cumulative AST node limit reached"); 7801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 7802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Parse and allocate variables. 7805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompilationInfo target_info(target, zone()); 7806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Use the same AstValueFactory for creating strings in the sub-compilation 7807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // step, but don't transfer ownership to target_info. 7808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target_info.SetAstValueFactory(top_info()->ast_value_factory(), false); 7809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<SharedFunctionInfo> target_shared(target->shared()); 7810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!Parser::Parse(&target_info) || !Scope::Analyze(&target_info)) { 7811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (target_info.isolate()->has_pending_exception()) { 7812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Parse or scope error, never optimize this function. 7813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetStackOverflow(); 7814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target_shared->DisableOptimization(kParseScopeError); 7815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "parse failure"); 7817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 7818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (target_info.scope()->num_heap_slots() > 0) { 7821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target has context-allocated variables"); 7822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 7823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FunctionLiteral* function = target_info.function(); 7825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The following conditions must be checked again after re-parsing, because 7827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // earlier the information might not have been complete due to lazy parsing. 7828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch nodes_added = function->ast_node_count(); 7829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { 7830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target AST is too large [late]"); 7831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 7832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function->dont_optimize()) { 7834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target contains unsupported syntax [late]"); 7835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 7836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the function uses the arguments object check that inlining of functions 7839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // with arguments object is enabled and the arguments-variable is 7840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // stack allocated. 7841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function->scope()->arguments() != NULL) { 7842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_inline_arguments) { 7843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target uses arguments object"); 7844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 7845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!function->scope()->arguments()->IsStackAllocated()) { 7848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, 7849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch caller, 7850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "target uses non-stackallocated arguments object"); 7851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 7852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // All declarations must be inlineable. 7856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Declaration*>* decls = target_info.scope()->declarations(); 7857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int decl_count = decls->length(); 7858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < decl_count; ++i) { 7859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!decls->at(i)->IsInlineable()) { 7860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target has non-trivial declaration"); 7861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 7862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 78638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 7864b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generate the deoptimization data for the unoptimized version of 7866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the target function if we don't already have it. 7867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!Compiler::EnsureDeoptimizationSupport(&target_info)) { 7868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "could not generate deoptimization info"); 7869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 7870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7871b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ---------------------------------------------------------------- 7873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // After this point, we've made a decision to inline this function (so 7874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TryInline should always return true). 7875b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Type-check the inlined function. 7877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(target_shared->has_deoptimization_support()); 7878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AstTyper::Run(&target_info); 7879b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int function_id = graph()->TraceInlinedFunction(target_shared, position); 78813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Save the pending call context. Set up new one for the inlined function. 7883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The function state is new-allocated because we need to delete it 7884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in two different places. 7885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FunctionState* target_state = new FunctionState( 7886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch this, &target_info, inlining_kind, function_id); 7887b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* undefined = graph()->GetConstantUndefined(); 7889589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 7890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* inner_env = 7891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->CopyForInlining(target, 7892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_count, 7893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function, 7894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch undefined, 7895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state()->inlining_kind()); 7896589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 7897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* context = Add<HConstant>(Handle<Context>(target->context())); 7898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inner_env->BindContext(context); 7899589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 7900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create a dematerialized arguments object for the function, also copy the 7901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // current arguments values to use them for materialization. 7902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* arguments_env = inner_env->arguments_environment(); 7903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int parameter_count = arguments_env->parameter_count(); 7904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HArgumentsObject* arguments_object = Add<HArgumentsObject>(parameter_count); 7905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < parameter_count; i++) { 7906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_object->AddArgument(arguments_env->Lookup(i), zone()); 7907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 79083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the function uses arguments object then bind bind one. 7910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function->scope()->arguments() != NULL) { 7911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(function->scope()->arguments()->IsStackAllocated()); 7912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inner_env->Bind(function->scope()->arguments(), arguments_object); 7913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 79143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Capture the state before invoking the inlined function for deopt in the 7916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inlined function. This simulate has no bailout-id since it's not directly 7917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // reachable for deopt, and is only used to capture the state. If the simulate 7918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // becomes reachable by merging, the ast id of the simulate merged into it is 7919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // adopted. 7920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(BailoutId::None()); 79213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_block()->UpdateEnvironment(inner_env); 7923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* saved_scope = scope(); 7924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_scope(target_info.scope()); 7925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnterInlined* enter_inlined = 7926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HEnterInlined>(return_id, target, context, arguments_count, function, 7927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state()->inlining_kind(), 7928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function->scope()->arguments(), arguments_object); 7929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state()->set_entry(enter_inlined); 7930b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitDeclarations(target_info.scope()->declarations()); 7932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitStatements(function->body()); 7933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_scope(saved_scope); 7934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasStackOverflow()) { 7935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bail out if the inline function did, as we cannot residualize a call 7936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instead, but do not disable optimization for the outer function. 7937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "inline graph construction failed"); 7938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target_shared->DisableOptimization(kInliningBailedOut); 7939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_info()->RetryOptimization(kInliningBailedOut); 7940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete target_state; 7941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 7942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update inlined nodes count. 7945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inlined_count_ += nodes_added; 7946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> unoptimized_code(target_shared->code()); 7948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(unoptimized_code->kind() == Code::FUNCTION); 7949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<TypeFeedbackInfo> type_info( 7950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); 7951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->update_type_change_checksum(type_info->own_type_change_checksum()); 7952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, NULL); 7954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_block() != NULL) { 7956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FunctionState* state = function_state(); 7957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { 7958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Falling off the end of an inlined construct call. In a test context the 7959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // return value will always evaluate to true, in a value context the 7960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // return value is the newly allocated receiver. 7961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (call_context()->IsTest()) { 7962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(inlined_test_context()->if_true(), state); 7963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (call_context()->IsEffect()) { 7964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(function_return(), state); 7965b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 7966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call_context()->IsValue()); 7967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddLeaveInlined(implicit_return_value, state); 7968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (state->inlining_kind() == SETTER_CALL_RETURN) { 7970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Falling off the end of an inlined setter call. The returned value is 7971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // never used, the value of an assignment is always the value of the RHS 7972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of the assignment. 7973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (call_context()->IsTest()) { 7974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inlined_test_context()->ReturnValue(implicit_return_value); 7975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (call_context()->IsEffect()) { 7976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(function_return(), state); 7977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call_context()->IsValue()); 7979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddLeaveInlined(implicit_return_value, state); 7980b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 7981b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 7982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Falling off the end of a normal inlined function. This basically means 7983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // returning undefined. 7984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (call_context()->IsTest()) { 7985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(inlined_test_context()->if_false(), state); 7986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (call_context()->IsEffect()) { 7987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(function_return(), state); 7988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call_context()->IsValue()); 7990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddLeaveInlined(undefined, state); 7991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fix up the function exits. 7996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (inlined_test_context() != NULL) { 7997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_true = inlined_test_context()->if_true(); 7998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_false = inlined_test_context()->if_false(); 7999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnterInlined* entry = function_state()->entry(); 8001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pop the return test context from the expression context stack. 8003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(ast_context() == inlined_test_context()); 8004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearInlinedTestContext(); 8005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete target_state; 8006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Forward to the real test context. 8008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (if_true->HasPredecessor()) { 8009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry->RegisterReturnTarget(if_true, zone()); 8010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_true->SetJoinId(ast_id); 8011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* true_target = TestContext::cast(ast_context())->if_true(); 8012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(if_true, true_target, function_state()); 8013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (if_false->HasPredecessor()) { 8015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry->RegisterReturnTarget(if_false, zone()); 8016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_false->SetJoinId(ast_id); 8017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* false_target = TestContext::cast(ast_context())->if_false(); 8018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(if_false, false_target, function_state()); 8019b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 8020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 8021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8022b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (function_return()->HasPredecessor()) { 8024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state()->entry()->RegisterReturnTarget(function_return(), zone()); 8025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_return()->SetJoinId(ast_id); 8026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(function_return()); 8027b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 8028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 8029b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 8030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete target_state; 8031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8032b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 8033b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineCall(Call* expr) { 8036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return TryInline(expr->target(), 8037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->arguments()->length(), 8038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL, 8039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->id(), 8040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->ReturnId(), 8041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NORMAL_RETURN, 8042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScriptPositionToSourcePosition(expr->position())); 8043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 8044b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8045b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, 8047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* implicit_return_value) { 8048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return TryInline(expr->target(), 8049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->arguments()->length(), 8050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch implicit_return_value, 8051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->id(), 8052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->ReturnId(), 8053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CONSTRUCT_CALL_RETURN, 8054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScriptPositionToSourcePosition(expr->position())); 8055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 80563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 80573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, 8059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> receiver_map, 8060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id, 8061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId return_id) { 8062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true; 8063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return TryInline(getter, 8064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0, 8065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL, 8066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_id, 8067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return_id, 8068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GETTER_CALL_RETURN, 8069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch source_position()); 8070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 80713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8072b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, 8074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> receiver_map, 8075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId id, 8076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId assignment_id, 8077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* implicit_return_value) { 8078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineApiSetter(setter, receiver_map, id)) return true; 8079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return TryInline(setter, 8080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1, 8081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch implicit_return_value, 8082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch id, assignment_id, 8083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SETTER_CALL_RETURN, 8084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch source_position()); 8085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 8086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function, 8089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Call* expr, 8090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int arguments_count) { 8091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return TryInline(function, 8092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_count, 8093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL, 8094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->id(), 8095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->ReturnId(), 8096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NORMAL_RETURN, 8097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScriptPositionToSourcePosition(expr->position())); 8098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 8099589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 8100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr) { 8102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; 8103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); 8104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (id) { 8105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathExp: 8106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_fast_math) break; 8107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fall through if FLAG_fast_math. 8108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathRound: 8109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathFround: 8110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathFloor: 8111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathAbs: 8112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathSqrt: 8113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathLog: 8114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathClz32: 8115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->arguments()->length() == 1) { 8116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* argument = Pop(); 8117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(2); // Receiver and function. 8118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id); 8119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(op, expr->id()); 8120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathImul: 8124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->arguments()->length() == 2) { 8125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right = Pop(); 8126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left = Pop(); 8127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(2); // Receiver and function. 8128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* op = HMul::NewImul(zone(), context(), left, right); 8129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(op, expr->id()); 8130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8131589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 8132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 8134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Not supported for inlining yet. 8135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 8138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 81393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 81401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 8141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( 8142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Call* expr, 8143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver, 8144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> receiver_map) { 8145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Try to inline calls like Math.* as operations in the calling function. 8146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; 8147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); 8148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = expr->arguments()->length() + 1; // Plus receiver. 8149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (id) { 8150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kStringCharCodeAt: 8151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kStringCharAt: 8152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument_count == 2) { 8153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = Pop(); 8154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* string = Pop(); 8155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Function. 8156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* char_code = 8157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildStringCharCodeAt(string, index); 8158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (id == kStringCharCodeAt) { 8159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(char_code, expr->id()); 8160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(char_code); 8163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NewUncasted<HStringCharFromCode>(char_code); 8164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(result, expr->id()); 8165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kStringFromCharCode: 8169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument_count == 2) { 8170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* argument = Pop(); 8171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(2); // Receiver and function. 8172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NewUncasted<HStringCharFromCode>(argument); 8173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(result, expr->id()); 8174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathExp: 8178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_fast_math) break; 8179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fall through if FLAG_fast_math. 8180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathRound: 8181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathFround: 8182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathFloor: 8183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathAbs: 8184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathSqrt: 8185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathLog: 8186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathClz32: 8187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument_count == 2) { 8188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* argument = Pop(); 8189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(2); // Receiver and function. 8190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id); 8191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(op, expr->id()); 8192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathPow: 8196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument_count == 3) { 8197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right = Pop(); 8198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left = Pop(); 8199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(2); // Receiver and function. 8200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NULL; 8201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Use sqrt() if exponent is 0.5 or -0.5. 8202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { 8203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double exponent = HConstant::cast(right)->DoubleValue(); 8204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (exponent == 0.5) { 8205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = NewUncasted<HUnaryMathOperation>(left, kMathPowHalf); 8206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (exponent == -0.5) { 8207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* one = graph()->GetConstant1(); 8208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* sqrt = AddUncasted<HUnaryMathOperation>( 8209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left, kMathPowHalf); 8210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // MathPowHalf doesn't have side effects so there's no need for 8211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // an environment simulation here. 8212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!sqrt->HasObservableSideEffects()); 8213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = NewUncasted<HDiv>(one, sqrt); 8214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (exponent == 2.0) { 8215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = NewUncasted<HMul>(left, left); 82163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 82173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 82183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (result == NULL) { 8220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = NewUncasted<HPower>(left, right); 82213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(result, expr->id()); 8223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8224589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 8225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathMax: 8227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathMin: 8228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument_count == 3) { 8229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right = Pop(); 8230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left = Pop(); 8231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(2); // Receiver and function. 8232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin 8233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : HMathMinMax::kMathMax; 8234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NewUncasted<HMathMinMax>(left, right, op); 8235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(result, expr->id()); 8236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathImul: 8240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument_count == 3) { 8241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right = Pop(); 8242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left = Pop(); 8243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(2); // Receiver and function. 8244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = HMul::NewImul(zone(), context(), left, right); 8245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(result, expr->id()); 8246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArrayPop: { 8250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map.is_null()) return false; 8251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; 8252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind = receiver_map->elements_kind(); 8253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsFastElementsKind(elements_kind)) return false; 8254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map->is_observed()) return false; 8255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!receiver_map->is_extensible()) return false; 8256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(expr->arguments()->length()); 8258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result; 8259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* reduced_length; 8260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver = Pop(); 82611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 8262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_object = AddCheckMap(receiver, receiver_map); 8263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length = Add<HLoadNamedField>( 8264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object, static_cast<HValue*>(NULL), 8265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForArrayLength(elements_kind)); 8266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Function. 8268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { NoObservableSideEffectsScope scope(this); 8270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder length_checker(this); 8271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* bounds_check = length_checker.If<HCompareNumericAndBranch>( 8273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length, graph()->GetConstant0(), Token::EQ); 8274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.Then(); 8275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(graph()->GetConstantUndefined()); 8277b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.Else(); 8279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements = AddLoadElements(checked_object); 8280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Ensure that we aren't popping from a copy-on-write array. 8281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFastSmiOrObjectElementsKind(elements_kind)) { 8282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements = BuildCopyElementsOnWrite(checked_object, elements, 8283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind, length); 8284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reduced_length = AddUncasted<HSub>(length, graph()->GetConstant1()); 8286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = AddElementAccess(elements, reduced_length, NULL, 8287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bounds_check, elements_kind, LOAD); 8288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate()->factory(); 8289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double nan_double = FixedDoubleArray::hole_nan_as_double(); 8290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) 8291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? Add<HConstant>(factory->the_hole_value()) 8292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Add<HConstant>(nan_double); 8293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFastSmiOrObjectElementsKind(elements_kind)) { 8294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind = FAST_HOLEY_ELEMENTS; 8295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddElementAccess( 8297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, reduced_length, hole, bounds_check, elements_kind, STORE); 8298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 8299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object, HObjectAccess::ForArrayLength(elements_kind), 8300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reduced_length, STORE_TO_INITIALIZED_ENTRY); 8301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(result); 8303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.End(); 8305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); 8307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 8308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Drop(1); 8309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnValue(result); 8311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArrayPush: { 8314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map.is_null()) return false; 8315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; 8316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind = receiver_map->elements_kind(); 8317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsFastElementsKind(elements_kind)) return false; 8318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map->is_observed()) return false; 8319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (JSArray::IsReadOnlyLengthDescriptor(receiver_map)) return false; 8320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!receiver_map->is_extensible()) return false; 8321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there may be elements accessors in the prototype chain, the fast 8323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inlined version can't be used. 8324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; 8325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there currently can be no elements accessors on the prototype chain, 8326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // it doesn't mean that there won't be any later. Install a full prototype 8327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chain check to trap element accessors being installed on the prototype 8328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chain, which would cause elements to go to dictionary mode and result 8329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in a map change. 8330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); 8331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckPrototypeMaps(prototype, Handle<JSObject>()); 8332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int argc = expr->arguments()->length(); 8334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argc != 1) return false; 8335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value_to_push = Pop(); 8337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* array = Pop(); 8338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Drop function. 8339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* new_size = NULL; 8341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length = NULL; 8342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope scope(this); 8345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length = Add<HLoadNamedField>(array, static_cast<HValue*>(NULL), 8347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForArrayLength(elements_kind)); 8348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_size = AddUncasted<HAdd>(length, graph()->GetConstant1()); 8350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 8352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildUncheckedMonomorphicElementAccess(array, length, 8353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_to_push, is_array, 8354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind, STORE, 8355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NEVER_RETURN_HOLE, 8356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STORE_AND_GROW_NO_TRANSITION); 8357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(new_size); 8359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 8360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Drop(1); 8361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnValue(new_size); 8364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArrayShift: { 8367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map.is_null()) return false; 8368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; 8369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind = receiver_map->elements_kind(); 8370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsFastElementsKind(kind)) return false; 8371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map->is_observed()) return false; 8372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!receiver_map->is_extensible()) return false; 8373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there may be elements accessors in the prototype chain, the fast 8375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inlined version can't be used. 8376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; 8377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there currently can be no elements accessors on the prototype chain, 8379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // it doesn't mean that there won't be any later. Install a full prototype 8380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chain check to trap element accessors being installed on the prototype 8381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chain, which would cause elements to go to dictionary mode and result 8382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in a map change. 8383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckPrototypeMaps( 8384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle(JSObject::cast(receiver_map->prototype()), isolate()), 8385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject>::null()); 8386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Threshold for fast inlined Array.shift(). 8388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* inline_threshold = Add<HConstant>(static_cast<int32_t>(16)); 8389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(expr->arguments()->length()); 8391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver = Pop(); 8392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = Pop(); 8393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result; 8394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope scope(this); 8397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length = Add<HLoadNamedField>( 8399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver, static_cast<HValue*>(NULL), 8400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForArrayLength(kind)); 8401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_lengthiszero(this); 8403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* lengthiszero = if_lengthiszero.If<HCompareNumericAndBranch>( 8404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length, graph()->GetConstant0(), Token::EQ); 8405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_lengthiszero.Then(); 8406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(graph()->GetConstantUndefined()); 8408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_lengthiszero.Else(); 8410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements = AddLoadElements(receiver); 8412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if we can use the fast inlined Array.shift(). 8414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_inline(this); 8415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_inline.If<HCompareNumericAndBranch>( 8416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length, inline_threshold, Token::LTE); 8417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFastSmiOrObjectElementsKind(kind)) { 8418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We cannot handle copy-on-write backing stores here. 8419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_inline.AndIf<HCompareMap>( 8420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, isolate()->factory()->fixed_array_map()); 8421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_inline.Then(); 8423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remember the result. 8425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) { 8426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(AddElementAccess(elements, graph()->GetConstant0(), NULL, 8427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lengthiszero, kind, LOAD)); 8428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8429b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the new length. 8431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_length = AddUncasted<HSub>( 8432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length, graph()->GetConstant1()); 8433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_length->ClearFlag(HValue::kCanOverflow); 8434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy the remaining elements. 8436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); 8437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_key = loop.BeginBody( 8439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0(), new_length, Token::LT); 8440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = AddUncasted<HAdd>(new_key, graph()->GetConstant1()); 8441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key->ClearFlag(HValue::kCanOverflow); 8442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* element = AddUncasted<HLoadKeyed>( 8443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, key, lengthiszero, kind, ALLOW_RETURN_HOLE); 8444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreKeyed* store = Add<HStoreKeyed>( 8445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, new_key, element, kind); 8446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store->SetFlag(HValue::kAllowUndefinedAsNaN); 8447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.EndBody(); 8449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Put a hole at the end. 8451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* hole = IsFastSmiOrObjectElementsKind(kind) 8452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? Add<HConstant>(isolate()->factory()->the_hole_value()) 8453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Add<HConstant>(FixedDoubleArray::hole_nan_as_double()); 8454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFastSmiOrObjectElementsKind(kind)) kind = FAST_HOLEY_ELEMENTS; 8455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreKeyed>( 8456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, new_length, hole, kind, INITIALIZING_STORE); 8457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remember new length. 8459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 8460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver, HObjectAccess::ForArrayLength(kind), 8461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_length, STORE_TO_INITIALIZED_ENTRY); 8462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_inline.Else(); 8464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(receiver); 8466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = Add<HCallJSFunction>(function, 1, true); 8467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(result); 8468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_inline.End(); 84703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_lengthiszero.End(); 84723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 8473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); 8474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 8475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Drop(1); 8476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnValue(result); 8477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArrayIndexOf: 8480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArrayLastIndexOf: { 8481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map.is_null()) return false; 8482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; 8483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind = receiver_map->elements_kind(); 8484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsFastElementsKind(kind)) return false; 8485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map->is_observed()) return false; 8486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument_count != 2) return false; 8487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!receiver_map->is_extensible()) return false; 8488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there may be elements accessors in the prototype chain, the fast 8490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inlined version can't be used. 8491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; 8492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there currently can be no elements accessors on the prototype chain, 8494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // it doesn't mean that there won't be any later. Install a full prototype 8495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chain check to trap element accessors being installed on the prototype 8496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chain, which would cause elements to go to dictionary mode and result 8497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in a map change. 8498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckPrototypeMaps( 8499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle(JSObject::cast(receiver_map->prototype()), isolate()), 8500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject>::null()); 8501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* search_element = Pop(); 8503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver = Pop(); 8504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Drop function. 85053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArrayIndexOfMode mode = (id == kArrayIndexOf) 8507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? kFirstIndexOf : kLastIndexOf; 8508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = BuildArrayIndexOf(receiver, search_element, kind, mode); 85093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(index); 8511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 8512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Drop(1); 8513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnValue(index); 8514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 85153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 8517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Not yet supported for inlining. 8518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 85193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 85213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 85223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 85233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineApiFunctionCall(Call* expr, 8525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver) { 8526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> function = expr->target(); 8527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argc = expr->arguments()->length(); 8528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList receiver_maps; 8529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return TryInlineApiCall(function, 8530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver, 8531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &receiver_maps, 8532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch argc, 8533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->id(), 8534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kCallApiFunction); 8535b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 8536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineApiMethodCall( 8539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Call* expr, 8540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver, 8541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList* receiver_maps) { 8542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> function = expr->target(); 8543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argc = expr->arguments()->length(); 8544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return TryInlineApiCall(function, 8545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver, 8546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver_maps, 8547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch argc, 8548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->id(), 8549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kCallApiMethod); 8550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 85513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 85523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineApiGetter(Handle<JSFunction> function, 8554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> receiver_map, 8555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id) { 8556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList receiver_maps(1, zone()); 8557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver_maps.Add(receiver_map, zone()); 8558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return TryInlineApiCall(function, 8559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL, // Receiver is on expression stack. 8560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &receiver_maps, 8561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0, 8562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_id, 8563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kCallApiGetter); 8564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 85653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 85663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineApiSetter(Handle<JSFunction> function, 8568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> receiver_map, 8569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id) { 8570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList receiver_maps(1, zone()); 8571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver_maps.Add(receiver_map, zone()); 8572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return TryInlineApiCall(function, 8573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL, // Receiver is on expression stack. 8574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &receiver_maps, 8575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1, 8576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_id, 8577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kCallApiSetter); 8578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 85793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 85803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineApiCall(Handle<JSFunction> function, 8582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver, 8583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList* receiver_maps, 8584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argc, 8585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id, 8586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ApiCallType call_type) { 8587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallOptimization optimization(function); 8588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!optimization.is_simple_api_call()) return false; 8589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> holder_map; 8590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (call_type == kCallApiFunction) { 8591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Cannot embed a direct reference to the global proxy map 8592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // as it maybe dropped on deserialization. 8593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!isolate()->serializer_enabled()); 8594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(0, receiver_maps->length()); 8595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver_maps->Add(handle(function->global_proxy()->map()), zone()); 8596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallOptimization::HolderLookup holder_lookup = 8598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallOptimization::kHolderNotFound; 8599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType( 8600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver_maps->first(), &holder_lookup); 8601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (holder_lookup == CallOptimization::kHolderNotFound) return false; 86023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_inlining) { 8604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Inlining api function "); 8605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function->ShortPrint(); 8606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("\n"); 8607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool drop_extra = false; 8610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_store = false; 8611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (call_type) { 8612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kCallApiFunction: 8613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kCallApiMethod: 8614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Need to check that none of the receiver maps could have changed. 8615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckMaps>(receiver, receiver_maps); 8616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Need to ensure the chain between receiver and api_holder is intact. 8617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (holder_lookup == CallOptimization::kHolderFound) { 8618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddCheckPrototypeMaps(api_holder, receiver_maps->first()); 8619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 8620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(holder_lookup, CallOptimization::kHolderIsReceiver); 86213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 8622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Includes receiver. 8623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argc + 1); 8624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Drop function after call. 8625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch drop_extra = true; 8626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kCallApiGetter: 8628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Receiver and prototype chain cannot have changed. 8629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(0, argc); 8630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(NULL, receiver); 8631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Receiver is on expression stack. 8632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver = Pop(); 8633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(receiver); 8634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kCallApiSetter: 8636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_store = true; 8638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Receiver and prototype chain cannot have changed. 8639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(1, argc); 8640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(NULL, receiver); 8641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Receiver and value are on expression stack. 8642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 8643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver = Pop(); 8644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(receiver, value); 8645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 86473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 86483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* holder = NULL; 8650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (holder_lookup) { 8651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CallOptimization::kHolderFound: 8652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch holder = Add<HConstant>(api_holder); 8653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CallOptimization::kHolderIsReceiver: 8655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch holder = receiver; 8656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CallOptimization::kHolderNotFound: 8658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 8659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 86608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 8661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 8662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> call_data_obj(api_call_info->data(), isolate()); 8663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool call_data_is_undefined = call_data_obj->IsUndefined(); 8664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* call_data = Add<HConstant>(call_data_obj); 8665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ApiFunction fun(v8::ToCData<Address>(api_call_info->callback())); 8666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference ref = ExternalReference(&fun, 8667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::DIRECT_API_CALL, 8668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()); 8669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* api_function_address = Add<HConstant>(ExternalReference(ref)); 8670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* op_vals[] = { 8672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context(), 8673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(function), 8674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call_data, 8675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch holder, 8676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch api_function_address 8677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 8678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ApiFunctionDescriptor descriptor(isolate()); 8680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallApiFunctionStub stub(isolate(), is_store, call_data_is_undefined, argc); 8681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = stub.GetCode(); 8682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* code_value = Add<HConstant>(code); 8683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((sizeof(op_vals) / kPointerSize) == descriptor.GetEnvironmentLength()); 8685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* call = New<HCallWithDescriptor>( 8687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_value, argc + 1, descriptor, 8688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Vector<HValue*>(op_vals, descriptor.GetEnvironmentLength())); 8689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (drop_extra) Drop(1); // Drop function. 8691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(call, ast_id); 8692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 86938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch} 86948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 86958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 8696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryCallApply(Call* expr) { 8697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->expression()->IsProperty()); 8698b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!expr->IsMonomorphic()) { 8700b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return false; 8701b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 8702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> function_map = expr->GetReceiverTypes()->first(); 8703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function_map->instance_type() != JS_FUNCTION_TYPE || 8704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !expr->target()->shared()->HasBuiltinFunctionId() || 8705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->target()->shared()->builtin_function_id() != kFunctionApply) { 8706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 8707b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 8708b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_info()->scope()->arguments() == NULL) return false; 8710b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Expression*>* args = expr->arguments(); 8712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (args->length() != 2) return false; 87131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 8714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VariableProxy* arg_two = args->at(1)->AsVariableProxy(); 8715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; 8716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); 8717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; 8718b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Found pattern f.apply(receiver, arguments). 8720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE_OR_RETURN(VisitForValue(args->at(0)), true); 8721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver = Pop(); // receiver 8722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = Pop(); // f 8723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // apply 8724b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_function = AddCheckMap(function, function_map); 8726b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function_state()->outer() == NULL) { 8728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* elements = Add<HArgumentsElements>(false); 8729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* length = Add<HArgumentsLength>(elements); 8730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* wrapped_receiver = BuildWrapReceiver(receiver, checked_function); 8731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = New<HApplyArguments>(function, 8732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch wrapped_receiver, 8733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length, 8734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements); 8735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(result, expr->id()); 8736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8737b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 8738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We are inside inlined function and we know exactly what is inside 8739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // arguments object. But we need to be able to materialize at deopt. 8740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(environment()->arguments_environment()->parameter_count(), 8741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state()->entry()->arguments_object()->arguments_count()); 8742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HArgumentsObject* args = function_state()->entry()->arguments_object(); 8743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ZoneList<HValue*>* arguments_values = args->arguments_values(); 8744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int arguments_count = arguments_values->length(); 8745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(function); 8746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(BuildWrapReceiver(receiver, checked_function)); 8747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 1; i < arguments_count; i++) { 8748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(arguments_values->at(i)); 8749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> known_function; 8752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function->IsConstant() && 8753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(function)->handle(isolate())->IsJSFunction()) { 8754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch known_function = Handle<JSFunction>::cast( 8755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(function)->handle(isolate())); 8756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int args_count = arguments_count - 1; // Excluding receiver. 8757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineApply(known_function, expr, args_count)) return true; 8758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(arguments_count); 8761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInvokeFunction* call = New<HInvokeFunction>( 8762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function, known_function, arguments_count); 8763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Function. 8764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(call, expr->id()); 8765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 8768b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 87693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function, 8771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> target) { 8772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedFunctionInfo* shared = target->shared(); 8773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shared->strict_mode() == SLOPPY && !shared->native()) { 8774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Cannot embed a direct reference to the global proxy 8775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // as is it dropped on deserialization. 8776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!isolate()->serializer_enabled()); 8777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> global_proxy(target->context()->global_proxy()); 8778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HConstant>(global_proxy); 8779b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 8780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return graph()->GetConstantUndefined(); 8781b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 8782b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8783b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildArrayCall(Expression* expression, 8785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int arguments_count, 8786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function, 8787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> site) { 8788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckValue>(function, array_function()); 8789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsCallArrayInlineable(arguments_count, site)) { 8791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildInlinedCallArray(expression, arguments_count, site); 8792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 8793b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 8794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* call = PreProcessCall(New<HCallNewArray>( 8796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function, arguments_count + 1, site->GetElementsKind())); 8797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expression->IsCall()) { 8798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 8799b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 8800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(call, expression->id()); 8801b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 8802b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8803b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HOptimizedGraphBuilder::BuildArrayIndexOf(HValue* receiver, 8805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* search_element, 8806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 8807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArrayIndexOfMode mode) { 8808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsFastElementsKind(kind)); 880944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 8810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 8811b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements = AddLoadElements(receiver); 8813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length = AddLoadArrayLength(receiver, kind); 8814b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* initial; 8816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* terminating; 8817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::Value token; 8818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder::Direction direction; 8819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode == kFirstIndexOf) { 8820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch initial = graph()->GetConstant0(); 8821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch terminating = length; 8822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch token = Token::LT; 8823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch direction = LoopBuilder::kPostIncrement; 8824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 8825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(kLastIndexOf, mode); 8826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch initial = length; 8827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch terminating = graph()->GetConstant0(); 8828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch token = Token::GT; 8829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch direction = LoopBuilder::kPreDecrement; 8830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(graph()->GetConstantMinus1()); 8833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFastDoubleElementsKind(kind) || IsFastSmiElementsKind(kind)) { 8834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure that we can actually compare numbers correctly below, see 8835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // https://code.google.com/p/chromium/issues/detail?id=407946 for details. 8836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch search_element = AddUncasted<HForceRepresentation>( 8837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch search_element, IsFastSmiElementsKind(kind) ? Representation::Smi() 8838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Representation::Double()); 8839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder loop(this, context(), direction); 8841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = loop.BeginBody(initial, terminating, token); 8843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* element = AddUncasted<HLoadKeyed>( 8844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, index, static_cast<HValue*>(NULL), 8845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind, ALLOW_RETURN_HOLE); 8846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_issame(this); 8847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.If<HCompareNumericAndBranch>(element, search_element, 8848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::EQ_STRICT); 8849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.Then(); 8850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 8852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(index); 8853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.Break(); 8854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.End(); 88569fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block } 8857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.EndBody(); 8858257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 8859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_isstring(this); 8860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isstring.If<HIsStringAndBranch>(search_element); 8861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isstring.Then(); 8862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder loop(this, context(), direction); 8864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = loop.BeginBody(initial, terminating, token); 8866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* element = AddUncasted<HLoadKeyed>( 8867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, index, static_cast<HValue*>(NULL), 8868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind, ALLOW_RETURN_HOLE); 8869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_issame(this); 8870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.If<HIsStringAndBranch>(element); 8871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.AndIf<HStringCompareAndBranch>( 8872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch element, search_element, Token::EQ_STRICT); 8873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.Then(); 8874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 8876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(index); 8877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.Break(); 8878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.End(); 8880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.EndBody(); 8882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isstring.Else(); 8884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_isnumber(this); 8886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isnumber.If<HIsSmiAndBranch>(search_element); 8887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isnumber.OrIf<HCompareMap>( 8888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch search_element, isolate()->factory()->heap_number_map()); 8889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isnumber.Then(); 8890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* search_number = 8892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HForceRepresentation>(search_element, 8893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation::Double()); 8894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder loop(this, context(), direction); 8895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = loop.BeginBody(initial, terminating, token); 8897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* element = AddUncasted<HLoadKeyed>( 8898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, index, static_cast<HValue*>(NULL), 8899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind, ALLOW_RETURN_HOLE); 8900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_element_isnumber(this); 8902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_element_isnumber.If<HIsSmiAndBranch>(element); 8903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_element_isnumber.OrIf<HCompareMap>( 8904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch element, isolate()->factory()->heap_number_map()); 8905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_element_isnumber.Then(); 8906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* number = 8908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HForceRepresentation>(element, 8909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation::Double()); 8910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_issame(this); 8911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.If<HCompareNumericAndBranch>( 8912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number, search_number, Token::EQ_STRICT); 8913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.Then(); 8914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 8916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(index); 8917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.Break(); 8918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.End(); 8920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_element_isnumber.End(); 8922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.EndBody(); 8924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isnumber.Else(); 8926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder loop(this, context(), direction); 8928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = loop.BeginBody(initial, terminating, token); 8930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* element = AddUncasted<HLoadKeyed>( 8931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, index, static_cast<HValue*>(NULL), 8932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind, ALLOW_RETURN_HOLE); 8933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_issame(this); 8934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.If<HCompareObjectEqAndBranch>( 8935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch element, search_element); 8936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.Then(); 8937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 8939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(index); 8940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.Break(); 8941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.End(); 8943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.EndBody(); 8945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isnumber.End(); 8947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isstring.End(); 894944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 8950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Pop(); 8952b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 8953b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8954b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryHandleArrayCall(Call* expr, HValue* function) { 8956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!array_function().is_identical_to(expr->target())) { 8957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 8958b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 8959b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> site = expr->allocation_site(); 8961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (site.is_null()) return false; 8962b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildArrayCall(expr, 8964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->arguments()->length(), 8965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function, 8966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site); 8967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 8969b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8970b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryHandleArrayCallNew(CallNew* expr, 8972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function) { 8973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!array_function().is_identical_to(expr->target())) { 8974b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return false; 8975b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 8976b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildArrayCall(expr, 8978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->arguments()->length(), 8979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function, 8980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->allocation_site()); 8981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 8983b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 89843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitCall(Call* expr) { 8986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 8987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 8988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 8989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* callee = expr->expression(); 8990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = expr->arguments()->length() + 1; // Plus receiver. 8991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* call = NULL; 89923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Property* prop = callee->AsProperty(); 8994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (prop != NULL) { 8995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(prop->obj())); 8996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver = Top(); 8997b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList* types; 8999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ComputeReceiverTypes(expr, receiver, &types, zone()); 9000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (prop->key()->IsPropertyName() && types->length() > 0) { 9002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 9003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessInfo info(this, LOAD, ToType(types->first()), name); 9004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info.CanAccessAsMonomorphic(types)) { 9005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandlePolymorphicCallNamed(expr, receiver, types, name); 9006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 9007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 90083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9009b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = NULL; 9011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!prop->key()->IsPropertyName()) { 9012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(prop->key())); 9013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key = Pop(); 90143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9015b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(PushLoad(prop, receiver, key)); 9017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = Pop(); 9018b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 9020e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 9021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Push the function under the receiver. 9022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(0, function); 9023b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(receiver); 9025b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function->IsConstant() && 9027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(function)->handle(isolate())->IsJSFunction()) { 9028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> known_function = Handle<JSFunction>::cast( 9029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(function)->handle(isolate())); 9030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->set_target(known_function); 90313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryCallApply(expr)) return; 9033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 90343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>(); 9036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineBuiltinMethodCall(expr, receiver, map)) { 9037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_inlining) { 9038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Inlining builtin "); 9039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch known_function->ShortPrint(); 9040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("\n"); 9041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 9043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineApiMethodCall(expr, receiver, types)) return; 9045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Wrap the receiver if necessary. 9047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (NeedsWrappingFor(ToType(types->first()), known_function)) { 9048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Since HWrapReceiver currently cannot actually wrap numbers and 9049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // strings, use the regular CallFunctionStub for method calls to wrap 9050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the receiver. 9051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(verwaest): Support creation of value wrappers directly in 9052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // HWrapReceiver. 9053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call = New<HCallFunction>( 9054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function, argument_count, WRAP_AND_CALL); 9055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (TryInlineCall(expr)) { 9056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 9057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 9058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call = BuildCallConstantFunction(known_function, argument_count); 9059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9060b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 9062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 9063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallFunctionFlags flags = receiver->type().IsJSObject() 9064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; 9065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call = New<HCallFunction>(function, argument_count, flags); 9066e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 9067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argument_count); 9068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 9070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VariableProxy* proxy = expr->expression()->AsVariableProxy(); 9071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { 9072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kPossibleDirectCallToEval); 90733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 9074b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The function is on the stack in the unoptimized code during 9076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // evaluation of the arguments. 9077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->expression())); 9078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = Top(); 9079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->global_call()) { 9080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* var = proxy->var(); 9081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool known_global_function = false; 9082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there is a global property cell for the name at compile time and 9083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // access check is not enabled we assume that the function will not change 9084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and generate optimized code for calling the function. 9085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<GlobalObject> global(current_info()->global_object()); 9086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupIterator it(global, var->name(), 9087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupIterator::OWN_SKIP_INTERCEPTOR); 9088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GlobalPropertyAccess type = LookupGlobalProperty(var, &it, LOAD); 9089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type == kUseCell) { 9090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<GlobalObject> global(current_info()->global_object()); 9091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch known_global_function = expr->ComputeGlobalTarget(global, &it); 9092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (known_global_function) { 9094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckValue>(function, expr->target()); 90953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 9096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Placeholder for the receiver. 9097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(graph()->GetConstantUndefined()); 9098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 9099b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Patch the global object on the stack by the expected receiver. 9101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver = ImplicitReceiverFor(function, expr->target()); 9102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int receiver_index = argument_count - 1; 9103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(receiver_index, receiver); 9104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineBuiltinFunctionCall(expr)) { 9106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_inlining) { 9107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Inlining builtin "); 9108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->target()->ShortPrint(); 9109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("\n"); 9110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 9112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineApiFunctionCall(expr, receiver)) return; 9114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryHandleArrayCall(expr, function)) return; 9115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineCall(expr)) return; 9116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argument_count); 9118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call = BuildCallConstantFunction(expr->target(), argument_count); 9119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 9120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(graph()->GetConstantUndefined()); 9121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 9122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argument_count); 9123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call = New<HCallFunction>(function, argument_count); 9124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (expr->IsMonomorphic()) { 9127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckValue>(function, expr->target()); 9128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(graph()->GetConstantUndefined()); 9130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 9131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver = ImplicitReceiverFor(function, expr->target()); 9133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int receiver_index = argument_count - 1; 9134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(receiver_index, receiver); 9135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineBuiltinFunctionCall(expr)) { 9137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_inlining) { 9138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Inlining builtin "); 9139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->target()->ShortPrint(); 9140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("\n"); 9141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 9143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineApiFunctionCall(expr, receiver)) return; 9145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineCall(expr)) return; 9147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call = PreProcessCall(New<HInvokeFunction>( 9149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function, expr->target(), argument_count)); 9150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 9152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(graph()->GetConstantUndefined()); 9153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 9154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argument_count); 9155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call = New<HCallFunction>(function, argument_count); 9156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 91573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Drop the function. 9160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(call, expr->id()); 9161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 9162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildInlinedCallArray( 9165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* expression, 9166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count, 9167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> site) { 9168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!site.is_null()); 9169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(argument_count >= 0 && argument_count <= 1); 9170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 9171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We should at least have the constructor on the expression stack. 9173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* constructor = environment()->ExpressionStackAt(argument_count); 9174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Register on the site for deoptimization if the transition feedback changes. 9176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSite::AddDependentCompilationInfo( 9177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site, AllocationSite::TRANSITIONS, top_info()); 9178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind = site->GetElementsKind(); 9179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* site_instruction = Add<HConstant>(site); 9180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // In the single constant argument case, we may have to adjust elements kind 9182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to avoid creating a packed non-empty array. 9183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument_count == 1 && !IsHoleyElementsKind(kind)) { 9184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* argument = environment()->Top(); 9185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument->IsConstant()) { 9186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* constant_argument = HConstant::cast(argument); 9187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(constant_argument->HasSmiValue()); 9188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int constant_array_size = constant_argument->Integer32Value(); 9189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (constant_array_size != 0) { 9190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind = GetHoleyElementsKind(kind); 9191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 9194b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Build the array. 9196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSArrayBuilder array_builder(this, 9197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind, 9198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site_instruction, 9199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constructor, 9200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISABLE_ALLOCATION_SITES); 9201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_object = argument_count == 0 9202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? array_builder.AllocateEmptyArray() 9203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : BuildAllocateArrayFromLength(&array_builder, Top()); 9204b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int args_to_drop = argument_count + (expression->IsCall() ? 2 : 1); 9206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(args_to_drop); 9207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnValue(new_object); 9208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 9209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Checks whether allocation using the given constructor can be inlined. 9212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool IsAllocationInlineable(Handle<JSFunction> constructor) { 9213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return constructor->has_initial_map() && 9214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && 9215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constructor->initial_map()->instance_size() < HAllocate::kMaxInlineSize && 9216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constructor->initial_map()->InitialPropertiesLength() == 0; 9217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 9218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::IsCallArrayInlineable( 9221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count, 9222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> site) { 9223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> caller = current_info()->closure(); 9224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> target = array_function(); 9225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We should have the function plus array arguments on the environment stack. 9226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(environment()->length() >= (argument_count + 1)); 9227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!site.is_null()); 9228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool inline_ok = false; 9230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (site->CanInlineCall()) { 9231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We also want to avoid inlining in certain 1 argument scenarios. 9232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument_count == 1) { 9233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* argument = Top(); 9234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument->IsConstant()) { 9235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Do not inline if the constant length argument is not a smi or 9236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // outside the valid range for unrolled loop initialization. 9237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* constant_argument = HConstant::cast(argument); 9238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (constant_argument->HasSmiValue()) { 9239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int value = constant_argument->Integer32Value(); 9240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline_ok = value >= 0 && value <= kElementLoopUnrollThreshold; 9241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!inline_ok) { 9242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, 9243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "Constant length outside of valid inlining range."); 9244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 9247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, 9248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "Dont inline [new] Array(n) where n isn't constant."); 9249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (argument_count == 0) { 9251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline_ok = true; 9252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 9253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "Too many arguments to inline."); 9254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 9255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 9256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "AllocationSite requested no inlining."); 9257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 9258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (inline_ok) { 9260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, NULL); 9261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return inline_ok; 9263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 92643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 9265b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { 9267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 9268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 9269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 9270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 9271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = expr->arguments()->length() + 1; // Plus constructor. 9272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate()->factory(); 9273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The constructor function is on the stack in the unoptimized code 9275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // during evaluation of the arguments. 9276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->expression())); 9277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = Top(); 9278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 9279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_inline_construct && 9281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->IsMonomorphic() && 9282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsAllocationInlineable(expr->target())) { 9283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> constructor = expr->target(); 9284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* check = Add<HCheckValue>(function, constructor); 9285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Force completion of inobject slack tracking before generating 9287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // allocation code to finalize instance size. 9288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (constructor->IsInobjectSlackTrackingInProgress()) { 9289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constructor->CompleteInobjectSlackTracking(); 9290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calculate instance size from initial map of constructor. 9293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(constructor->has_initial_map()); 9294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> initial_map(constructor->initial_map()); 9295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int instance_size = initial_map->instance_size(); 9296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(initial_map->InitialPropertiesLength() == 0); 9297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate an instance of the implicit receiver object. 9299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* size_in_bytes = Add<HConstant>(instance_size); 9300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocationMode allocation_mode; 9301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_pretenuring_call_new) { 9302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_allocation_site_pretenuring) { 9303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Try to use pretenuring feedback. 9304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> allocation_site = expr->allocation_site(); 9305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_mode = HAllocationMode(allocation_site); 9306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Take a dependency on allocation site. 9307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSite::AddDependentCompilationInfo(allocation_site, 9308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSite::TENURING, 9309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch top_info()); 9310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9311257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 9312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocate* receiver = BuildAllocate( 9314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode); 9315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver->set_known_initial_map(initial_map); 9316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize map and fields of the newly allocated object. 9318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { NoObservableSideEffectsScope no_effects(this); 9319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(initial_map->instance_type() == JS_OBJECT_TYPE); 9320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(receiver, 9321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMapAndOffset(initial_map, JSObject::kMapOffset), 9322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(initial_map)); 9323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array()); 9324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(receiver, 9325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMapAndOffset(initial_map, 9326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::kPropertiesOffset), 9327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch empty_fixed_array); 9328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(receiver, 9329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMapAndOffset(initial_map, 9330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::kElementsOffset), 9331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch empty_fixed_array); 9332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (initial_map->inobject_properties() != 0) { 9333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* undefined = graph()->GetConstantUndefined(); 9334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < initial_map->inobject_properties(); i++) { 9335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int property_offset = initial_map->GetInObjectPropertyOffset(i); 9336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(receiver, 9337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMapAndOffset(initial_map, property_offset), 9338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch undefined); 9339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9341257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 9342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Replace the constructor function with a newly allocated receiver using 9344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the index of the receiver from the top of the expression stack. 9345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int receiver_index = argument_count - 1; 9346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(environment()->ExpressionStackAt(receiver_index) == function); 9347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(receiver_index, receiver); 9348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineConstruct(expr, receiver)) { 9350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Inlining worked, add a dependency on the initial map to make sure that 9351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this code is deoptimized whenever the initial map of the constructor 9352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // changes. 9353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map::AddDependentCompilationInfo( 9354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch initial_map, DependentCode::kInitialMapChangedGroup, top_info()); 9355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 9356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(mstarzinger): For now we remove the previous HAllocate and all 9359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // corresponding instructions and instead add HPushArguments for the 9360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // arguments in case inlining failed. What we actually should do is for 9361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inlining to try to build a subgraph without mutating the parent graph. 9362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = current_block()->last(); 9363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch do { 9364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* prev_instr = instr->previous(); 9365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->DeleteAndReplaceWith(NULL); 9366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = prev_instr; 9367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } while (instr != check); 9368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(receiver_index, function); 9369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* call = 9370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PreProcessCall(New<HCallNew>(function, argument_count)); 9371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(call, expr->id()); 9372257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 9373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The constructor function is both an operand to the instruction and an 9374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // argument to the construct call. 9375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryHandleArrayCallNew(expr, function)) return; 9376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* call = 9378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PreProcessCall(New<HCallNew>(function, argument_count)); 9379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(call, expr->id()); 9380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 93815d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch} 93825d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 93835d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 9384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Support for generating inlined runtime functions. 93853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Lookup table for generators for runtime calls that are generated inline. 9387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Elements of the table are member pointers to functions of 9388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// HOptimizedGraphBuilder. 9389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \ 9390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &HOptimizedGraphBuilder::Generate##Name, 93913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst HOptimizedGraphBuilder::InlineFunctionGenerator 9393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HOptimizedGraphBuilder::kInlineFunctionGenerators[] = { 9394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 9395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INLINE_OPTIMIZED_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 9396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 9397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef INLINE_FUNCTION_GENERATOR_ADDRESS 93983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 93993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <class ViewClass> 9401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildArrayBufferViewInitialization( 9402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* obj, 9403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* buffer, 9404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* byte_offset, 9405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* byte_length) { 9406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int offset = ViewClass::kSize; 9408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset < ViewClass::kSizeWithInternalFields; 9409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset += kPointerSize) { 9410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(obj, 9411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForObservableJSObjectOffset(offset), 9412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0()); 9413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 9416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj, 9417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSArrayBufferViewByteOffset(), 9418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_offset); 9419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 9420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj, 9421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSArrayBufferViewByteLength(), 9422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_length); 9423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (buffer != NULL) { 9425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 9426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj, 9427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSArrayBufferViewBuffer(), buffer); 9428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess weak_first_view_access = 9429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSArrayBufferWeakFirstView(); 9430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(obj, 9431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSArrayBufferViewWeakNext(), 9432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadNamedField>(buffer, 9433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<HValue*>(NULL), 9434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch weak_first_view_access)); 9435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(buffer, weak_first_view_access, obj); 9436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 9437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 9438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj, 9439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSArrayBufferViewBuffer(), 9440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>(0))); 9441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(obj, 9442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSArrayBufferViewWeakNext(), 9443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstantUndefined()); 94443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 94453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 94463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 94473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateDataViewInitialize( 9449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* expr) { 9450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Expression*>* arguments = expr->arguments(); 9451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(arguments->length()== 4); 9453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(arguments->at(0))); 9454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* obj = Pop(); 94553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(arguments->at(1))); 9457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* buffer = Pop(); 94583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(arguments->at(2))); 9460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* byte_offset = Pop(); 9461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(arguments->at(3))); 9463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* byte_length = Pop(); 9464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 9466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope scope(this); 9467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildArrayBufferViewInitialization<JSDataView>( 9468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj, buffer, byte_offset, byte_length); 9469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 9470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 9471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic Handle<Map> TypedArrayMap(Isolate* isolate, 9474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalArrayType array_type, 9475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind target_kind) { 9476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Context> native_context = isolate->native_context(); 9477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> fun; 9478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (array_type) { 9479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 9480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kExternal##Type##Array: \ 9481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fun = Handle<JSFunction>(native_context->type##_array_fun()); \ 9482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 9483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TYPED_ARRAYS(TYPED_ARRAY_CASE) 9485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef TYPED_ARRAY_CASE 948642effa50d92d47f80404ee63808dbde9921e6202Ben Murdoch } 9487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map(fun->initial_map()); 9488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Map::AsElementsKind(map, target_kind); 9489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 9490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9491b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HOptimizedGraphBuilder::BuildAllocateExternalElements( 9493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalArrayType array_type, 9494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_zero_byte_offset, 9495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* buffer, HValue* byte_offset, HValue* length) { 9496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> external_array_map( 9497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->heap()->MapForExternalArrayType(array_type)); 9498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The HForceRepresentation is to prevent possible deopt on int-smi 9500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // conversion after allocation but before the new object fields are set. 9501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length = AddUncasted<HForceRepresentation>(length, Representation::Smi()); 9502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements = 9503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HAllocate>( 9504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(ExternalArray::kAlignedSize), 9505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HType::HeapObject(), 9506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NOT_TENURED, 9507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch external_array_map->instance_type()); 9508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddStoreMapConstant(elements, external_array_map); 9510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(elements, 9511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForFixedArrayLength(), length); 9512257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* backing_store = Add<HLoadNamedField>( 9514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer, static_cast<HValue*>(NULL), 9515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSArrayBufferBackingStore()); 95163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* typed_array_start; 9518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_zero_byte_offset) { 9519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typed_array_start = backing_store; 95203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 9521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* external_pointer = 9522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HAdd>(backing_store, byte_offset); 9523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Arguments are checked prior to call to TypedArrayInitialize, 9524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // including byte_offset. 9525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch external_pointer->ClearFlag(HValue::kCanOverflow); 9526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typed_array_start = external_pointer; 9527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 95283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(elements, 9530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForExternalArrayExternalPointer(), 9531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typed_array_start); 95323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return elements; 9534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 95353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 95363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HOptimizedGraphBuilder::BuildAllocateFixedTypedArray( 9538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalArrayType array_type, size_t element_size, 9539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind fixed_elements_kind, 9540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* byte_length, HValue* length) { 9541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT( 9542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (FixedTypedArrayBase::kHeaderSize & kObjectAlignmentMask) == 0); 9543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* total_size; 9544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // if fixed array's elements are not aligned to object's alignment, 9546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // we need to align the whole array to object alignment. 9547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (element_size % kObjectAlignment != 0) { 9548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total_size = BuildObjectSizeAlignment( 9549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_length, FixedTypedArrayBase::kHeaderSize); 9550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 9551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total_size = AddUncasted<HAdd>(byte_length, 9552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(FixedTypedArrayBase::kHeaderSize)); 9553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total_size->ClearFlag(HValue::kCanOverflow); 95543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The HForceRepresentation is to prevent possible deopt on int-smi 9557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // conversion after allocation but before the new object fields are set. 9558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length = AddUncasted<HForceRepresentation>(length, Representation::Smi()); 9559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> fixed_typed_array_map( 9560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->heap()->MapForFixedTypedArray(array_type)); 9561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements = 9562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HAllocate>(total_size, HType::HeapObject(), 9563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NOT_TENURED, fixed_typed_array_map->instance_type()); 9564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddStoreMapConstant(elements, fixed_typed_array_map); 9565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(elements, 9567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForFixedArrayLength(), 9568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length); 9569b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* filler = Add<HConstant>(static_cast<int32_t>(0)); 9571b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 9573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement); 9574b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = builder.BeginBody( 9576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>(0)), 9577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length, Token::LT); 9578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreKeyed>(elements, key, filler, fixed_elements_kind); 9579b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder.EndBody(); 9581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return elements; 9583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 9584b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9585b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateTypedArrayInitialize( 9587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* expr) { 9588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Expression*>* arguments = expr->arguments(); 9589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kObjectArg = 0; 9591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kArrayIdArg = 1; 9592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kBufferArg = 2; 9593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kByteOffsetArg = 3; 9594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kByteLengthArg = 4; 9595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kArgsLength = 5; 9596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(arguments->length() == kArgsLength); 9597b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9598b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(arguments->at(kObjectArg))); 9600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* obj = Pop(); 9601b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (arguments->at(kArrayIdArg)->IsLiteral()) { 9603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This should never happen in real use, but can happen when fuzzing. 9604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Just bail out. 9605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bailout(kNeedSmiLiteral); 9606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 9607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> value = 9609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<Literal*>(arguments->at(kArrayIdArg))->value(); 9610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!value->IsSmi()) { 9611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This should never happen in real use, but can happen when fuzzing. 9612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Just bail out. 9613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bailout(kNeedSmiLiteral); 9614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 9615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int array_id = Smi::cast(*value)->value(); 9617b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* buffer; 9619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!arguments->at(kBufferArg)->IsNullLiteral()) { 9620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(arguments->at(kBufferArg))); 9621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer = Pop(); 9622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 9623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer = NULL; 9624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 96251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 9626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* byte_offset; 9627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_zero_byte_offset; 9628b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (arguments->at(kByteOffsetArg)->IsLiteral() 9630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch && Smi::FromInt(0) == 9631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *static_cast<Literal*>(arguments->at(kByteOffsetArg))->value()) { 9632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_offset = Add<HConstant>(static_cast<int32_t>(0)); 9633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_zero_byte_offset = true; 9634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 9635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(arguments->at(kByteOffsetArg))); 9636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_offset = Pop(); 9637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_zero_byte_offset = false; 9638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(buffer != NULL); 9639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9640b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(arguments->at(kByteLengthArg))); 9642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* byte_length = Pop(); 9643b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope scope(this); 9645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder byte_offset_smi(this); 96463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!is_zero_byte_offset) { 9648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_offset_smi.If<HIsSmiAndBranch>(byte_offset); 9649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_offset_smi.Then(); 9650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9651b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalArrayType array_type = 9653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kExternalInt8Array; // Bogus initialization. 9654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t element_size = 1; // Bogus initialization. 9655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind external_elements_kind = // Bogus initialization. 9656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EXTERNAL_INT8_ELEMENTS; 9657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind fixed_elements_kind = // Bogus initialization. 9658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INT8_ELEMENTS; 9659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::ArrayIdToTypeAndSize(array_id, 9660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &array_type, 9661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &external_elements_kind, 9662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &fixed_elements_kind, 9663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &element_size); 9664b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9665b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { // byte_offset is Smi. 9667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildArrayBufferViewInitialization<JSTypedArray>( 9668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj, buffer, byte_offset, byte_length); 9669b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 96703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* length = AddUncasted<HDiv>(byte_length, 9672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>(element_size))); 96733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(obj, 9675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSTypedArrayLength(), 9676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length); 96773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements; 9679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (buffer != NULL) { 9680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements = BuildAllocateExternalElements( 9681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array_type, is_zero_byte_offset, buffer, byte_offset, length); 9682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> obj_map = TypedArrayMap( 9683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate(), array_type, external_elements_kind); 9684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddStoreMapConstant(obj, obj_map); 9685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 9686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_zero_byte_offset); 9687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements = BuildAllocateFixedTypedArray( 9688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array_type, element_size, fixed_elements_kind, 9689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_length, length); 9690b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 9691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 9692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj, HObjectAccess::ForElementsPointer(), elements); 9693b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 9694b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!is_zero_byte_offset) { 9696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_offset_smi.Else(); 9697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { // byte_offset is not Smi. 9698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(obj); 9699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(arguments->at(kArrayIdArg))); 9700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(buffer); 9701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(byte_offset); 9702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(byte_length); 9703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(kArgsLength); 9704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength); 9705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_offset_smi.End(); 9708b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 9709b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9710b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateMaxSmi(CallRuntime* expr) { 9712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->arguments()->length() == 0); 9713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue)); 9714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(max_smi, expr->id()); 97153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 97163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 97173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateTypedArrayMaxSizeInHeap( 9719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* expr) { 9720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->arguments()->length() == 0); 9721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* result = New<HConstant>(static_cast<int32_t>( 9722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FLAG_typed_array_max_size_in_heap)); 9723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(result, expr->id()); 9724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 97253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 97263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateArrayBufferGetByteLength( 9728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* expr) { 9729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->arguments()->length() == 1); 9730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 9731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* buffer = Pop(); 9732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = New<HLoadNamedField>( 9733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer, 9734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<HValue*>(NULL), 9735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSArrayBufferByteLength()); 9736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(result, expr->id()); 9737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 97383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 97393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteLength( 9741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* expr) { 9742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->arguments()->length() == 1); 9743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 9744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* buffer = Pop(); 9745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = New<HLoadNamedField>( 9746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer, 9747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<HValue*>(NULL), 9748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSArrayBufferViewByteLength()); 9749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(result, expr->id()); 9750b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 9751b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9752b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteOffset( 9754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* expr) { 9755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->arguments()->length() == 1); 9756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 9757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* buffer = Pop(); 9758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = New<HLoadNamedField>( 9759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer, 9760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<HValue*>(NULL), 9761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSArrayBufferViewByteOffset()); 9762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(result, expr->id()); 9763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 9764b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9765b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateTypedArrayGetLength( 9767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* expr) { 9768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->arguments()->length() == 1); 9769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 9770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* buffer = Pop(); 9771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = New<HLoadNamedField>( 9772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer, 9773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<HValue*>(NULL), 9774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSTypedArrayLength()); 9775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(result, expr->id()); 9776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 9777b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9778b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { 9780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 9781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 9782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 9783b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (expr->is_jsruntime()) { 9784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kCallToAJavaScriptRuntimeFunction); 9785b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 9786b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 978744f0eee88ff00398ff7f715fab053374d808c90dSteve Block const Runtime::Function* function = expr->function(); 9788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(function != NULL); 9789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function->intrinsic_type == Runtime::INLINE || 9791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function->intrinsic_type == Runtime::INLINE_OPTIMIZED) { 9792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->name()->length() > 0); 9793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->name()->Get(0) == '_'); 9794b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Call to an inline function. 9795b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int lookup_index = static_cast<int>(function->function_id) - 9796b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static_cast<int>(Runtime::kFirstInlineFunction); 9797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(lookup_index >= 0); 9798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(static_cast<size_t>(lookup_index) < 9799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arraysize(kInlineFunctionGenerators)); 9800b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; 9801b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9802b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Call the inline code generator using the pointer-to-member. 9803e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (this->*generator)(expr); 9804b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 9805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(function->intrinsic_type == Runtime::RUNTIME); 9806e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<String> name = expr->name(); 9807e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int argument_count = expr->arguments()->length(); 9808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 9809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argument_count); 9810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCallRuntime* call = New<HCallRuntime>(name, function, 9811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch argument_count); 98123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(call, expr->id()); 9813b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 9814b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 9815b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9816b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { 9818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 9819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 9820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 9821257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch switch (expr->op()) { 9822257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case Token::DELETE: return VisitDelete(expr); 9823257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case Token::VOID: return VisitVoid(expr); 9824257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case Token::TYPEOF: return VisitTypeof(expr); 9825257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case Token::NOT: return VisitNot(expr); 9826257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch default: UNREACHABLE(); 9827257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 9828257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 9829257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { 9832257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Property* prop = expr->expression()->AsProperty(); 9833589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch VariableProxy* proxy = expr->expression()->AsVariableProxy(); 9834589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (prop != NULL) { 983569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_ALIVE(VisitForValue(prop->obj())); 983669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_ALIVE(VisitForValue(prop->key())); 983769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch HValue* key = Pop(); 983869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch HValue* obj = Pop(); 9839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = AddLoadJSBuiltin(Builtins::DELETE); 9840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(obj, key, Add<HConstant>(function_strict_mode())); 9841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(olivf) InvokeFunction produces a check for the parameter count, 9842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // even though we are certain to pass the correct number of arguments here. 9843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = New<HInvokeFunction>(function, 3); 984469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 9845589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } else if (proxy != NULL) { 9846589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Variable* var = proxy->var(); 9847589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (var->IsUnallocated()) { 9848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bailout(kDeleteWithGlobalVariable); 9849589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } else if (var->IsStackAllocated() || var->IsContextSlot()) { 9850589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Result of deleting non-global variables is false. 'this' is not 9851589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // really a variable, though we implement it as one. The 9852589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // subexpression does not have side effects. 9853589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch HValue* value = var->is_this() 9854589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ? graph()->GetConstantTrue() 9855589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch : graph()->GetConstantFalse(); 9856589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return ast_context()->ReturnValue(value); 9857589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } else { 9858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bailout(kDeleteWithNonGlobalVariable); 9859589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 9860257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 9861589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Result of deleting non-property, non-variable reference is true. 9862589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Evaluate the subexpression for side effects. 9863589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch CHECK_ALIVE(VisitForEffect(expr->expression())); 9864589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return ast_context()->ReturnValue(graph()->GetConstantTrue()); 9865257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 9866257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 9867e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 986844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitVoid(UnaryOperation* expr) { 9870257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForEffect(expr->expression())); 98713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 9872257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 9873257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9874257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) { 9876257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForTypeOf(expr->expression())); 9877257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HValue* value = Pop(); 9878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = New<HTypeof>(value); 98793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 9880257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 9881257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9882257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { 9884257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (ast_context()->IsTest()) { 9885257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch TestContext* context = TestContext::cast(ast_context()); 9886257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch VisitForControl(expr->expression(), 9887257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch context->if_false(), 9888257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch context->if_true()); 9889257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return; 9890257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 9891257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9892257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (ast_context()->IsEffect()) { 9893257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch VisitForEffect(expr->expression()); 9894257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return; 9895257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 9896257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(ast_context()->IsValue()); 9898257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* materialize_false = graph()->CreateBasicBlock(); 9899257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* materialize_true = graph()->CreateBasicBlock(); 9900257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_BAILOUT(VisitForControl(expr->expression(), 9901257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch materialize_false, 9902257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch materialize_true)); 9903257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9904257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (materialize_false->HasPredecessor()) { 99053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch materialize_false->SetJoinId(expr->MaterializeFalseId()); 9906257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch set_current_block(materialize_false); 9907257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Push(graph()->GetConstantFalse()); 990844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { 9909257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch materialize_false = NULL; 9910257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 9911257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9912257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (materialize_true->HasPredecessor()) { 99133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch materialize_true->SetJoinId(expr->MaterializeTrueId()); 9914257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch set_current_block(materialize_true); 9915257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Push(graph()->GetConstantTrue()); 9916257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 9917257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch materialize_true = NULL; 9918b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 9919257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9920257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* join = 9921257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CreateJoin(materialize_false, materialize_true, expr->id()); 9922257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch set_current_block(join); 99233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (join != NULL) return ast_context()->ReturnValue(Pop()); 9924b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 9925b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9926b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildIncrement( 9928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool returns_original_input, 9929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CountOperation* expr) { 9930257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // The input to the count operation is on top of the expression stack. 9931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation rep = Representation::FromType(expr->type()); 9932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (rep.IsNone() || rep.IsTagged()) { 9933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rep = Representation::Smi(); 9934257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 9935257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9936257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (returns_original_input) { 9937257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // We need an explicit HValue representing ToNumber(input). The 9938257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // actual HChange instruction we need is (sometimes) added in a later 9939257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // phase, so it is not available now to be used as an input to HAdd and 9940257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // as the return value. 9941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* number_input = AddUncasted<HForceRepresentation>(Pop(), rep); 9942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!rep.IsDouble()) { 9943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_input->SetFlag(HInstruction::kFlexibleRepresentation); 9944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_input->SetFlag(HInstruction::kCannotBeTagged); 9945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9946257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Push(number_input); 9947257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 9948257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9949257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // The addition has no side effects, so we do not need 9950257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // to simulate the expression stack after this instruction. 9951257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Any later failures deopt to the load of the input or earlier. 9952257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HConstant* delta = (expr->op() == Token::INC) 9953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? graph()->GetConstant1() 9954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : graph()->GetConstantMinus1(); 9955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = AddUncasted<HAdd>(Top(), delta); 9956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->IsAdd()) { 9957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAdd* add = HAdd::cast(instr); 9958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch add->set_observed_input_representation(1, rep); 9959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch add->set_observed_input_representation(2, Representation::Smi()); 9960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetFlag(HInstruction::kCannotBeTagged); 9962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->ClearAllSideEffects(); 9963b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return instr; 9964b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 9965b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9966b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildStoreForEffect(Expression* expr, 9968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Property* prop, 9969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id, 9970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId return_id, 9971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object, 9972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key, 9973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value) { 9974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EffectContext for_effect(this); 9975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(object); 9976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (key != NULL) Push(key); 9977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(value); 9978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildStore(expr, prop, ast_id, return_id); 9979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 9980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { 9983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 9984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 9985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 9986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 99878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Expression* target = expr->expression(); 9988b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch VariableProxy* proxy = target->AsVariableProxy(); 9989b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Property* prop = target->AsProperty(); 9990589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (proxy == NULL && prop == NULL) { 9991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kInvalidLhsInCountOperation); 9992257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 9993257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9994257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Match the full code generator stack by simulating an extra stack 9995257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // element for postfix operations in a non-effect context. The return 9996257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // value is ToNumber(input). 9997257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool returns_original_input = 9998257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch expr->is_postfix() && !ast_context()->IsEffect(); 9999257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HValue* input = NULL; // ToNumber(original_input). 10000257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HValue* after = NULL; // The result after incrementing or decrementing. 10001b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10002589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (proxy != NULL) { 10003589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Variable* var = proxy->var(); 10004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (var->mode() == CONST_LEGACY) { 10005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kUnsupportedCountOperationWithConst); 100063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 10007257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Argument of the count operation is a variable, not a property. 10008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(prop == NULL); 10009257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(target)); 10010257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10011257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch after = BuildIncrement(returns_original_input, expr); 10012257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch input = returns_original_input ? Top() : Pop(); 10013b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Push(after); 10014b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10015589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch switch (var->location()) { 10016589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch case Variable::UNALLOCATED: 10017589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch HandleGlobalVariableAssignment(var, 10018589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch after, 10019589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch expr->AssignmentId()); 10020589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch break; 10021589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 10022589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch case Variable::PARAMETER: 10023589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch case Variable::LOCAL: 10024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BindIfLive(var, after); 10025589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch break; 10026589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 10027589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch case Variable::CONTEXT: { 10028589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Bail out if we try to mutate a parameter value in a function 10029589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // using the arguments object. We do not (yet) correctly handle the 10030589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // arguments property of the function. 10031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_info()->scope()->arguments() != NULL) { 10032589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Parameters will rewrite to context slots. We have no direct 10033589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // way to detect that the variable is a parameter so we use a 10034589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // linear search of the parameter list. 10035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int count = current_info()->scope()->num_parameters(); 10036589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch for (int i = 0; i < count; ++i) { 10037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (var == current_info()->scope()->parameter(i)) { 10038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kAssignmentToParameterInArgumentsObject); 10039589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 100403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 100413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 10042589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 10043589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch HValue* context = BuildContextChainWalk(var); 10044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) 100453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; 10046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), 10047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode, after); 100483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->HasObservableSideEffects()) { 10049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 100503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10051589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch break; 100523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 100533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 10054589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch case Variable::LOOKUP: 10055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kLookupVariableInCountOperation); 10056b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10057b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(returns_original_input ? 2 : 1); 10059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(expr->is_postfix() ? input : after); 10060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Argument of the count operation is a property. 10063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(prop != NULL); 10064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (returns_original_input) Push(graph()->GetConstantUndefined()); 10065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(prop->obj())); 10067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object = Top(); 10068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = NULL; 10070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!prop->key()->IsPropertyName() || prop->IsStringAccess()) { 10071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(prop->key())); 10072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key = Top(); 10073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(PushLoad(prop, object, key)); 10076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch after = BuildIncrement(returns_original_input, expr); 10078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (returns_original_input) { 10080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch input = Pop(); 10081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Drop object and key to push it again in the effect context below. 10082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(key == NULL ? 1 : 2); 10083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(0, input); 10084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(BuildStoreForEffect( 10085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr, prop, expr->id(), expr->AssignmentId(), object, key, after)); 10086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 10087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(0, after); 10090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildStore(expr, prop, expr->id(), expr->AssignmentId()); 10091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( 10095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* string, 10096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index) { 10097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (string->IsConstant() && index->IsConstant()) { 10098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* c_string = HConstant::cast(string); 10099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* c_index = HConstant::cast(index); 10100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (c_string->HasStringValue() && c_index->HasNumberValue()) { 10101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t i = c_index->NumberValueAsInteger32(); 10102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> s = c_string->StringValue(); 10103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i < 0 || i >= s->length()) { 10104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HConstant>(base::OS::nan_value()); 10105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HConstant>(s->Get(i)); 10107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch string = BuildCheckString(string); 10110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch index = Add<HBoundsCheck>(index, AddLoadStringLength(string)); 10111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HStringCharCodeAt>(string, index); 10112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Checks if the given shift amounts have following forms: 10116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (N1) and (N2) with N1 + N2 = 32; (sa) and (32 - sa). 10117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool ShiftAmountsAllowReplaceByRotate(HValue* sa, 10118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* const32_minus_sa) { 10119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (sa->IsConstant() && const32_minus_sa->IsConstant()) { 10120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const HConstant* c1 = HConstant::cast(sa); 10121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const HConstant* c2 = HConstant::cast(const32_minus_sa); 10122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return c1->HasInteger32Value() && c2->HasInteger32Value() && 10123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (c1->Integer32Value() + c2->Integer32Value() == 32); 10124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!const32_minus_sa->IsSub()) return false; 10126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HSub* sub = HSub::cast(const32_minus_sa); 10127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return sub->left()->EqualsInteger32Constant(32) && sub->right() == sa; 10128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Checks if the left and the right are shift instructions with the oposite 10132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// directions that can be replaced by one rotate right instruction or not. 10133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Returns the operand and the shift amount for the rotate instruction in the 10134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// former case. 10135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HGraphBuilder::MatchRotateRight(HValue* left, 10136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right, 10137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue** operand, 10138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue** shift_amount) { 10139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HShl* shl; 10140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HShr* shr; 10141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (left->IsShl() && right->IsShr()) { 10142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shl = HShl::cast(left); 10143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shr = HShr::cast(right); 10144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (left->IsShr() && right->IsShl()) { 10145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shl = HShl::cast(right); 10146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shr = HShr::cast(left); 10147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 10149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shl->left() != shr->left()) return false; 10151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ShiftAmountsAllowReplaceByRotate(shl->right(), shr->right()) && 10153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !ShiftAmountsAllowReplaceByRotate(shr->right(), shl->right())) { 10154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 10155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *operand= shr->left(); 10157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *shift_amount = shr->right(); 10158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 10159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10161b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool CanBeZero(HValue* right) { 10163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (right->IsConstant()) { 10164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* right_const = HConstant::cast(right); 10165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (right_const->HasInteger32Value() && 10166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (right_const->Integer32Value() & 0x1f) != 0) { 10167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 10168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 10171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::EnforceNumberType(HValue* number, 10175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* expected) { 10176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expected->Is(Type::SignedSmall())) { 10177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddUncasted<HForceRepresentation>(number, Representation::Smi()); 10178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expected->Is(Type::Signed32())) { 10180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddUncasted<HForceRepresentation>(number, 10181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation::Integer32()); 10182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return number; 10184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::TruncateToNumber(HValue* value, Type** expected) { 10188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value->IsConstant()) { 10189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* constant = HConstant::cast(value); 10190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone()); 10191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (number.has_value) { 10192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *expected = Type::Number(zone()); 10193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddInstruction(number.value); 10194b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10196257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We put temporary values on the stack, which don't correspond to anything 10198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in baseline code. Since nothing is observable we avoid recording those 10199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pushes with a NoObservableSideEffectsScope. 10200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 10201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* expected_type = *expected; 10203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Separate the number type from the rest. 10205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* expected_obj = 10206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type::Intersect(expected_type, Type::NonNumber(zone()), zone()); 10207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* expected_number = 10208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type::Intersect(expected_type, Type::Number(zone()), zone()); 10209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We expect to get a number. 10211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (We need to check first, since Type::None->Is(Type::Any()) == true. 10212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expected_obj->Is(Type::None())) { 10213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!expected_number->Is(Type::None(zone()))); 10214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return value; 10215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expected_obj->Is(Type::Undefined(zone()))) { 10218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This is already done by HChange. 10219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *expected = Type::Union(expected_number, Type::Number(zone()), zone()); 10220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return value; 10221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return value; 10224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 10225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HOptimizedGraphBuilder::BuildBinaryOperation( 10228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BinaryOperation* expr, 10229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left, 10230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right, 10231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushBeforeSimulateBehavior push_sim_result) { 10232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* left_type = expr->left()->bounds().lower; 10233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* right_type = expr->right()->bounds().lower; 10234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* result_type = expr->bounds().lower; 10235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Maybe<int> fixed_right_arg = expr->fixed_right_arg(); 10236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> allocation_site = expr->allocation_site(); 10237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocationMode allocation_mode; 10239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) { 10240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_mode = HAllocationMode(allocation_site); 10241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result = HGraphBuilder::BuildBinaryOperation( 10244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->op(), left, right, left_type, right_type, result_type, 10245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fixed_right_arg, allocation_mode); 10246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Add a simulate after instructions with observable side effects, and 10247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // after phis, which are the result of BuildBinaryOperation when we 10248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inlined some complex subgraph. 10249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (result->HasObservableSideEffects() || result->IsPhi()) { 10250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (push_sim_result == PUSH_BEFORE_SIMULATE) { 10251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(result); 10252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 10253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 10254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 10256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 102591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 102601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 102611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 10262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildBinaryOperation( 10263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::Value op, 10264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left, 10265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right, 10266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* left_type, 10267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* right_type, 10268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* result_type, 10269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Maybe<int> fixed_right_arg, 10270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocationMode allocation_mode) { 10271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation left_rep = Representation::FromType(left_type); 10273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation right_rep = Representation::FromType(right_type); 10274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool maybe_string_add = op == Token::ADD && 10276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (left_type->Maybe(Type::String()) || 10277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left_type->Maybe(Type::Receiver()) || 10278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right_type->Maybe(Type::String()) || 10279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right_type->Maybe(Type::Receiver())); 10280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!left_type->IsInhabited()) { 10282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation", 10283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Deoptimizer::SOFT); 10284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(rossberg): we should be able to get rid of non-continuous 10285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // defaults. 10286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left_type = Type::Any(zone()); 10287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!maybe_string_add) left = TruncateToNumber(left, &left_type); 10289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left_rep = Representation::FromType(left_type); 10290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!right_type->IsInhabited()) { 10293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation", 10294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Deoptimizer::SOFT); 10295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right_type = Type::Any(zone()); 10296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!maybe_string_add) right = TruncateToNumber(right, &right_type); 10298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right_rep = Representation::FromType(right_type); 10299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Special case for string addition here. 10302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (op == Token::ADD && 10303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { 10304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Validate type feedback for left argument. 10305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (left_type->Is(Type::String())) { 10306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left = BuildCheckString(left); 10307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Validate type feedback for right argument. 10310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (right_type->Is(Type::String())) { 10311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right = BuildCheckString(right); 10312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert left argument as necessary. 10315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (left_type->Is(Type::Number())) { 10316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(right_type->Is(Type::String())); 10317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left = BuildNumberToString(left, left_type); 10318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (!left_type->Is(Type::String())) { 10319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(right_type->Is(Type::String())); 10320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT); 10321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(left, right); 10322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddUncasted<HInvokeFunction>(function, 2); 10323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert right argument as necessary. 10326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (right_type->Is(Type::Number())) { 10327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(left_type->Is(Type::String())); 10328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right = BuildNumberToString(right, right_type); 10329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (!right_type->Is(Type::String())) { 10330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(left_type->Is(Type::String())); 10331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); 10332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(left, right); 10333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddUncasted<HInvokeFunction>(function, 2); 10334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fast path for empty constant strings. 10337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (left->IsConstant() && 10338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(left)->HasStringValue() && 10339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(left)->StringValue()->length() == 0) { 10340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return right; 10341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (right->IsConstant() && 10343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(right)->HasStringValue() && 10344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(right)->StringValue()->length() == 0) { 10345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return left; 10346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Register the dependent code with the allocation site. 10349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation_mode.feedback_site().is_null()) { 10350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!graph()->info()->IsStub()); 10351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> site(allocation_mode.feedback_site()); 10352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSite::AddDependentCompilationInfo( 10353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site, AllocationSite::TENURING, top_info()); 10354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Inline the string addition into the stub when creating allocation 10357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // mementos to gather allocation site feedback, or if we can statically 10358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // infer that we're going to create a cons string. 10359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((graph()->info()->IsStub() && 10360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_mode.CreateAllocationMementos()) || 10361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (left->IsConstant() && 10362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(left)->HasStringValue() && 10363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(left)->StringValue()->length() + 1 >= 10364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConsString::kMinLength) || 10365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (right->IsConstant() && 10366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(right)->HasStringValue() && 10367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(right)->StringValue()->length() + 1 >= 10368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConsString::kMinLength)) { 10369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildStringAdd(left, right, allocation_mode); 10370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fallback to using the string add stub. 10373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddUncasted<HStringAdd>( 10374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left, right, allocation_mode.GetPretenureMode(), 10375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); 10376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (graph()->info()->IsStub()) { 10379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left = EnforceNumberType(left, left_type); 10380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right = EnforceNumberType(right, right_type); 103813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 10382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation result_rep = Representation::FromType(result_type); 10384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || 10386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (right_rep.IsTagged() && !right_rep.IsSmi()); 10387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 103883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HInstruction* instr = NULL; 10389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Only the stub is allowed to call into the runtime, since otherwise we would 10390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inline several instructions (including the two pushes) for every tagged 10391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // operation in optimized code, which is more expensive, than a stub call. 10392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (graph()->info()->IsStub() && is_non_primitive) { 10393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op)); 10394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(left, right); 10395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = AddUncasted<HInvokeFunction>(function, 2); 10396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (op) { 10398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::ADD: 10399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = AddUncasted<HAdd>(left, right); 10400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::SUB: 10402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = AddUncasted<HSub>(left, right); 10403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::MUL: 10405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = AddUncasted<HMul>(left, right); 10406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::MOD: { 10408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (fixed_right_arg.has_value && 10409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !right->EqualsInteger32Constant(fixed_right_arg.value)) { 10410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* fixed_right = Add<HConstant>( 10411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(fixed_right_arg.value)); 10412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_same(this); 10413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ); 10414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_same.Then(); 10415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_same.ElseDeopt("Unexpected RHS of binary operation"); 10416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right = fixed_right; 10417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = AddUncasted<HMod>(left, right); 10419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 104203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 10421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::DIV: 10422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = AddUncasted<HDiv>(left, right); 10423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::BIT_XOR: 10425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::BIT_AND: 10426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = AddUncasted<HBitwise>(op, left, right); 10427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::BIT_OR: { 10429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* operand, *shift_amount; 10430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (left_type->Is(Type::Signed32()) && 10431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right_type->Is(Type::Signed32()) && 10432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MatchRotateRight(left, right, &operand, &shift_amount)) { 10433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = AddUncasted<HRor>(operand, shift_amount); 10434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = AddUncasted<HBitwise>(op, left, right); 10436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::SAR: 10440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = AddUncasted<HSar>(left, right); 10441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::SHR: 10443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = AddUncasted<HShr>(left, right); 10444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_opt_safe_uint32_operations && instr->IsShr() && 10445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CanBeZero(right)) { 10446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->RecordUint32Instruction(instr); 10447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::SHL: 10450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = AddUncasted<HShl>(left, right); 10451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 10453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 10454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 104553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 104563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 10457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->IsBinaryOperation()) { 10458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBinaryOperation* binop = HBinaryOperation::cast(instr); 10459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch binop->set_observed_input_representation(1, left_rep); 10460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch binop->set_observed_input_representation(2, right_rep); 10461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch binop->initialize_output_representation(result_rep); 10462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (graph()->info()->IsStub()) { 10463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Stub should not call into stub. 10464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetFlag(HValue::kCannotBeTagged); 10465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // And should truncate on HForceRepresentation already. 10466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (left->IsForceRepresentation()) { 10467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left->CopyFlag(HValue::kTruncatingToSmi, instr); 10468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left->CopyFlag(HValue::kTruncatingToInt32, instr); 10469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (right->IsForceRepresentation()) { 10471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right->CopyFlag(HValue::kTruncatingToSmi, instr); 10472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right->CopyFlag(HValue::kTruncatingToInt32, instr); 10473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 104751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 10476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return instr; 10477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 10478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Check for the form (%_ClassOf(foo) === 'BarClass'). 10481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic bool IsClassOfTest(CompareOperation* expr) { 10482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (expr->op() != Token::EQ_STRICT) return false; 10483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CallRuntime* call = expr->left()->AsCallRuntime(); 10484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (call == NULL) return false; 10485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Literal* literal = expr->right()->AsLiteral(); 10486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (literal == NULL) return false; 10487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!literal->value()->IsString()) return false; 10488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!call->name()->IsOneByteEqualTo(STATIC_CHAR_VECTOR("_ClassOf"))) { 10489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 10490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 10492b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return true; 10493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 10494b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { 10497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 10498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 10499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 10500257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch switch (expr->op()) { 105013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case Token::COMMA: 105023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return VisitComma(expr); 105033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case Token::OR: 105043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case Token::AND: 105053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return VisitLogicalExpression(expr); 105063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch default: 105073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return VisitArithmeticExpression(expr); 10508257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 10509257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 10510b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitComma(BinaryOperation* expr) { 10513257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForEffect(expr->left())); 10514257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Visit the right subexpression in the same AST context as the entire 10515257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // expression. 10516257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Visit(expr->right()); 10517257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 10518e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 10519e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 10520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) { 105213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool is_logical_and = expr->op() == Token::AND; 10522257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (ast_context()->IsTest()) { 10523257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch TestContext* context = TestContext::cast(ast_context()); 10524257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Translate left subexpression. 10525257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* eval_right = graph()->CreateBasicBlock(); 10526257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (is_logical_and) { 10527257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_BAILOUT(VisitForControl(expr->left(), 10528257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch eval_right, 10529257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch context->if_false())); 10530257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 10531257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_BAILOUT(VisitForControl(expr->left(), 10532257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch context->if_true(), 10533257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch eval_right)); 10534257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 10535257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10536257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Translate right subexpression by visiting it in the same AST 10537257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // context as the entire expression. 10538257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (eval_right->HasPredecessor()) { 10539257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch eval_right->SetJoinId(expr->RightId()); 10540e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch set_current_block(eval_right); 10541257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Visit(expr->right()); 10542257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 10543e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 10544257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else if (ast_context()->IsValue()) { 10545257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(expr->left())); 10546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 10547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left_value = Top(); 10548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Short-circuit left values that always evaluate to the same boolean value. 10550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->left()->ToBooleanIsTrue() || expr->left()->ToBooleanIsFalse()) { 10551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // l (evals true) && r -> r 10552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // l (evals true) || r -> l 10553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // l (evals false) && r -> l 10554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // l (evals false) || r -> r 10555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_logical_and == expr->left()->ToBooleanIsTrue()) { 10556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 10557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->right())); 10558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 10560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10561257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10562257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // We need an extra block to maintain edge-split form. 10563257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* empty_block = graph()->CreateBasicBlock(); 10564257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* eval_right = graph()->CreateBasicBlock(); 10565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ToBooleanStub::Types expected(expr->left()->to_boolean_types()); 105663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HBranch* test = is_logical_and 10567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? New<HBranch>(left_value, expected, eval_right, empty_block) 10568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : New<HBranch>(left_value, expected, empty_block, eval_right); 10569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(test); 10570257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10571257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch set_current_block(eval_right); 10572257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Drop(1); // Value of the left subexpression. 10573257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_BAILOUT(VisitForValue(expr->right())); 10574257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10575257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* join_block = 10576257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CreateJoin(empty_block, current_block(), expr->id()); 10577257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch set_current_block(join_block); 105783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnValue(Pop()); 10579e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 10580257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 10581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(ast_context()->IsEffect()); 10582257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // In an effect context, we don't need the value of the left subexpression, 10583257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // only its control flow and side effects. We need an extra block to 10584257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // maintain edge-split form. 10585257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* empty_block = graph()->CreateBasicBlock(); 10586257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* right_block = graph()->CreateBasicBlock(); 10587257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (is_logical_and) { 10588257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_BAILOUT(VisitForControl(expr->left(), right_block, empty_block)); 10589e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 10590257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_BAILOUT(VisitForControl(expr->left(), empty_block, right_block)); 10591257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 10592257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10593257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // TODO(kmillikin): Find a way to fix this. It's ugly that there are 10594257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // actually two empty blocks (one here and one inserted by 10595257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // TestContext::BuildBranch, and that they both have an HSimulate though the 10596257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // second one is not a merge node, and that we really have no good AST ID to 10597257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // put on that first HSimulate. 10598257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10599257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (empty_block->HasPredecessor()) { 10600053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block empty_block->SetJoinId(expr->id()); 10601257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 10602257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch empty_block = NULL; 10603257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 10604257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10605257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (right_block->HasPredecessor()) { 10606053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block right_block->SetJoinId(expr->RightId()); 10607053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block set_current_block(right_block); 10608257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_BAILOUT(VisitForEffect(expr->right())); 10609257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch right_block = current_block(); 10610257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 10611257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch right_block = NULL; 10612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10613b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10614257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* join_block = 10615257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CreateJoin(empty_block, right_block, expr->id()); 10616257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch set_current_block(join_block); 10617257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // We did not materialize any value in the predecessor environments, 10618257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // so there is no need to handle it here. 10619b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10620b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 10621b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { 10624257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(expr->left())); 10625257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(expr->right())); 10626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetSourcePosition(expr->position()); 10627257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HValue* right = Pop(); 10628257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HValue* left = Pop(); 10629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result = 10630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildBinaryOperation(expr, left, right, 10631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE 10632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : PUSH_BEFORE_SIMULATE); 10633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_hydrogen_track_positions && result->IsBinaryOperation()) { 10634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBinaryOperation::cast(result)->SetOperandPositions( 10635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone(), 10636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScriptPositionToSourcePosition(expr->left()->position()), 10637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScriptPositionToSourcePosition(expr->right()->position())); 106383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(result); 106403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 106413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 106423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, 10644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* sub_expr, 10645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> check) { 10646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForTypeOf(sub_expr)); 10647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetSourcePosition(expr->position()); 10648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 10649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HTypeofIsAndBranch* instr = New<HTypeofIsAndBranch>(value, check); 10650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnControl(instr, expr->id()); 106513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 106523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 106533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool IsLiteralCompareBool(Isolate* isolate, 10655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left, 106563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Token::Value op, 106573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HValue* right) { 106583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return op == Token::EQ_STRICT && 10659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ((left->IsConstant() && 10660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(left)->handle(isolate)->IsBoolean()) || 10661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (right->IsConstant() && 10662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(right)->handle(isolate)->IsBoolean())); 10663c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch} 10664c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 10665c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 10666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 10667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 10668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 10669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 10670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 10672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check for a few fast cases. The AST visiting behavior must be in sync 10674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // with the full codegen: We don't push both left and right values onto 10675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the expression stack when one side is a special-case literal. 10676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* sub_expr = NULL; 10677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> check; 10678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { 10679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return HandleLiteralCompareTypeof(expr, sub_expr, check); 10680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) { 10682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue); 10683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->IsLiteralCompareNull(&sub_expr)) { 10685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return HandleLiteralCompareNil(expr, sub_expr, kNullValue); 10686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10688b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (IsClassOfTest(expr)) { 10689b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CallRuntime* call = expr->left()->AsCallRuntime(); 10690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 10691257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 10692b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* value = Pop(); 10693b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Literal* literal = expr->right()->AsLiteral(); 10694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> rhs = Handle<String>::cast(literal->value()); 10695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HClassOfTestAndBranch* instr = New<HClassOfTestAndBranch>(value, rhs); 106963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnControl(instr, expr->id()); 106973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 106983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 10699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* left_type = expr->left()->bounds().lower; 10700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* right_type = expr->right()->bounds().lower; 10701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* combined_type = expr->combined_type(); 107023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 10703257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(expr->left())); 10704257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(expr->right())); 10705b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 10707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10708b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* right = Pop(); 10709b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* left = Pop(); 10710b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Token::Value op = expr->op(); 10711b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsLiteralCompareBool(isolate(), left, op, right)) { 107133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HCompareObjectEqAndBranch* result = 10714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HCompareObjectEqAndBranch>(left, right); 107153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ast_context()->ReturnControl(result, expr->id()); 107163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 107173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10718b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (op == Token::INSTANCEOF) { 10719086aeeaae12517475c22695a200be45495516549Ben Murdoch // Check to see if the rhs of the instanceof is a global function not 10720086aeeaae12517475c22695a200be45495516549Ben Murdoch // residing in new space. If it is we assume that the function will stay the 10721086aeeaae12517475c22695a200be45495516549Ben Murdoch // same. 10722086aeeaae12517475c22695a200be45495516549Ben Murdoch Handle<JSFunction> target = Handle<JSFunction>::null(); 10723589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch VariableProxy* proxy = expr->right()->AsVariableProxy(); 10724589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated(); 10725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (global_function && current_info()->has_global_object()) { 10726589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Handle<String> name = proxy->name(); 10727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<GlobalObject> global(current_info()->global_object()); 10728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupIterator it(global, name, LookupIterator::OWN_SKIP_INTERCEPTOR); 10729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> value = JSObject::GetDataProperty(&it); 10730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (it.IsFound() && value->IsJSFunction()) { 10731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> candidate = Handle<JSFunction>::cast(value); 10732086aeeaae12517475c22695a200be45495516549Ben Murdoch // If the function is in new space we assume it's more likely to 10733086aeeaae12517475c22695a200be45495516549Ben Murdoch // change and thus prefer the general IC code. 1073444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!isolate()->heap()->InNewSpace(*candidate)) { 10735086aeeaae12517475c22695a200be45495516549Ben Murdoch target = candidate; 10736086aeeaae12517475c22695a200be45495516549Ben Murdoch } 10737086aeeaae12517475c22695a200be45495516549Ben Murdoch } 10738086aeeaae12517475c22695a200be45495516549Ben Murdoch } 10739086aeeaae12517475c22695a200be45495516549Ben Murdoch 10740086aeeaae12517475c22695a200be45495516549Ben Murdoch // If the target is not null we have found a known global function that is 10741086aeeaae12517475c22695a200be45495516549Ben Murdoch // assumed to stay the same for this instanceof. 10742086aeeaae12517475c22695a200be45495516549Ben Murdoch if (target.is_null()) { 10743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstanceOf* result = New<HInstanceOf>(left, right); 107443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, expr->id()); 10745086aeeaae12517475c22695a200be45495516549Ben Murdoch } else { 10746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckValue>(right, target); 107473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HInstanceOfKnownGlobal* result = 10748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HInstanceOfKnownGlobal>(left, target); 107493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, expr->id()); 10750086aeeaae12517475c22695a200be45495516549Ben Murdoch } 10751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Code below assumes that we don't fall through. 10753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 10754b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else if (op == Token::IN) { 10755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = AddLoadJSBuiltin(Builtins::IN); 10756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(left, right); 10757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(olivf) InvokeFunction produces a check for the parameter count, 10758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // even though we are certain to pass the correct number of arguments here. 10759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = New<HInvokeFunction>(function, 2); 107603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, expr->id()); 10761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushBeforeSimulateBehavior push_behavior = 10764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE 10765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : PUSH_BEFORE_SIMULATE; 10766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HControlInstruction* compare = BuildCompareInstruction( 10767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch op, left, right, left_type, right_type, combined_type, 10768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScriptPositionToSourcePosition(expr->left()->position()), 10769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScriptPositionToSourcePosition(expr->right()->position()), 10770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch push_behavior, expr->id()); 10771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (compare == NULL) return; // Bailed out. 10772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnControl(compare, expr->id()); 10773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( 10777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::Value op, 10778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left, 10779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right, 10780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* left_type, 10781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* right_type, 10782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* combined_type, 10783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HSourcePosition left_position, 10784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HSourcePosition right_position, 10785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushBeforeSimulateBehavior push_sim_result, 10786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId bailout_id) { 10787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Cases handled below depend on collected type feedback. They should 10788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // soft deoptimize when there is no type feedback. 10789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!combined_type->IsInhabited()) { 10790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HDeoptimize>("Insufficient type feedback for combined type " 10791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "of binary operation", 10792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Deoptimizer::SOFT); 10793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch combined_type = left_type = right_type = Type::Any(zone()); 10794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation left_rep = Representation::FromType(left_type); 10797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation right_rep = Representation::FromType(right_type); 10798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation combined_rep = Representation::FromType(combined_type); 10799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (combined_type->Is(Type::Receiver())) { 10801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (Token::IsEqualityOp(op)) { 10802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // HCompareObjectEqAndBranch can only deal with object, so 10803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // exclude numbers. 10804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((left->IsConstant() && 10805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(left)->HasNumberValue()) || 10806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (right->IsConstant() && 10807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(right)->HasNumberValue())) { 10808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HDeoptimize>("Type mismatch between feedback and constant", 10809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Deoptimizer::SOFT); 10810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The caller expects a branch instruction, so make it happy. 10811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HBranch>(graph()->GetConstantTrue()); 10812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Can we get away with map check and not instance type check? 10814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* operand_to_check = 10815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left->block()->block_id() < right->block()->block_id() ? left : right; 10816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (combined_type->IsClass()) { 10817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = combined_type->AsClass()->Map(); 10818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddCheckMap(operand_to_check, map); 10819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCompareObjectEqAndBranch* result = 10820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HCompareObjectEqAndBranch>(left, right); 10821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_hydrogen_track_positions) { 10822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_operand_position(zone(), 0, left_position); 10823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_operand_position(zone(), 1, right_position); 108243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 10826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(operand_to_check); 10828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckInstanceType>(operand_to_check, 10829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCheckInstanceType::IS_SPEC_OBJECT); 10830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCompareObjectEqAndBranch* result = 10831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HCompareObjectEqAndBranch>(left, right); 10832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 10833b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bailout(kUnsupportedNonPrimitiveCompare); 10836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 10837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (combined_type->Is(Type::InternalizedString()) && 10839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::IsEqualityOp(op)) { 10840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we have a constant argument, it should be consistent with the type 10841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // feedback (otherwise we fail assertions in HCompareObjectEqAndBranch). 10842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((left->IsConstant() && 10843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !HConstant::cast(left)->HasInternalizedStringValue()) || 10844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (right->IsConstant() && 10845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !HConstant::cast(right)->HasInternalizedStringValue())) { 10846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HDeoptimize>("Type mismatch between feedback and constant", 10847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Deoptimizer::SOFT); 10848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The caller expects a branch instruction, so make it happy. 10849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HBranch>(graph()->GetConstantTrue()); 10850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(left); 10852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckInstanceType>(left, HCheckInstanceType::IS_INTERNALIZED_STRING); 10853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(right); 10854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckInstanceType>(right, HCheckInstanceType::IS_INTERNALIZED_STRING); 108553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HCompareObjectEqAndBranch* result = 10856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HCompareObjectEqAndBranch>(left, right); 10857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 10858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (combined_type->Is(Type::String())) { 10859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(left); 10860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckInstanceType>(left, HCheckInstanceType::IS_STRING); 10861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(right); 10862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckInstanceType>(right, HCheckInstanceType::IS_STRING); 10863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStringCompareAndBranch* result = 10864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HStringCompareAndBranch>(left, right, op); 10865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 10866b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 10867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (combined_rep.IsTagged() || combined_rep.IsNone()) { 10868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCompareGeneric* result = Add<HCompareGeneric>(left, right, op); 10869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_observed_input_representation(1, left_rep); 10870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_observed_input_representation(2, right_rep); 10871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (result->HasObservableSideEffects()) { 10872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (push_sim_result == PUSH_BEFORE_SIMULATE) { 10873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(result); 10874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSimulate(bailout_id, REMOVABLE_SIMULATE); 10875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 10876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSimulate(bailout_id, REMOVABLE_SIMULATE); 10878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(jkummerow): Can we make this more efficient? 10881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBranch* branch = New<HBranch>(result); 10882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return branch; 108833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 10884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCompareNumericAndBranch* result = 10885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HCompareNumericAndBranch>(left, right, op); 10886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_observed_input_representation(left_rep, right_rep); 10887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_hydrogen_track_positions) { 10888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->SetOperandPositions(zone(), left_position, right_position); 10889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 108913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 10892b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10893b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 10894b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10895b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, 10897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* sub_expr, 10898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NilValue nil) { 10899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 10900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 10901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 10902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); 10903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 10904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(sub_expr)); 10905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 10906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->op() == Token::EQ_STRICT) { 10907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* nil_constant = nil == kNullValue 10908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? graph()->GetConstantNull() 10909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : graph()->GetConstantUndefined(); 10910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCompareObjectEqAndBranch* instr = 10911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HCompareObjectEqAndBranch>(value, nil_constant); 10912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnControl(instr, expr->id()); 10913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(Token::EQ, expr->op()); 10915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Type* type = expr->combined_type()->Is(Type::None()) 10916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? Type::Any(zone()) : expr->combined_type(); 10917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIfContinuation continuation; 10918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCompareNil(value, type, &continuation); 10919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnContinuation(&continuation, expr->id()); 10920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10921b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 10922b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10923b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildThisFunction() { 10925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we share optimized code between different closures, the 10926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this-function is not a constant, except inside an inlined body. 10927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function_state()->outer() != NULL) { 10928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HConstant>( 10929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state()->compilation_info()->closure()); 10930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HThisFunction>(); 10932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10933b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 10934b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10935b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildFastLiteral( 10937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> boilerplate_object, 10938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteUsageContext* site_context) { 10939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 10940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstanceType instance_type = boilerplate_object->map()->instance_type(); 10941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); 10942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HType type = instance_type == JS_ARRAY_TYPE 10944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? HType::JSArray() : HType::JSObject(); 10945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object_size_constant = Add<HConstant>( 10946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate_object->map()->instance_size()); 10947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PretenureFlag pretenure_flag = NOT_TENURED; 10949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_allocation_site_pretenuring) { 10950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pretenure_flag = site_context->current()->GetPretenureMode(); 10951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> site(site_context->current()); 10952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSite::AddDependentCompilationInfo( 10953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site, AllocationSite::TENURING, top_info()); 109543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 109553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* object = Add<HAllocate>(object_size_constant, type, 10957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pretenure_flag, instance_type, site_context->current()); 10958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If allocation folding reaches Page::kMaxRegularHeapObjectSize the 10960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // elements array may not get folded into the object. Hence, we set the 10961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // elements pointer to empty fixed array and let store elimination remove 10962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this store in the folding case. 10963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* empty_fixed_array = Add<HConstant>( 10964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->empty_fixed_array()); 10965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 10966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch empty_fixed_array); 10967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildEmitObjectHeader(boilerplate_object, object); 10969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArrayBase> elements(boilerplate_object->elements()); 10971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int elements_size = (elements->length() > 0 && 10972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements->map() != isolate()->heap()->fixed_cow_array_map()) ? 10973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements->Size() : 0; 10974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (pretenure_flag == TENURED && 10976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements->map() == isolate()->heap()->fixed_cow_array_map() && 10977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->heap()->InNewSpace(*elements)) { 10978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we would like to pretenure a fixed cow array, we must ensure that the 10979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // array is already in old space, otherwise we'll create too many old-to- 10980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // new-space pointers (overflowing the store buffer). 10981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements = Handle<FixedArrayBase>( 10982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->CopyAndTenureFixedCOWArray( 10983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray>::cast(elements))); 10984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate_object->set_elements(*elements); 10985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* object_elements = NULL; 10988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (elements_size > 0) { 10989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object_elements_size = Add<HConstant>(elements_size); 10990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstanceType instance_type = boilerplate_object->HasFastDoubleElements() 10991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? FIXED_DOUBLE_ARRAY_TYPE : FIXED_ARRAY_TYPE; 10992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_elements = Add<HAllocate>( 10993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_elements_size, HType::HeapObject(), 10994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pretenure_flag, instance_type, site_context->current()); 10995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildInitElementsInObjectHeader(boilerplate_object, object, object_elements); 10997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy object elements if non-COW. 10999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object_elements != NULL) { 11000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildEmitElements(boilerplate_object, elements, object_elements, 11001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site_context); 11002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy in-object properties. 11005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (boilerplate_object->map()->NumberOfFields() != 0 || 11006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate_object->map()->unused_property_fields() > 0) { 11007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildEmitInObjectProperties(boilerplate_object, object, site_context, 11008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pretenure_flag); 11009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return object; 11011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildEmitObjectHeader( 11015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> boilerplate_object, 11016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* object) { 11017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(boilerplate_object->properties()->length() == 0); 11018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> boilerplate_object_map(boilerplate_object->map()); 11020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddStoreMapConstant(object, boilerplate_object_map); 11021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> properties_field = 11023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object>(boilerplate_object->properties(), isolate()); 11024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(*properties_field == isolate()->heap()->empty_fixed_array()); 11025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* properties = Add<HConstant>(properties_field); 11026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = HObjectAccess::ForPropertiesPointer(); 11027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, access, properties); 11028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (boilerplate_object->IsJSArray()) { 11030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSArray> boilerplate_array = 11031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSArray>::cast(boilerplate_object); 11032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> length_field = 11033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object>(boilerplate_array->length(), isolate()); 11034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* length = Add<HConstant>(length_field); 11035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(boilerplate_array->length()->IsSmi()); 11037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength( 11038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate_array->GetElementsKind()), length); 11039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildInitElementsInObjectHeader( 11044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> boilerplate_object, 11045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* object, 11046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* object_elements) { 11047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(boilerplate_object->properties()->length() == 0); 11048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object_elements == NULL) { 11049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> elements_field = 11050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object>(boilerplate_object->elements(), isolate()); 11051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_elements = Add<HConstant>(elements_field); 11052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 11054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_elements); 11055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildEmitInObjectProperties( 11059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> boilerplate_object, 11060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* object, 11061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteUsageContext* site_context, 11062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PretenureFlag pretenure_flag) { 11063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> boilerplate_map(boilerplate_object->map()); 11064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<DescriptorArray> descriptors(boilerplate_map->instance_descriptors()); 11065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int limit = boilerplate_map->NumberOfOwnDescriptors(); 11066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int copied_fields = 0; 11068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < limit; i++) { 11069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyDetails details = descriptors->GetDetails(i); 11070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (details.type() != FIELD) continue; 11071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch copied_fields++; 11072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = descriptors->GetFieldIndex(i); 11073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); 11074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> name(descriptors->GetKey(i)); 11075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> value = 11076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object>(boilerplate_object->InObjectPropertyAt(index), 11077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()); 11078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The access for the store depends on the type of the boilerplate. 11080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = boilerplate_object->IsJSArray() ? 11081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSArrayOffset(property_offset) : 11082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset); 11083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value->IsJSObject()) { 11085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> value_object = Handle<JSObject>::cast(value); 11086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> current_site = site_context->EnterNewScope(); 11087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = 11088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildFastLiteral(value_object, site_context); 11089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site_context->ExitScope(current_site, value_object); 11090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, access, result); 11091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 11092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation representation = details.representation(); 11093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* value_instruction; 11094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (representation.IsDouble()) { 11096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate a HeapNumber box and store the value into it. 11097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize); 11098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This heap number alloc does not have a corresponding 11099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // AllocationSite. That is okay because 11100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 1) it's a child object of another object with a valid allocation site 11101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2) we can just use the mode of the parent object for pretenuring 11102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* double_box = 11103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HAllocate>(heap_number_constant, HType::HeapObject(), 11104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pretenure_flag, MUTABLE_HEAP_NUMBER_TYPE); 11105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddStoreMapConstant(double_box, 11106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->mutable_heap_number_map()); 11107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Unwrap the mutable heap number from the boilerplate. 11108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* double_value = 11109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(Handle<HeapNumber>::cast(value)->value()); 11110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 11111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double_box, HObjectAccess::ForHeapNumberValue(), double_value); 11112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_instruction = double_box; 11113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (representation.IsSmi()) { 11114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_instruction = value->IsUninitialized() 11115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? graph()->GetConstant0() 11116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Add<HConstant>(value); 11117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Ensure that value is stored as smi. 11118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch access = access.WithRepresentation(representation); 11119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 11120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_instruction = Add<HConstant>(value); 111213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, access, value_instruction); 11124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int inobject_properties = boilerplate_object->map()->inobject_properties(); 11128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* value_instruction = 11129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); 11130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = copied_fields; i < inobject_properties; i++) { 11131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(boilerplate_object->IsJSObject()); 11132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); 11133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = 11134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset); 11135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, access, value_instruction); 11136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildEmitElements( 11141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> boilerplate_object, 11142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArrayBase> elements, 11143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object_elements, 11144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteUsageContext* site_context) { 11145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind = boilerplate_object->map()->elements_kind(); 11146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int elements_length = elements->length(); 11147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object_elements_length = Add<HConstant>(elements_length); 11148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildInitializeElementsHeader(object_elements, kind, object_elements_length); 11149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy elements backing store content. 11151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (elements->IsFixedDoubleArray()) { 11152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildEmitFixedDoubleArray(elements, kind, object_elements); 11153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (elements->IsFixedArray()) { 11154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildEmitFixedArray(elements, kind, object_elements, 11155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site_context); 11156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 11157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 11158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( 11163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArrayBase> elements, 11164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 11165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object_elements) { 11166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* boilerplate_elements = Add<HConstant>(elements); 11167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int elements_length = elements->length(); 11168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < elements_length; i++) { 11169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key_constant = Add<HConstant>(i); 11170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* value_instruction = 11171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadKeyed>(boilerplate_elements, key_constant, 11172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<HValue*>(NULL), kind, 11173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOW_RETURN_HOLE); 11174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, 11175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_instruction, kind); 11176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store->SetFlag(HValue::kAllowUndefinedAsNaN); 11177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildEmitFixedArray( 11182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArrayBase> elements, 11183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 11184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object_elements, 11185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteUsageContext* site_context) { 11186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* boilerplate_elements = Add<HConstant>(elements); 11187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int elements_length = elements->length(); 11188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); 11189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < elements_length; i++) { 11190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> value(fast_elements->get(i), isolate()); 11191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key_constant = Add<HConstant>(i); 11192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value->IsJSObject()) { 11193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> value_object = Handle<JSObject>::cast(value); 11194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> current_site = site_context->EnterNewScope(); 11195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = 11196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildFastLiteral(value_object, site_context); 11197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site_context->ExitScope(current_site, value_object); 11198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreKeyed>(object_elements, key_constant, result, kind); 11199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 11200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* value_instruction = 11201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadKeyed>(boilerplate_elements, key_constant, 11202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<HValue*>(NULL), kind, 11203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ALLOW_RETURN_HOLE); 11204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); 112053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 112063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11207589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 11208589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 11209589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 11210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { 11211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 11212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 11213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 11214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = BuildThisFunction(); 11215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 11216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitSuperReference(SuperReference* expr) { 11220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 11221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 11222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 11223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kSuperReference); 11224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitDeclarations( 11228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Declaration*>* declarations) { 11229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(globals_.is_empty()); 11230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AstVisitor::VisitDeclarations(declarations); 11231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!globals_.is_empty()) { 11232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> array = 11233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->NewFixedArray(globals_.length(), TENURED); 11234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); 11235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) | 11236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DeclareGlobalsNativeFlag::encode(current_info()->is_native()) | 11237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DeclareGlobalsStrictMode::encode(current_info()->strict_mode()); 11238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HDeclareGlobals>(array, flags); 11239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch globals_.Rewind(0); 11240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitVariableDeclaration( 11245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VariableDeclaration* declaration) { 11246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VariableProxy* proxy = declaration->proxy(); 11247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VariableMode mode = declaration->mode(); 11248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* variable = proxy->var(); 11249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY; 11250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (variable->location()) { 11251589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch case Variable::UNALLOCATED: 11252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch globals_.Add(variable->name(), zone()); 11253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch globals_.Add(variable->binding_needs_init() 11254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? isolate()->factory()->the_hole_value() 11255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : isolate()->factory()->undefined_value(), zone()); 112563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return; 11257589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch case Variable::PARAMETER: 11258589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch case Variable::LOCAL: 11259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (hole_init) { 11260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = graph()->GetConstantHole(); 11261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Bind(variable, value); 11262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 11264589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch case Variable::CONTEXT: 11265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (hole_init) { 11266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = graph()->GetConstantHole(); 11267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = environment()->context(); 11268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreContextSlot* store = Add<HStoreContextSlot>( 11269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context, variable->index(), HStoreContextSlot::kNoCheck, value); 11270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (store->HasObservableSideEffects()) { 11271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); 11272589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 11273589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 11274589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch break; 11275589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch case Variable::LOOKUP: 11276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kUnsupportedLookupSlotInDeclaration); 112773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 11278b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11279b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitFunctionDeclaration( 11282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FunctionDeclaration* declaration) { 11283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VariableProxy* proxy = declaration->proxy(); 11284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* variable = proxy->var(); 11285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (variable->location()) { 11286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::UNALLOCATED: { 11287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch globals_.Add(variable->name(), zone()); 11288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<SharedFunctionInfo> function = Compiler::BuildFunctionInfo( 11289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch declaration->fun(), current_info()->script(), top_info()); 11290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check for stack-overflow exception. 11291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function.is_null()) return SetStackOverflow(); 11292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch globals_.Add(function, zone()); 11293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 11294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::PARAMETER: 11296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::LOCAL: { 11297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(declaration->fun())); 11298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 11299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BindIfLive(variable, value); 11300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 11301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::CONTEXT: { 11303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(declaration->fun())); 11304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 11305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = environment()->context(); 11306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreContextSlot* store = Add<HStoreContextSlot>( 11307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context, variable->index(), HStoreContextSlot::kNoCheck, value); 11308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (store->HasObservableSideEffects()) { 11309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); 11310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 11312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Variable::LOOKUP: 11314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kUnsupportedLookupSlotInDeclaration); 11315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 113163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 113173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 113183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitModuleDeclaration( 11320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ModuleDeclaration* declaration) { 113213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 113223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 113233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 113243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitImportDeclaration( 11326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ImportDeclaration* declaration) { 113273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 113283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 113293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 113303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitExportDeclaration( 11332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExportDeclaration* declaration) { 113333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 113343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 113353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 113363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitModuleLiteral(ModuleLiteral* module) { 113383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 113393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 113403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 113413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitModuleVariable(ModuleVariable* module) { 11343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 113443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 113453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 113463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitModulePath(ModulePath* module) { 11348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 113493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 113503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 113513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitModuleUrl(ModuleUrl* module) { 11353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 113543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 113553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 113563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitModuleStatement(ModuleStatement* stmt) { 11358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 113593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 113603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 113613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Generators for inline runtime functions. 11363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Support for types. 11364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateIsSmi(CallRuntime* call) { 11365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 11366257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* value = Pop(); 11368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIsSmiAndBranch* result = New<HIsSmiAndBranch>(value); 113693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnControl(result, call->id()); 11370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateIsSpecObject(CallRuntime* call) { 11374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 11375257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* value = Pop(); 113773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HHasInstanceTypeAndBranch* result = 11378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HHasInstanceTypeAndBranch>(value, 11379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FIRST_SPEC_OBJECT_TYPE, 11380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LAST_SPEC_OBJECT_TYPE); 113813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnControl(result, call->id()); 11382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateIsFunction(CallRuntime* call) { 11386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 11387257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* value = Pop(); 113893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HHasInstanceTypeAndBranch* result = 11390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HHasInstanceTypeAndBranch>(value, JS_FUNCTION_TYPE); 11391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnControl(result, call->id()); 11392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateIsMinusZero(CallRuntime* call) { 11396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 11397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 11399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCompareMinusZeroAndBranch* result = New<HCompareMinusZeroAndBranch>(value); 114003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnControl(result, call->id()); 11401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) { 11405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 11406257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* value = Pop(); 114083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HHasCachedArrayIndexAndBranch* result = 11409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HHasCachedArrayIndexAndBranch>(value); 114103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnControl(result, call->id()); 11411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11412b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateIsArray(CallRuntime* call) { 11415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 11416257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* value = Pop(); 114183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HHasInstanceTypeAndBranch* result = 11419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HHasInstanceTypeAndBranch>(value, JS_ARRAY_TYPE); 114203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnControl(result, call->id()); 11421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateIsRegExp(CallRuntime* call) { 11425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 11426257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* value = Pop(); 114283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HHasInstanceTypeAndBranch* result = 11429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HHasInstanceTypeAndBranch>(value, JS_REGEXP_TYPE); 114303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnControl(result, call->id()); 11431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateIsObject(CallRuntime* call) { 11435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 11436257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* value = Pop(); 11438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIsObjectAndBranch* result = New<HIsObjectAndBranch>(value); 114393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnControl(result, call->id()); 11440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11442b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) { 11444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kInlinedRuntimeFunctionIsNonNegativeSmi); 11445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11446b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) { 11449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 11450257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11451257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HValue* value = Pop(); 11452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIsUndetectableAndBranch* result = New<HIsUndetectableAndBranch>(value); 114533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnControl(result, call->id()); 11454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( 11458e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch CallRuntime* call) { 11459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kInlinedRuntimeFunctionIsStringWrapperSafeForDefaultValueOf); 11460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 114631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Support for construct call checks. 11464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateIsConstructCall(CallRuntime* call) { 11465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 0); 114668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (function_state()->outer() != NULL) { 114673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We are generating graph for inlined function. 11468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = function_state()->inlining_kind() == CONSTRUCT_CALL_RETURN 114693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? graph()->GetConstantTrue() 114703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : graph()->GetConstantFalse(); 114713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ast_context()->ReturnValue(value); 114728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else { 11473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnControl(New<HIsConstructCallAndBranch>(), 114743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch call->id()); 114758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 11476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Support for arguments.length and arguments[?]. 11480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { 11481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 0); 11482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NULL; 11483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function_state()->outer() == NULL) { 11484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* elements = Add<HArgumentsElements>(false); 11485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = New<HArgumentsLength>(elements); 11486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 11487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Number of arguments without receiver. 11488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = environment()-> 11489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_environment()->parameter_count() - 1; 11490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = New<HConstant>(argument_count); 11491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 114923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 11493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11494b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { 11497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 11498257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11499b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* index = Pop(); 11500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NULL; 11501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function_state()->outer() == NULL) { 11502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* elements = Add<HArgumentsElements>(false); 11503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* length = Add<HArgumentsLength>(elements); 11504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* checked_index = Add<HBoundsCheck>(index, length); 11505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = New<HAccessArgumentsAt>(elements, length, checked_index); 11506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 11507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnsureArgumentsArePushedForAccess(); 11508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Number of arguments without receiver. 11510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* elements = function_state()->arguments_elements(); 11511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = environment()-> 11512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_environment()->parameter_count() - 1; 11513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* length = Add<HConstant>(argument_count); 11514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* checked_key = Add<HBoundsCheck>(index, length); 11515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = New<HAccessArgumentsAt>(elements, length, checked_key); 11516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 115173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 11518b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11519b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11521b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Support for accessing the class and value fields of an object. 11522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { 11523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The special form detected by IsClassOfTest is detected before we get here 11524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // and does not cause a bailout. 11525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kInlinedRuntimeFunctionClassOf); 11526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateValueOf(CallRuntime* call) { 11530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 11531257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object = Pop(); 11533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_objectisvalue(this); 11535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* objectisvalue = if_objectisvalue.If<HHasInstanceTypeAndBranch>( 11536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, JS_VALUE_TYPE); 11537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectisvalue.Then(); 11538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 11539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the actual value. 11540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Add<HLoadNamedField>( 11541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, objectisvalue, 11542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForObservableJSObjectOffset( 11543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSValue::kValueOffset))); 11544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(call->id(), FIXED_SIMULATE); 11545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectisvalue.Else(); 11547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 11548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the object is not a value return the object. 11549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(object); 11550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(call->id(), FIXED_SIMULATE); 11551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectisvalue.End(); 11553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 11554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateDateField(CallRuntime* call) { 11558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 2); 11559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NE(NULL, call->arguments()->at(1)->AsLiteral()); 11560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Smi* index = Smi::cast(*(call->arguments()->at(1)->AsLiteral()->value())); 115613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 115623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HValue* date = Pop(); 11563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HDateField* result = New<HDateField>(date, index); 115643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ast_context()->ReturnInstruction(result, call->id()); 115653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 115663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 115673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateOneByteSeqStringSetChar( 11569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* call) { 11570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 3); 11571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 11574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* string = Pop(); 11575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 11576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = Pop(); 11577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSeqStringSetChar>(String::ONE_BYTE_ENCODING, string, 11578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch index, value); 11579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(call->id(), FIXED_SIMULATE); 11580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 11581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateTwoByteSeqStringSetChar( 11585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* call) { 11586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 3); 11587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 11590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* string = Pop(); 11591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 11592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = Pop(); 11593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSeqStringSetChar>(String::TWO_BYTE_ENCODING, string, 11594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch index, value); 11595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(call->id(), FIXED_SIMULATE); 11596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 11597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) { 11601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 2); 116023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 116033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 116043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HValue* value = Pop(); 116053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HValue* object = Pop(); 116063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 116073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check if object is a JSValue. 11608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_objectisvalue(this); 11609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectisvalue.If<HHasInstanceTypeAndBranch>(object, JS_VALUE_TYPE); 11610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectisvalue.Then(); 11611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 11612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create in-object property store to kValueOffset. 11613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, 11614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForObservableJSObjectOffset(JSValue::kValueOffset), 11615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value); 11616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) { 11617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(value); 11618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(call->id(), FIXED_SIMULATE); 11620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectisvalue.Else(); 11622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 11623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Nothing to do in this case. 11624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) { 11625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(value); 11626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(call->id(), FIXED_SIMULATE); 11628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectisvalue.End(); 11630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) { 11631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 11632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 116333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ast_context()->ReturnValue(value); 11634b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11635b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11636b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11637b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Fast support for charCodeAt(n). 11638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { 11639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 2); 11640257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11641257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 116421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block HValue* index = Pop(); 116431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block HValue* string = Pop(); 11644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = BuildStringCharCodeAt(string, index); 116453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 11646b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11647b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11648b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11649b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Fast support for string.charAt(n) and string[n]. 11650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { 11651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 11652257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 1165344f0eee88ff00398ff7f715fab053374d808c90dSteve Block HValue* char_code = Pop(); 11654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NewUncasted<HStringCharFromCode>(char_code); 116553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 11656b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11657b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11658b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11659b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Fast support for string.charAt(n) and string[n]. 11660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) { 11661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 2); 11662257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11663257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 1166444f0eee88ff00398ff7f715fab053374d808c90dSteve Block HValue* index = Pop(); 1166544f0eee88ff00398ff7f715fab053374d808c90dSteve Block HValue* string = Pop(); 11666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* char_code = BuildStringCharCodeAt(string, index); 1166744f0eee88ff00398ff7f715fab053374d808c90dSteve Block AddInstruction(char_code); 11668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NewUncasted<HStringCharFromCode>(char_code); 116693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 11670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Fast support for object equality testing. 11674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) { 11675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 2); 11676257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11677257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* right = Pop(); 11679b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* left = Pop(); 116803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HCompareObjectEqAndBranch* result = 11681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HCompareObjectEqAndBranch>(left, right); 116823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnControl(result, call->id()); 11683b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Fast support for StringAdd. 11687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { 11688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(2, call->arguments()->length()); 11689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right = Pop(); 11692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left = Pop(); 11693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NewUncasted<HStringAdd>(left, right); 11694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(result, call->id()); 11695b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11696b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11697b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Fast support for SubString. 11699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { 11700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(3, call->arguments()->length()); 11701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(call->arguments())); 11702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(call->arguments()->length()); 11703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCallStub* result = New<HCallStub>(CodeStub::SubString, 3); 117043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ast_context()->ReturnInstruction(result, call->id()); 11705b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11706b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11707b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Fast support for StringCompare. 11709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) { 11710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(2, call->arguments()->length()); 11711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(call->arguments())); 11712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(call->arguments()->length()); 11713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCallStub* result = New<HCallStub>(CodeStub::StringCompare, 2); 117143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 11715b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11716b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11717b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Support for direct calls from JavaScript to native RegExp code. 11719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { 11720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(4, call->arguments()->length()); 11721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(call->arguments())); 11722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(call->arguments()->length()); 11723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCallStub* result = New<HCallStub>(CodeStub::RegExpExec, 4); 117243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 11725b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11726b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11727b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateDoubleLo(CallRuntime* call) { 11729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(1, call->arguments()->length()); 11730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 11732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NewUncasted<HDoubleBits>(value, HDoubleBits::LOW); 117333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 11734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11736b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateDoubleHi(CallRuntime* call) { 11738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(1, call->arguments()->length()); 11739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 11741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NewUncasted<HDoubleBits>(value, HDoubleBits::HIGH); 117423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 11743b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11744b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11745b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateConstructDouble(CallRuntime* call) { 11747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(2, call->arguments()->length()); 11748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* lo = Pop(); 11751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* hi = Pop(); 11752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NewUncasted<HConstructDouble>(hi, lo); 117533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 11754b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11755b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11756b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Construct a RegExp exec result with two in-object properties. 11758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { 11759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(3, call->arguments()->length()); 11760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 11763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* input = Pop(); 11764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = Pop(); 11765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length = Pop(); 11766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result = BuildRegExpConstructResult(length, index, input); 11767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(result); 11768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11771b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Support for fast native caches. 11772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { 11773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kInlinedRuntimeFunctionGetFromCache); 11774b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11775b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11776b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11777b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Fast support for number to string. 11778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { 11779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(1, call->arguments()->length()); 11780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* number = Pop(); 11782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result = BuildNumberToString(number, Type::Any(zone())); 11783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(result); 11784b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11785b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11786b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11787b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Fast call for custom callbacks. 11788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { 11789257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // 1 ~ The function to call is not itself an argument to the call. 11790257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int arg_count = call->arguments()->length() - 1; 11791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(arg_count >= 1); // There's always at least a receiver. 117923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(call->arguments())); 11794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The function is the last argument 11795257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HValue* function = Pop(); 11796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Push the arguments to the stack 11797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(arg_count); 117983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_is_jsfunction(this); 11800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_is_jsfunction.If<HHasInstanceTypeAndBranch>(function, JS_FUNCTION_TYPE); 118013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_is_jsfunction.Then(); 11803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 11804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* invoke_result = 11805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HInvokeFunction>(function, arg_count); 11806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) { 11807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(invoke_result); 11808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(call->id(), FIXED_SIMULATE); 11810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_is_jsfunction.Else(); 11813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 11814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* call_result = 11815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCallFunction>(function, arg_count); 11816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) { 11817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(call_result); 11818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(call->id(), FIXED_SIMULATE); 11820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_is_jsfunction.End(); 11822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ast_context()->IsEffect()) { 11824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // EffectContext::ReturnValue ignores the value, so we can just pass 11825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 'undefined' (as we do not have the call result anymore). 11826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 11827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 11828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 11829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11830b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11831b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11832b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11833b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Fast call to math functions. 11834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) { 11835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(2, call->arguments()->length()); 11836257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11837257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11838b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* right = Pop(); 11839b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* left = Pop(); 11840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NewUncasted<HPower>(left, right); 118413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 11842b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11843b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11844b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateMathLogRT(CallRuntime* call) { 11846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 11847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 11849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NewUncasted<HUnaryMathOperation>(value, kMathLog); 118503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 11851b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11852b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11853b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateMathSqrtRT(CallRuntime* call) { 11855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 11856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 11858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NewUncasted<HUnaryMathOperation>(value, kMathSqrt); 118593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 11860b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11861b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11862b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) { 11864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 11865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 11867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HGetCachedArrayIndex* result = New<HGetCachedArrayIndex>(value); 118683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ast_context()->ReturnInstruction(result, call->id()); 118693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 118703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 118713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateFastOneByteArrayJoin(CallRuntime* call) { 11873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kInlinedRuntimeFunctionFastOneByteArrayJoin); 11874b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11875b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11876b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Support for generators. 11878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateGeneratorNext(CallRuntime* call) { 11879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kInlinedRuntimeFunctionGeneratorNext); 11880b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11881b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11882b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateGeneratorThrow(CallRuntime* call) { 11884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kInlinedRuntimeFunctionGeneratorThrow); 11885b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11886b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11887b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateDebugBreakInOptimizedCode( 11889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* call) { 11890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HDebugBreak>(); 11891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(graph()->GetConstant0()); 11892b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11893b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11894b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateDebugIsActive(CallRuntime* call) { 11896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 0); 11897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* ref = 11898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(ExternalReference::debug_is_active_address(isolate())); 11899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Add<HLoadNamedField>( 11900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ref, static_cast<HValue*>(NULL), HObjectAccess::ForExternalUInteger8()); 11901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(value); 11902b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11903b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11904b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11905b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef CHECK_BAILOUT 11906257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#undef CHECK_ALIVE 11907b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11908b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11909b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHEnvironment::HEnvironment(HEnvironment* outer, 11910b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Scope* scope, 11911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> closure, 11912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone) 11913b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : closure_(closure), 11914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values_(0, zone), 119153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch frame_type_(JS_FUNCTION), 11916b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch parameter_count_(0), 11917257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch specials_count_(1), 11918b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch local_count_(0), 11919b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch outer_(outer), 11920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_(NULL), 11921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pop_count_(0), 11922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch push_count_(0), 11923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_id_(BailoutId::None()), 11924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone_(zone) { 11925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* declaration_scope = scope->DeclarationScope(); 11926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Initialize(declaration_scope->num_parameters() + 1, 11927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch declaration_scope->num_stack_slots(), 0); 11928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHEnvironment::HEnvironment(Zone* zone, int parameter_count) 11932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : values_(0, zone), 11933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch frame_type_(STUB), 11934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch parameter_count_(parameter_count), 11935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch specials_count_(1), 11936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch local_count_(0), 11937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer_(NULL), 11938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_(NULL), 11939b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch pop_count_(0), 11940b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch push_count_(0), 11941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_id_(BailoutId::None()), 11942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone_(zone) { 11943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Initialize(parameter_count, 0, 0); 11944b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11945b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11946b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) 11948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : values_(0, zone), 119493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch frame_type_(JS_FUNCTION), 11950b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch parameter_count_(0), 11951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch specials_count_(0), 11952b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch local_count_(0), 11953b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch outer_(NULL), 11954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_(NULL), 11955b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch pop_count_(0), 11956b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch push_count_(0), 11957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_id_(other->ast_id()), 11958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone_(zone) { 11959b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Initialize(other); 11960b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11961b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11962b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 119633ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHEnvironment::HEnvironment(HEnvironment* outer, 119643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSFunction> closure, 119653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FrameType frame_type, 11966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int arguments, 11967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone) 119683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : closure_(closure), 11969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values_(arguments, zone), 119703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch frame_type_(frame_type), 119713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch parameter_count_(arguments), 11972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch specials_count_(0), 119733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch local_count_(0), 119743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch outer_(outer), 11975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_(NULL), 119763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pop_count_(0), 119773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch push_count_(0), 11978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_id_(BailoutId::None()), 11979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone_(zone) { 119803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 119813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 119823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11983b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HEnvironment::Initialize(int parameter_count, 11984b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int local_count, 11985b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int stack_height) { 11986b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch parameter_count_ = parameter_count; 11987b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch local_count_ = local_count; 11988b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11989b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Avoid reallocating the temporaries' backing store on the first Push. 11990257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int total = parameter_count + specials_count_ + local_count + stack_height; 11991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values_.Initialize(total + 4, zone()); 11992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < total; ++i) values_.Add(NULL, zone()); 11993b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11994b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11995b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 119969fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockvoid HEnvironment::Initialize(const HEnvironment* other) { 119979fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block closure_ = other->closure(); 11998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values_.AddAll(other->values_, zone()); 11999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assigned_variables_.Union(other->assigned_variables_, zone()); 120003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch frame_type_ = other->frame_type_; 120019fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block parameter_count_ = other->parameter_count_; 120029fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block local_count_ = other->local_count_; 120039fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. 12004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_ = other->entry_; 120059fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block pop_count_ = other->pop_count_; 120069fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block push_count_ = other->push_count_; 12007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch specials_count_ = other->specials_count_; 120089fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block ast_id_ = other->ast_id_; 120099fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block} 120109fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 120119fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 12012b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { 12013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!block->IsLoopHeader()); 12014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(values_.length() == other->values_.length()); 12015b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12016b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int length = values_.length(); 12017b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < length; ++i) { 12018b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* value = values_[i]; 12019b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (value != NULL && value->IsPhi() && value->block() == block) { 12020b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // There is already a phi for the i'th value. 12021b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HPhi* phi = HPhi::cast(value); 12022b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Assert index is correct and that we haven't missed an incoming edge. 12023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(phi->merged_index() == i || !phi->HasMergedIndex()); 12024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(phi->OperandCount() == block->predecessors()->length()); 12025b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phi->AddInput(other->values_[i]); 12026b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else if (values_[i] != other->values_[i]) { 12027b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // There is a fresh value on the incoming edge, a phi is needed. 12028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(values_[i] != NULL && other->values_[i] != NULL); 12029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhi* phi = block->AddNewPhi(i); 12030b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* old_value = values_[i]; 12031b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int j = 0; j < block->predecessors()->length(); j++) { 12032b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phi->AddInput(old_value); 12033b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phi->AddInput(other->values_[i]); 12035b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch this->values_[i] = phi; 12036b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12038b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12039b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12040b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 120419fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockvoid HEnvironment::Bind(int index, HValue* value) { 12042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(value != NULL); 12043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assigned_variables_.Add(index, zone()); 120449fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block values_[index] = value; 12045b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12046b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12047b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 120489fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockbool HEnvironment::HasExpressionAt(int index) const { 12049257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return index >= parameter_count_ + specials_count_ + local_count_; 120509fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block} 120519fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 120529fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 120539fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockbool HEnvironment::ExpressionStackIsEmpty() const { 12054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(length() >= first_expression_index()); 120553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return length() == first_expression_index(); 120569fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block} 120579fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 120589fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 120599fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockvoid HEnvironment::SetExpressionStackAt(int index_from_top, HValue* value) { 120609fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block int count = index_from_top + 1; 120619fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block int index = values_.length() - count; 12062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(HasExpressionAt(index)); 120639fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block // The push count must include at least the element in question or else 120649fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block // the new value will not be included in this environment's history. 120659fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block if (push_count_ < count) { 120669fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block // This is the same effect as popping then re-pushing 'count' elements. 120679fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block pop_count_ += (count - push_count_); 120689fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block push_count_ = count; 120699fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block } 120709fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block values_[index] = value; 120719fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block} 120729fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 120739fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 120749fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockvoid HEnvironment::Drop(int count) { 120759fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block for (int i = 0; i < count; ++i) { 120769fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block Pop(); 12077b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12078b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12079b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12080b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12081b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHEnvironment* HEnvironment::Copy() const { 12082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new(zone()) HEnvironment(this, zone()); 12083b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12084b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12085b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12086b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHEnvironment* HEnvironment::CopyWithoutHistory() const { 12087b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HEnvironment* result = Copy(); 12088b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result->ClearHistory(); 12089b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return result; 12090b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12091b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12092b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12093b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { 12094b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HEnvironment* new_env = Copy(); 12095b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < values_.length(); ++i) { 12096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhi* phi = loop_header->AddNewPhi(i); 12097b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phi->AddInput(values_[i]); 12098b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch new_env->values_[i] = phi; 12099b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch new_env->ClearHistory(); 12101b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return new_env; 12102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 121053ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, 121063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSFunction> target, 121073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FrameType frame_type, 121083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int arguments) const { 12109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* new_env = 12110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new(zone()) HEnvironment(outer, target, frame_type, 12111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments + 1, zone()); 121123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i <= arguments; ++i) { // Include receiver. 121133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_env->Push(ExpressionStackAt(arguments - i)); 121143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 121153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_env->ClearHistory(); 121163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return new_env; 121173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 121183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 121193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12120257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochHEnvironment* HEnvironment::CopyForInlining( 12121257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<JSFunction> target, 121223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int arguments, 12123257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch FunctionLiteral* function, 12124257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HConstant* undefined, 12125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InliningKind inlining_kind) const { 12126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(frame_type() == JS_FUNCTION); 121273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Outer environment is a copy of this one without the arguments. 12129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int arity = function->scope()->num_parameters(); 121303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HEnvironment* outer = Copy(); 121323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch outer->Drop(arguments + 1); // Including receiver. 12133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch outer->ClearHistory(); 121343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (inlining_kind == CONSTRUCT_CALL_RETURN) { 121363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Create artificial constructor stub environment. The receiver should 121373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // actually be the constructor function, but we pass the newly allocated 121383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // object instead, DoComputeConstructStubFrame() relies on that. 121393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch outer = CreateStubEnvironment(outer, target, JS_CONSTRUCT, arguments); 12140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (inlining_kind == GETTER_CALL_RETURN) { 12141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We need an additional StackFrame::INTERNAL frame for restoring the 12142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // correct context. 12143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer = CreateStubEnvironment(outer, target, JS_GETTER, arguments); 12144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (inlining_kind == SETTER_CALL_RETURN) { 12145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We need an additional StackFrame::INTERNAL frame for temporarily saving 12146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the argument of the setter, see StoreStubCompiler::CompileStoreViaSetter. 12147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer = CreateStubEnvironment(outer, target, JS_SETTER, arguments); 121483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 121493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 121503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (arity != arguments) { 121513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Create artificial arguments adaptation environment. 121523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch outer = CreateStubEnvironment(outer, target, ARGUMENTS_ADAPTOR, arguments); 121533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 121543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 121558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HEnvironment* inner = 12156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new(zone()) HEnvironment(outer, function->scope(), target, zone()); 12157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the argument values from the original environment. 121583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = 0; i <= arity; ++i) { // Include receiver. 121593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HValue* push = (i <= arguments) ? 121603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExpressionStackAt(arguments - i) : undefined; 121613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch inner->SetValueAt(i, push); 121623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 12163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inner->SetValueAt(arity + 1, context()); 12164257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch for (int i = arity + 2; i < inner->length(); ++i) { 12165257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch inner->SetValueAt(i, undefined); 12166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inner->set_ast_id(BailoutId::FunctionEntry()); 12169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return inner; 12170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOStream& operator<<(OStream& os, const HEnvironment& env) { 12174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < env.length(); i++) { 12175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i == 0) os << "parameters\n"; 12176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i == env.parameter_count()) os << "specials\n"; 12177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i == env.parameter_count() + env.specials_count()) os << "locals\n"; 12178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i == env.parameter_count() + env.specials_count() + env.local_count()) { 12179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << "expressions\n"; 12180257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 12181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* val = env.values()->at(i); 12182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << i << ": "; 12183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (val != NULL) { 12184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << val; 12185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 12186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << "NULL"; 12187b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << "\n"; 12189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return os << "\n"; 12191b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HTracer::TraceCompilation(CompilationInfo* info) { 12195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Tag tag(this, "compilation"); 12196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->IsOptimizing()) { 12197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> name = info->function()->debug_name(); 12198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintStringProperty("name", name->ToCString().get()); 12199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintIndent(); 12200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trace_.Add("method \"%s:%d\"\n", 12201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch name->ToCString().get(), 12202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->optimization_id()); 12203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 12204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeStub::Major major_key = info->code_stub()->MajorKey(); 12205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintStringProperty("name", CodeStub::MajorName(major_key, false)); 12206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintStringProperty("method", "stub"); 12207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintLongProperty("date", 12209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int64_t>(base::OS::TimeCurrentMillis())); 12210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12213b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HTracer::TraceLithium(const char* name, LChunk* chunk) { 12214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!chunk->isolate()->concurrent_recompilation_enabled()); 12215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowHandleDereference allow_deref; 12216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference allow_deferred_deref; 12217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Trace(name, chunk->graph(), chunk); 12218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12219b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HTracer::TraceHydrogen(const char* name, HGraph* graph) { 12222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!graph->isolate()->concurrent_recompilation_enabled()); 12223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowHandleDereference allow_deref; 12224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference allow_deferred_deref; 12225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Trace(name, graph, NULL); 12226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HTracer::Trace(const char* name, HGraph* graph, LChunk* chunk) { 12230b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Tag tag(this, "cfg"); 12231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintStringProperty("name", name); 12232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const ZoneList<HBasicBlock*>* blocks = graph->blocks(); 12233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < blocks->length(); i++) { 12234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* current = blocks->at(i); 12235b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Tag block_tag(this, "block"); 12236b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintBlockProperty("name", current->block_id()); 12237b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintIntProperty("from_bci", -1); 12238b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintIntProperty("to_bci", -1); 12239b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!current->predecessors()->is_empty()) { 12241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintIndent(); 12242b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add("predecessors"); 12243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int j = 0; j < current->predecessors()->length(); ++j) { 12244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" \"B%d\"", current->predecessors()->at(j)->block_id()); 12245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add("\n"); 12247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 12248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintEmptyProperty("predecessors"); 12249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 122513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current->end()->SuccessorCount() == 0) { 12252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintEmptyProperty("successors"); 122533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 122543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrintIndent(); 122553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch trace_.Add("successors"); 122563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (HSuccessorIterator it(current->end()); !it.Done(); it.Advance()) { 122573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch trace_.Add(" \"B%d\"", it.Current()->block_id()); 122583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 122593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch trace_.Add("\n"); 12260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12261b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12262b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintEmptyProperty("xhandlers"); 12263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 12264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 12265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintIndent(); 12266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trace_.Add("flags"); 12267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current->IsLoopSuccessorDominator()) { 12268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trace_.Add(" \"dom-loop-succ\""); 12269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current->IsUnreachable()) { 12271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trace_.Add(" \"dead\""); 12272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current->is_osr_entry()) { 12274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trace_.Add(" \"osr\""); 12275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trace_.Add("\n"); 12277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12278b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12279b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (current->dominator() != NULL) { 12280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintBlockProperty("dominator", current->dominator()->block_id()); 12281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12283589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch PrintIntProperty("loop_depth", current->LoopNestingDepth()); 12284589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 12285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (chunk != NULL) { 12286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int first_index = current->first_instruction_index(); 12287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int last_index = current->last_instruction_index(); 12288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintIntProperty( 12289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "first_lir_id", 12290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LifetimePosition::FromInstructionIndex(first_index).Value()); 12291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintIntProperty( 12292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "last_lir_id", 12293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LifetimePosition::FromInstructionIndex(last_index).Value()); 12294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 12297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Tag states_tag(this, "states"); 12298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Tag locals_tag(this, "locals"); 12299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int total = current->phis()->length(); 12300257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch PrintIntProperty("size", current->phis()->length()); 12301257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch PrintStringProperty("method", "None"); 12302b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int j = 0; j < total; ++j) { 12303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HPhi* phi = current->phis()->at(j); 12304257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch PrintIndent(); 12305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OStringStream os; 12306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << phi->merged_index() << " " << NameOf(phi) << " " << *phi << "\n"; 12307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trace_.Add(os.c_str()); 12308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 12312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Tag HIR_tag(this, "HIR"); 12313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (HInstructionIterator it(current); !it.Done(); it.Advance()) { 12314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instruction = it.Current(); 12315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int uses = instruction->UseCount(); 12316257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch PrintIndent(); 12317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OStringStream os; 12318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << "0 " << uses << " " << NameOf(instruction) << " " << *instruction; 12319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_hydrogen_track_positions && 12320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instruction->has_position() && 12321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instruction->position().raw() != 0) { 12322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const HSourcePosition pos = instruction->position(); 12323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << " pos:"; 12324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (pos.inlining_id() != 0) os << pos.inlining_id() << "_"; 12325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << pos.position(); 12326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << " <|@\n"; 12328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trace_.Add(os.c_str()); 12329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12330b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (chunk != NULL) { 12334b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Tag LIR_tag(this, "LIR"); 12335b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int first_index = current->first_instruction_index(); 12336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int last_index = current->last_instruction_index(); 12337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (first_index != -1 && last_index != -1) { 12338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const ZoneList<LInstruction*>* instructions = chunk->instructions(); 12339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = first_index; i <= last_index; ++i) { 12340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LInstruction* linstr = instructions->at(i); 12341b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (linstr != NULL) { 12342257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch PrintIndent(); 12343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add("%d ", 12344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LifetimePosition::FromInstructionIndex(i).Value()); 12345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch linstr->PrintTo(&trace_); 12346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OStringStream os; 12347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << " [hir:" << NameOf(linstr->hydrogen_value()) << "] <|@\n"; 12348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trace_.Add(os.c_str()); 12349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HTracer::TraceLiveRanges(const char* name, LAllocator* allocator) { 12358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Tag tag(this, "intervals"); 12359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintStringProperty("name", name); 12360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1236144f0eee88ff00398ff7f715fab053374d808c90dSteve Block const Vector<LiveRange*>* fixed_d = allocator->fixed_double_live_ranges(); 12362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < fixed_d->length(); ++i) { 12363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceLiveRange(fixed_d->at(i), "fixed", allocator->zone()); 12364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1236644f0eee88ff00398ff7f715fab053374d808c90dSteve Block const Vector<LiveRange*>* fixed = allocator->fixed_live_ranges(); 12367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < fixed->length(); ++i) { 12368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceLiveRange(fixed->at(i), "fixed", allocator->zone()); 12369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const ZoneList<LiveRange*>* live_ranges = allocator->live_ranges(); 12372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < live_ranges->length(); ++i) { 12373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceLiveRange(live_ranges->at(i), "object", allocator->zone()); 12374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HTracer::TraceLiveRange(LiveRange* range, const char* type, 12379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone) { 12380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (range != NULL && !range->IsEmpty()) { 12381257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch PrintIndent(); 12382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add("%d %s", range->id(), type); 12383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (range->HasRegisterAssigned()) { 12384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* op = range->CreateAssignedOperand(zone); 12385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int assigned_reg = op->index(); 12386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (op->IsDoubleRegister()) { 12387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" \"%s\"", 12388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DoubleRegister::AllocationIndexToString(assigned_reg)); 12389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 12390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(op->IsRegister()); 12391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg)); 12392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else if (range->IsSpilled()) { 12394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LOperand* op = range->TopLevel()->GetSpillOperand(); 12395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (op->IsDoubleStackSlot()) { 12396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" \"double_stack:%d\"", op->index()); 12397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 12398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(op->IsStackSlot()); 12399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" \"stack:%d\"", op->index()); 12400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int parent_index = -1; 12403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (range->IsChild()) { 12404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch parent_index = range->parent()->id(); 12405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 12406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch parent_index = range->id(); 12407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LOperand* op = range->FirstHint(); 12409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int hint_index = -1; 124103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (op != NULL && op->IsUnallocated()) { 124113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch hint_index = LUnallocated::cast(op)->virtual_register(); 124123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" %d %d", parent_index, hint_index); 12414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UseInterval* cur_interval = range->first_interval(); 12415e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while (cur_interval != NULL && range->Covers(cur_interval->start())) { 12416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" [%d, %d[", 12417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch cur_interval->start().Value(), 12418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch cur_interval->end().Value()); 12419b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch cur_interval = cur_interval->next(); 12420b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UsePosition* current_pos = range->first_pos(); 12423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (current_pos != NULL) { 12424e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (current_pos->RegisterIsBeneficial() || FLAG_trace_all_uses) { 12425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" %d M", current_pos->pos().Value()); 12426b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch current_pos = current_pos->next(); 12428b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12429b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" \"\"\n"); 12431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HTracer::FlushToFile() { 12436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AppendChars(filename_.start(), trace_.ToCString().get(), trace_.length(), 12437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch false); 12438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Reset(); 12439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1244244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid HStatistics::Initialize(CompilationInfo* info) { 12443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->shared_info().is_null()) return; 1244444f0eee88ff00398ff7f715fab053374d808c90dSteve Block source_size_ += info->shared_info()->SourceSize(); 1244544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 1244644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1244744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 12448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HStatistics::Print(const char* stats_name) { 12449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF( 12450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "\n" 12451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "----------------------------------------" 12452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "----------------------------------------\n" 12453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "--- %s timing results:\n" 12454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "----------------------------------------" 12455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "----------------------------------------\n", 12456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stats_name); 12457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeDelta sum; 12458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < times_.length(); ++i) { 12459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sum += times_[i]; 12460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < names_.length(); ++i) { 12463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("%33s", names_[i]); 12464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double ms = times_[i].InMillisecondsF(); 12465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double percent = times_[i].PercentOf(sum); 12466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF(" %8.3f ms / %4.1f %% ", ms, percent); 12467b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 12468b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch unsigned size = sizes_[i]; 12469b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch double size_percent = static_cast<double>(size) * 100 / total_size_; 12470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF(" %9u bytes / %4.1f %%\n", size, size_percent); 12471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 12473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF( 12474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "----------------------------------------" 12475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "----------------------------------------\n"); 12476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeDelta total = create_graph_ + optimize_graph_ + generate_code_; 12477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("%33s %8.3f ms / %4.1f %% \n", "Create graph", 12478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch create_graph_.InMillisecondsF(), create_graph_.PercentOf(total)); 12479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("%33s %8.3f ms / %4.1f %% \n", "Optimize graph", 12480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch optimize_graph_.InMillisecondsF(), optimize_graph_.PercentOf(total)); 12481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("%33s %8.3f ms / %4.1f %% \n", "Generate and install code", 12482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch generate_code_.InMillisecondsF(), generate_code_.PercentOf(total)); 12483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF( 12484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "----------------------------------------" 12485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "----------------------------------------\n"); 12486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("%33s %8.3f ms %9u bytes\n", "Total", 12487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total.InMillisecondsF(), total_size_); 12488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("%33s (%.1f times slower than full code gen)\n", "", 12489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total.TimesOf(full_code_gen_)); 12490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1249144f0eee88ff00398ff7f715fab053374d808c90dSteve Block double source_size_in_kb = static_cast<double>(source_size_) / 1024; 1249244f0eee88ff00398ff7f715fab053374d808c90dSteve Block double normalized_time = source_size_in_kb > 0 12493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? total.InMillisecondsF() / source_size_in_kb 1249444f0eee88ff00398ff7f715fab053374d808c90dSteve Block : 0; 12495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double normalized_size_in_kb = source_size_in_kb > 0 12496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? total_size_ / 1024 / source_size_in_kb 1249744f0eee88ff00398ff7f715fab053374d808c90dSteve Block : 0; 12498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("%33s %8.3f ms %7.3f kB allocated\n", 12499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "Average per kB source", normalized_time, normalized_size_in_kb); 12500b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12501b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12502b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HStatistics::SaveTiming(const char* name, base::TimeDelta time, 12504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned size) { 12505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total_size_ += size; 12506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < names_.length(); ++i) { 12507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (strcmp(names_[i], name) == 0) { 12508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch times_[i] += time; 12509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sizes_[i] += size; 12510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 12511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12512b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch names_.Add(name); 12514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch times_.Add(time); 12515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sizes_.Add(size); 12516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12518b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHPhase::~HPhase() { 12520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ShouldProduceTraceOutput()) { 12521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 12525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph_->Verify(false); // No full verify. 12526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 12527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} } // namespace v8::internal 12530