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 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen.h" 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <memory> 8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <sstream> 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation-site-scopes.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/ast-numbering.h" 12f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/ast/compile-time-value.h" 13f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/ast/scopes.h" 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/code-factory.h" 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-bce.h" 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-canonicalize.h" 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-check-elimination.h" 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-dce.h" 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-dehoist.h" 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-environment-liveness.h" 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-escape-analysis.h" 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-gvn.h" 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-infer-representation.h" 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-infer-types.h" 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-load-elimination.h" 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-mark-unreachable.h" 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-osr.h" 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-range-analysis.h" 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-redundant-phi.h" 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-removable-simulates.h" 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-representation-changes.h" 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-sce.h" 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-store-elimination.h" 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-uint32-analysis.h" 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/lithium-allocator.h" 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/typing.h" 37109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/field-type.h" 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/full-codegen/full-codegen.h" 39f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/globals.h" 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ic/call-optimization.h" 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ic/ic.h" 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// GetRootConstructor 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ic/ic-inl.h" 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate-inl.h" 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/runtime/runtime.h" 46b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 47b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#if V8_TARGET_ARCH_IA32 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/ia32/lithium-codegen-ia32.h" // NOLINT 49b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#elif V8_TARGET_ARCH_X64 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/x64/lithium-codegen-x64.h" // NOLINT 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_ARM64 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/arm64/lithium-codegen-arm64.h" // NOLINT 53b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#elif V8_TARGET_ARCH_ARM 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/arm/lithium-codegen-arm.h" // NOLINT 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#elif V8_TARGET_ARCH_PPC 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/ppc/lithium-codegen-ppc.h" // NOLINT 5744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#elif V8_TARGET_ARCH_MIPS 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/mips/lithium-codegen-mips.h" // NOLINT 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_MIPS64 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/mips64/lithium-codegen-mips64.h" // NOLINT 613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#elif V8_TARGET_ARCH_S390 623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#include "src/crankshaft/s390/lithium-codegen-s390.h" // NOLINT 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_X87 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/x87/lithium-codegen-x87.h" // NOLINT 65b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#else 66b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#error Unsupported target architecture. 67b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 68b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 69b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 { 70b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal { 71b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochconst auto GetRegConfig = RegisterConfiguration::Crankshaft; 7313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 74bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochclass HOptimizedGraphBuilderWithPositions : public HOptimizedGraphBuilder { 75bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch public: 76bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch explicit HOptimizedGraphBuilderWithPositions(CompilationInfo* info) 77f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch : HOptimizedGraphBuilder(info, true) { 78f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch SetSourcePosition(info->shared_info()->start_position()); 79f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 80bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 81bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define DEF_VISIT(type) \ 82bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void Visit##type(type* node) override { \ 83bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch SourcePosition old_position = SourcePosition::Unknown(); \ 84f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (node->position() != kNoSourcePosition) { \ 85bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch old_position = source_position(); \ 86bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch SetSourcePosition(node->position()); \ 87bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } \ 88bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HOptimizedGraphBuilder::Visit##type(node); \ 89c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (old_position.IsKnown()) { \ 90bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch set_source_position(old_position); \ 91bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } \ 92bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 93bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch EXPRESSION_NODE_LIST(DEF_VISIT) 94bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#undef DEF_VISIT 95bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 96bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define DEF_VISIT(type) \ 97bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void Visit##type(type* node) override { \ 98bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch SourcePosition old_position = SourcePosition::Unknown(); \ 99f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (node->position() != kNoSourcePosition) { \ 100bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch old_position = source_position(); \ 101bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch SetSourcePosition(node->position()); \ 102bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } \ 103bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HOptimizedGraphBuilder::Visit##type(node); \ 104c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (old_position.IsKnown()) { \ 105bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch set_source_position(old_position); \ 106bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } \ 107bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 108bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch STATEMENT_NODE_LIST(DEF_VISIT) 109bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#undef DEF_VISIT 110bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 111bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define DEF_VISIT(type) \ 112bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void Visit##type(type* node) override { \ 113bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HOptimizedGraphBuilder::Visit##type(node); \ 114bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 115bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DECLARATION_NODE_LIST(DEF_VISIT) 116bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#undef DEF_VISIT 117bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}; 118bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 119f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochHCompilationJob::Status HCompilationJob::PrepareJobImpl() { 120f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!isolate()->use_crankshaft() || 12162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch info()->shared_info()->must_use_ignition_turbo()) { 122f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Crankshaft is entirely disabled. 123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return FAILED; 124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 125bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 126bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Optimization requires a version of fullcode with deoptimization support. 127bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Recompile the unoptimized version of the code if the current version 128bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // doesn't have deoptimization support already. 129bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Otherwise, if we are gathering compilation time and space statistics 130bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // for hydrogen, gather baseline statistics for a fullcode compilation. 131bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch bool should_recompile = !info()->shared_info()->has_deoptimization_support(); 132bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (should_recompile || FLAG_hydrogen_stats) { 133bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch base::ElapsedTimer timer; 134bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (FLAG_hydrogen_stats) { 135bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch timer.Start(); 136bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 137bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!Compiler::EnsureDeoptimizationSupport(info())) { 138bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return FAILED; 139bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 140bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (FLAG_hydrogen_stats) { 141bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch isolate()->GetHStatistics()->IncrementFullCodeGen(timer.Elapsed()); 142bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 143bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 144bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(info()->shared_info()->has_deoptimization_support()); 145bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 146bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Check the whitelist for Crankshaft. 147bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!info()->shared_info()->PassesFilter(FLAG_hydrogen_filter)) { 148bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return AbortOptimization(kHydrogenFilter); 149bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 150bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 151bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Scope* scope = info()->scope(); 152bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (LUnallocated::TooManyParameters(scope->num_parameters())) { 153bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Crankshaft would require too many Lithium operands. 154bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return AbortOptimization(kTooManyParameters); 155bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 156bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 157bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (info()->is_osr() && 158bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch LUnallocated::TooManyParametersOrStackSlots(scope->num_parameters(), 159bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch scope->num_stack_slots())) { 160bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Crankshaft would require too many Lithium operands. 161bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return AbortOptimization(kTooManyParametersLocals); 162bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 163bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 164bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (IsGeneratorFunction(info()->shared_info()->kind())) { 165bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Crankshaft does not support generators. 166bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return AbortOptimization(kGenerator); 167bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 168bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 169bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (FLAG_trace_hydrogen) { 170bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch isolate()->GetHTracer()->TraceCompilation(info()); 171bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 172bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 173bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Optimization could have been disabled by the parser. Note that this check 174bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // is only needed because the Hydrogen graph builder is missing some bailouts. 175bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (info()->shared_info()->optimization_disabled()) { 176bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return AbortOptimization( 177bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch info()->shared_info()->disable_optimization_reason()); 178bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 179bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 180bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HOptimizedGraphBuilder* graph_builder = 181f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch (FLAG_hydrogen_track_positions || isolate()->is_profiling() || 182f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch FLAG_trace_ic) 183bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ? new (info()->zone()) HOptimizedGraphBuilderWithPositions(info()) 184f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch : new (info()->zone()) HOptimizedGraphBuilder(info(), false); 185bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 186bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Type-check the function. 187bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch AstTyper(info()->isolate(), info()->zone(), info()->closure(), 188bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch info()->scope(), info()->osr_ast_id(), info()->literal(), 189bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch graph_builder->bounds()) 190bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch .Run(); 191bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 192bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch graph_ = graph_builder->CreateGraph(); 193bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 194bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (isolate()->has_pending_exception()) { 195bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return FAILED; 196bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 197bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 198bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (graph_ == NULL) return FAILED; 199bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 200bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (info()->dependencies()->HasAborted()) { 201bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Dependency has changed during graph creation. Let's try again later. 202bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return RetryOptimization(kBailedOutDueToDependencyChange); 203bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 204bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 205bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return SUCCEEDED; 206bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 207bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochHCompilationJob::Status HCompilationJob::ExecuteJobImpl() { 209bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(graph_ != NULL); 210bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch BailoutReason bailout_reason = kNoReason; 211bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 212bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (graph_->Optimize(&bailout_reason)) { 213bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch chunk_ = LChunk::NewChunk(graph_); 214bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (chunk_ != NULL) return SUCCEEDED; 215bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (bailout_reason != kNoReason) { 216bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch info()->AbortOptimization(bailout_reason); 217bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 218bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 219bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return FAILED; 220bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 221bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochHCompilationJob::Status HCompilationJob::FinalizeJobImpl() { 223bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(chunk_ != NULL); 224bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(graph_ != NULL); 225bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch { 226bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Deferred handles reference objects that were accessible during 227bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // graph creation. To make sure that we don't encounter inconsistencies 228bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // between graph creation and code generation, we disallow accessing 229bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // objects through deferred handles during the latter, with exceptions. 230bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DisallowDeferredHandleDereference no_deferred_handle_deref; 231bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Handle<Code> optimized_code = chunk_->Codegen(); 232bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (optimized_code.is_null()) { 233bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (info()->bailout_reason() == kNoReason) { 234bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return AbortOptimization(kCodeGenerationFailed); 235bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 236bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return FAILED; 237bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 238bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch RegisterWeakObjectsInOptimizedCode(optimized_code); 239bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch info()->SetCode(optimized_code); 240bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 241bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Add to the weak list of optimized code objects. 242bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch info()->context()->native_context()->AddOptimizedCode(*info()->code()); 243bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return SUCCEEDED; 244bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 245bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHBasicBlock::HBasicBlock(HGraph* graph) 247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : block_id_(graph->GetNextBlockID()), 248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch graph_(graph), 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch phis_(4, graph->zone()), 250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch first_(NULL), 251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch last_(NULL), 252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch end_(NULL), 253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch loop_information_(NULL), 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch predecessors_(2, graph->zone()), 255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch dominator_(NULL), 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dominated_blocks_(4, graph->zone()), 257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch last_environment_(NULL), 258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch argument_count_(-1), 259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch first_instruction_index_(-1), 260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch last_instruction_index_(-1), 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deleted_phis_(4, graph->zone()), 2621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block parent_loop_header_(NULL), 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inlined_entry_block_(NULL), 2643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch is_inline_return_target_(false), 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_reachable_(true), 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dominates_loop_successors_(false), 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_osr_entry_(false), 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_ordered_(false) { } 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochIsolate* HBasicBlock::isolate() const { 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return graph_->isolate(); 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HBasicBlock::MarkUnreachable() { 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_reachable_ = false; 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 279b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::AttachLoopInformation() { 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsLoopHeader()); 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_information_ = new(zone()) HLoopInformation(this, zone()); 284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::DetachLoopInformation() { 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsLoopHeader()); 289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch loop_information_ = NULL; 290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::AddPhi(HPhi* phi) { 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsStartBlock()); 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch phis_.Add(phi, zone()); 296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phi->SetBlock(this); 297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::RemovePhi(HPhi* phi) { 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(phi->block() == this); 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(phis_.Contains(phi)); 3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch phi->Kill(); 304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phis_.RemoveElement(phi); 305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phi->SetBlock(NULL); 306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HBasicBlock::AddInstruction(HInstruction* instr, SourcePosition position) { 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsStartBlock() || !IsFinished()); 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!instr->IsLinked()); 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsFinished()); 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 314c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (position.IsKnown()) { 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->set_position(position); 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (first_ == NULL) { 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(last_environment() != NULL); 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!last_environment()->ast_id().IsNone()); 3208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HBlockEntry* entry = new(zone()) HBlockEntry(); 321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch entry->InitializeAsFirst(this); 322c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (position.IsKnown()) { 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry->set_position(position); 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!FLAG_hydrogen_track_positions || 326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier !graph()->info()->IsOptimizing() || instr->IsAbnormalExit()); 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 328e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch first_ = last_ = entry; 329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 330e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch instr->InsertAfter(last_); 331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHPhi* HBasicBlock::AddNewPhi(int merged_index) { 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (graph()->IsInsideNoSideEffectsScope()) { 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch merged_index = HPhi::kInvalidMergedIndex; 33744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhi* phi = new(zone()) HPhi(merged_index, zone()); 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddPhi(phi); 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return phi; 34144f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 34244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 34344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id, 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RemovableSimulate removable) { 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(HasEnvironment()); 347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HEnvironment* environment = last_environment(); 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(ast_id.IsNone() || 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_id == BailoutId::StubEntry() || 3503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch environment->closure()->shared()->VerifyBailoutId(ast_id)); 351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int push_count = environment->push_count(); 353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int pop_count = environment->pop_count(); 354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HSimulate* instr = 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new(zone()) HSimulate(ast_id, pop_count, zone(), removable); 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->set_closure(environment->closure()); 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Order of pushed values: newest (top of stack) first. This allows 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // HSimulate::MergeWith() to easily append additional pushed values 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // that are older (from further down the stack). 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < push_count; ++i) { 364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch instr->AddPushedValue(environment->ExpressionStackAt(i)); 365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (GrowableBitVector::Iterator it(environment->assigned_variables(), 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone()); 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !it.Done(); 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch it.Advance()) { 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = it.Current(); 371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch instr->AddAssignedValue(index, environment->Lookup(index)); 372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch environment->ClearHistory(); 374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return instr; 375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HBasicBlock::Finish(HControlInstruction* end, SourcePosition position) { 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsFinished()); 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(end, position); 381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch end_ = end; 3823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { 3833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch it.Current()->RegisterPredecessor(this); 384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HBasicBlock::Goto(HBasicBlock* block, SourcePosition position, 389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FunctionState* state, bool add_simulate) { 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool drop_extra = state != NULL && 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch state->inlining_kind() == NORMAL_RETURN; 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 39344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (block->IsInlineReturnTarget()) { 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = last_environment(); 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = env->arguments_environment()->parameter_count(); 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(new(zone()) 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLeaveInlined(state->entry(), argument_count), 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch position); 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); 40044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (add_simulate) AddNewSimulate(BailoutId::None(), position); 4038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HGoto* instr = new(zone()) HGoto(block); 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Finish(instr, position); 405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HBasicBlock::AddLeaveInlined(HValue* return_value, FunctionState* state, 409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SourcePosition position) { 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* target = state->function_return(); 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool drop_extra = state->inlining_kind() == NORMAL_RETURN; 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(target->IsInlineReturnTarget()); 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(return_value != NULL); 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = last_environment(); 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = env->arguments_environment()->parameter_count(); 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(new(zone()) HLeaveInlined(state->entry(), argument_count), 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch position); 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); 42044f0eee88ff00398ff7f715fab053374d808c90dSteve Block last_environment()->Push(return_value); 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddNewSimulate(BailoutId::None(), position); 4228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HGoto* instr = new(zone()) HGoto(target); 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Finish(instr, position); 42444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 42544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 42644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::SetInitialEnvironment(HEnvironment* env) { 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasEnvironment()); 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(first() == NULL); 430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UpdateEnvironment(env); 431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HBasicBlock::UpdateEnvironment(HEnvironment* env) { 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_environment_ = env; 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->update_maximum_environment_size(env->first_expression_index()); 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HBasicBlock::SetJoinId(BailoutId ast_id) { 441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int length = predecessors_.length(); 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(length > 0); 443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < length; i++) { 444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* predecessor = predecessors_[i]; 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(predecessor->end()->IsGoto()); 446e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HSimulate* simulate = HSimulate::cast(predecessor->end()->previous()); 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(i != 0 || 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (predecessor->last_environment()->closure().is_null() || 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch predecessor->last_environment()->closure()->shared() 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->VerifyBailoutId(ast_id))); 4513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch simulate->set_ast_id(ast_id); 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch predecessor->last_environment()->set_ast_id(ast_id); 453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochbool HBasicBlock::Dominates(HBasicBlock* other) const { 458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* current = other->dominator(); 459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (current != NULL) { 460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (current == this) return true; 461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch current = current->dominator(); 462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return false; 464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HBasicBlock::EqualToOrDominates(HBasicBlock* other) const { 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (this == other) return true; 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Dominates(other); 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 473589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochint HBasicBlock::LoopNestingDepth() const { 474589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch const HBasicBlock* current = this; 475589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch int result = (current->IsLoopHeader()) ? 1 : 0; 476589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch while (current->parent_loop_header() != NULL) { 477589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch current = current->parent_loop_header(); 478589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch result++; 479589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 480589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return result; 481589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 482589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 483589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::PostProcessLoopHeader(IterationStatement* stmt) { 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsLoopHeader()); 486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SetJoinId(stmt->EntryId()); 488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (predecessors()->length() == 1) { 489b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // This is a degenerated loop. 490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DetachLoopInformation(); 491b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return; 492b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 494b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Only the first entry into the loop is from outside the loop. All other 495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // entries must be back edges. 496b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 1; i < predecessors()->length(); ++i) { 497b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch loop_information()->RegisterBackEdge(predecessors()->at(i)); 498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 499b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 500b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 501b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HBasicBlock::MarkSuccEdgeUnreachable(int succ) { 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsFinished()); 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* succ_block = end()->SuccessorAt(succ); 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(succ_block->predecessors()->length() == 1); 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch succ_block->MarkUnreachable(); 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::RegisterPredecessor(HBasicBlock* pred) { 512257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (HasPredecessor()) { 513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Only loop header blocks can have a predecessor added after 514b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // instructions have been added to the block (they have phis for all 515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // values in the environment, these phis may be eliminated later). 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsLoopHeader() || first_ == NULL); 517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HEnvironment* incoming_env = pred->last_environment(); 518b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (IsLoopHeader()) { 519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(phis()->length(), incoming_env->length()); 520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < phis_.length(); ++i) { 521b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phis_[i]->AddInput(incoming_env->values()->at(i)); 522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch last_environment()->AddIncomingEdge(this, pred->last_environment()); 525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else if (!HasEnvironment() && !IsFinished()) { 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsLoopHeader()); 528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SetInitialEnvironment(pred->last_environment()->Copy()); 529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 530b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch predecessors_.Add(pred, zone()); 532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 533b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 534b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 535b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::AddDominatedBlock(HBasicBlock* block) { 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dominated_blocks_.Contains(block)); 537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Keep the list of dominated blocks sorted such that if there is two 538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // succeeding block in this list, the predecessor is before the successor. 539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int index = 0; 540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (index < dominated_blocks_.length() && 541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch dominated_blocks_[index]->block_id() < block->block_id()) { 542b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ++index; 543b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dominated_blocks_.InsertAt(index, block, zone()); 545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::AssignCommonDominator(HBasicBlock* other) { 549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (dominator_ == NULL) { 550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch dominator_ = other; 551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch other->AddDominatedBlock(this); 552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else if (other->dominator() != NULL) { 553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* first = dominator_; 554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* second = other; 555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (first != second) { 557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (first->block_id() > second->block_id()) { 558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch first = first->dominator(); 559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch second = second->dominator(); 561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(first != NULL && second != NULL); 563b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 564b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (dominator_ != first) { 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(dominator_->dominated_blocks_.Contains(this)); 567b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch dominator_->dominated_blocks_.RemoveElement(this); 568b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch dominator_ = first; 569b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch first->AddDominatedBlock(this); 570b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 571b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 572b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 573b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 574b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid HBasicBlock::AssignLoopSuccessorDominators() { 5763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Mark blocks that dominate all subsequent reachable blocks inside their 5773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // loop. Exploit the fact that blocks are sorted in reverse post order. When 5783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the loop is visited in increasing block id order, if the number of 5793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // non-loop-exiting successor edges at the dominator_candidate block doesn't 5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // exceed the number of previously encountered predecessor edges, there is no 5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // path from the loop header to any block with higher id that doesn't go 5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // through the dominator_candidate block. In this case, the 5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // dominator_candidate block is guaranteed to dominate all blocks reachable 5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // from it with higher ids. 5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HBasicBlock* last = loop_information()->GetLastBackEdge(); 5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int outstanding_successors = 1; // one edge from the pre-header 5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Header always dominates everything. 5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkAsLoopSuccessorDominator(); 5893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int j = block_id(); j <= last->block_id(); ++j) { 5903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HBasicBlock* dominator_candidate = graph_->blocks()->at(j); 5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (HPredecessorIterator it(dominator_candidate); !it.Done(); 5923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch it.Advance()) { 5933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HBasicBlock* predecessor = it.Current(); 5943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Don't count back edges. 5953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (predecessor->block_id() < dominator_candidate->block_id()) { 5963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch outstanding_successors--; 5973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If more successors than predecessors have been seen in the loop up to 6013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // now, it's not possible to guarantee that the current block dominates 6023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // all of the blocks with higher IDs. In this case, assume conservatively 6033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // that those paths through loop that don't go through the current block 6043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // contain all of the loop's dependencies. Also be careful to record 6053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // dominator information about the current loop that's being processed, 6063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // and not nested loops, which will be processed when 6073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // AssignLoopSuccessorDominators gets called on their header. 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(outstanding_successors >= 0); 6093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HBasicBlock* parent_loop_header = dominator_candidate->parent_loop_header(); 6103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (outstanding_successors == 0 && 6113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (parent_loop_header == this && !dominator_candidate->IsLoopHeader())) { 6123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch dominator_candidate->MarkAsLoopSuccessorDominator(); 6133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HControlInstruction* end = dominator_candidate->end(); 6153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { 6163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HBasicBlock* successor = it.Current(); 6173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Only count successors that remain inside the loop and don't loop back 6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // to a loop header. 6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (successor->block_id() > dominator_candidate->block_id() && 6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch successor->block_id() <= last->block_id()) { 6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Backwards edges must land on loop headers. 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(successor->block_id() > dominator_candidate->block_id() || 6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch successor->IsLoopHeader()); 6243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch outstanding_successors++; 6253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 631b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochint HBasicBlock::PredecessorIndexOf(HBasicBlock* predecessor) const { 632b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < predecessors_.length(); ++i) { 633b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (predecessors_[i] == predecessor) return i; 634b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 635b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UNREACHABLE(); 636b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return -1; 637b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 638b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 639b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 640b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 641b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HBasicBlock::Verify() { 642b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check that every block is finished. 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsFinished()); 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(block_id() >= 0); 64544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 64644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Check that the incoming edges are in edge split form. 64744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (predecessors_.length() > 1) { 64844f0eee88ff00398ff7f715fab053374d808c90dSteve Block for (int i = 0; i < predecessors_.length(); ++i) { 649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(predecessors_[i]->end()->SecondSuccessor() == NULL); 65044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 65144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 652b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 653b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 654b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 655b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 656b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HLoopInformation::RegisterBackEdge(HBasicBlock* block) { 657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch this->back_edges_.Add(block, block->zone()); 658b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AddBlock(block); 659b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 660b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 661b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 662b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHBasicBlock* HLoopInformation::GetLastBackEdge() const { 663b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int max_id = -1; 664b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* result = NULL; 665b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < back_edges_.length(); ++i) { 666b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* cur = back_edges_[i]; 667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (cur->block_id() > max_id) { 668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch max_id = cur->block_id(); 669b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result = cur; 670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return result; 673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 674b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 675b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HLoopInformation::AddBlock(HBasicBlock* block) { 677b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (block == loop_header()) return; 678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (block->parent_loop_header() == loop_header()) return; 679b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (block->parent_loop_header() != NULL) { 680b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AddBlock(block->parent_loop_header()); 681b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 682b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch block->set_parent_loop_header(loop_header()); 683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocks_.Add(block, block->zone()); 684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < block->predecessors()->length(); ++i) { 685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AddBlock(block->predecessors()->at(i)); 686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 687b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 688b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 689b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 690b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 691b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 692b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 693b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Checks reachability of the blocks in this graph and stores a bit in 694b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// the BitVector "reachable()" for every block that can be reached 695b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// from the start block of the graph. If "dont_visit" is non-null, the given 696b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// block is treated as if it would not be part of the graph. "visited_count()" 697b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// returns the number of reachable blocks. 698b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass ReachabilityAnalyzer BASE_EMBEDDED { 699b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 700b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ReachabilityAnalyzer(HBasicBlock* entry_block, 701b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int block_count, 702b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* dont_visit) 703b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : visited_count_(0), 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stack_(16, entry_block->zone()), 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reachable_(block_count, entry_block->zone()), 706b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch dont_visit_(dont_visit) { 707b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PushBlock(entry_block); 708b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Analyze(); 709b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 710b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 711b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int visited_count() const { return visited_count_; } 712b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const BitVector* reachable() const { return &reachable_; } 713b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 714b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 715b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void PushBlock(HBasicBlock* block) { 716b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (block != NULL && block != dont_visit_ && 717b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch !reachable_.Contains(block->block_id())) { 718b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reachable_.Add(block->block_id()); 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stack_.Add(block, block->zone()); 720b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch visited_count_++; 721b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 722b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 723b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 724b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Analyze() { 725b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (!stack_.is_empty()) { 726b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HControlInstruction* end = stack_.RemoveLast()->end(); 7273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { 7283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PushBlock(it.Current()); 7293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 730b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 731b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 732b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int visited_count_; 734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ZoneList<HBasicBlock*> stack_; 735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BitVector reachable_; 736b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* dont_visit_; 737b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 738b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid HGraph::Verify(bool do_full_verify) const { 741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RelocationLock relocation_lock(isolate()->heap()); 742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowHandleDereference allow_deref; 743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference allow_deferred_deref; 744b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < blocks_.length(); i++) { 745b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* block = blocks_.at(i); 746b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 747b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch block->Verify(); 748b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 749b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check that every block contains at least one node and that only the last 750b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // node is a control instruction. 751b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HInstruction* current = block->first(); 752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current != NULL && current->IsBlockEntry()); 753b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (current != NULL) { 754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((current->next() == NULL) == current->IsControlInstruction()); 755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current->block() == block); 756b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch current->Verify(); 757b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch current = current->next(); 758b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 759b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 760b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check that successors are correctly set. 761b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* first = block->end()->FirstSuccessor(); 762b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* second = block->end()->SecondSuccessor(); 763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(second == NULL || first != NULL); 764b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 765b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check that the predecessor array is correct. 766b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (first != NULL) { 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(first->predecessors()->Contains(block)); 768b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (second != NULL) { 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(second->predecessors()->Contains(block)); 770b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 771b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 772b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 773b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check that phis have correct arguments. 774b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int j = 0; j < block->phis()->length(); j++) { 775b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HPhi* phi = block->phis()->at(j); 776b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phi->Verify(); 777b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 778b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 779b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check that all join blocks have predecessors that end with an 780b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // unconditional goto and agree on their environment node id. 781b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (block->predecessors()->length() >= 2) { 782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId id = 783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block->predecessors()->first()->last_environment()->ast_id(); 784b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int k = 0; k < block->predecessors()->length(); k++) { 785b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* predecessor = block->predecessors()->at(k); 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(predecessor->end()->IsGoto() || 787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch predecessor->end()->IsDeoptimize()); 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(predecessor->last_environment()->ast_id() == id); 789b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 790b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 791b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 792b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 793b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check special property of first block to have no predecessors. 794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(blocks_.at(0)->predecessors()->is_empty()); 795b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (do_full_verify) { 7973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check that the graph is fully connected. 7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReachabilityAnalyzer analyzer(entry_block_, blocks_.length(), NULL); 799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(analyzer.visited_count() == blocks_.length()); 800b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check that entry block dominator is NULL. 802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(entry_block_->dominator() == NULL); 803b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check dominators. 8053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < blocks_.length(); ++i) { 8063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HBasicBlock* block = blocks_.at(i); 8073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (block->dominator() == NULL) { 8083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Only start block may have no dominator assigned to. 809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(i == 0); 8103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 8113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Assert that block is unreachable if dominator must not be visited. 8123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReachabilityAnalyzer dominator_analyzer(entry_block_, 8133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch blocks_.length(), 8143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch block->dominator()); 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dominator_analyzer.reachable()->Contains(block->block_id())); 8163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 817b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 818b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 819b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 820b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 821b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 822b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 823b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 824b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer, 825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t value) { 826b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!pointer->is_set()) { 827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Can't pass GetInvalidContext() to HConstant::New, because that will 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // recursively call GetConstant 829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant* constant = HConstant::New(isolate(), zone(), NULL, value); 830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant->InsertAfter(entry_block()->first()); 831b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch pointer->set(constant); 832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return constant; 833b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReinsertConstantIfNecessary(pointer->get()); 835b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 836b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 837b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHConstant* HGraph::ReinsertConstantIfNecessary(HConstant* constant) { 839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!constant->IsLinked()) { 840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The constant was removed from the graph. Reinsert. 841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant->ClearFlag(HValue::kIsDead); 842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant->InsertAfter(entry_block()->first()); 843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return constant; 845b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 846b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 847b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHConstant* HGraph::GetConstant0() { 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetConstant(&constant_0_, 0); 850b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 851b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 852b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHConstant* HGraph::GetConstant1() { 854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetConstant(&constant_1_, 1); 855b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 856b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 857b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHConstant* HGraph::GetConstantMinus1() { 859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetConstant(&constant_minus1_, -1); 860b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 861b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHConstant* HGraph::GetConstantBool(bool value) { 864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return value ? GetConstantTrue() : GetConstantFalse(); 865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 8673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#define DEFINE_GET_CONSTANT(Name, name, constant, type, htype, boolean_value, \ 8683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch undetectable) \ 8693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HConstant* HGraph::GetConstant##Name() { \ 8703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (!constant_##name##_.is_set()) { \ 8713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HConstant* constant = new (zone()) HConstant( \ 8723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Unique<Object>::CreateImmovable(isolate()->factory()->constant()), \ 8733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Unique<Map>::CreateImmovable(isolate()->factory()->type##_map()), \ 8743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch false, Representation::Tagged(), htype, true, boolean_value, \ 8753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch undetectable, ODDBALL_TYPE); \ 8763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch constant->InsertAfter(entry_block()->first()); \ 8773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch constant_##name##_.set(constant); \ 8783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } \ 8793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return ReinsertConstantIfNecessary(constant_##name##_.get()); \ 8803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 8813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 8823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochDEFINE_GET_CONSTANT(Undefined, undefined, undefined_value, undefined, 8833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HType::Undefined(), false, true) 8843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochDEFINE_GET_CONSTANT(True, true, true_value, boolean, HType::Boolean(), true, 8853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch false) 8863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochDEFINE_GET_CONSTANT(False, false, false_value, boolean, HType::Boolean(), false, 8873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch false) 8883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochDEFINE_GET_CONSTANT(Hole, the_hole, the_hole_value, the_hole, HType::None(), 8893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch false, false) 8903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochDEFINE_GET_CONSTANT(Null, null, null_value, null, HType::Null(), false, true) 8913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochDEFINE_GET_CONSTANT(OptimizedOut, optimized_out, optimized_out, optimized_out, 8923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HType::None(), false, false) 893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DEFINE_GET_CONSTANT 895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DEFINE_IS_CONSTANT(Name, name) \ 897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HGraph::IsConstant##Name(HConstant* constant) { \ 898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return constant_##name##_.is_set() && constant == constant_##name##_.get(); \ 899b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_IS_CONSTANT(Undefined, undefined) 901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_IS_CONSTANT(0, 0) 902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_IS_CONSTANT(1, 1) 903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_IS_CONSTANT(Minus1, minus1) 904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_IS_CONSTANT(True, true) 905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_IS_CONSTANT(False, false) 906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_IS_CONSTANT(Hole, the_hole) 907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_IS_CONSTANT(Null, null) 908b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DEFINE_IS_CONSTANT 910b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHConstant* HGraph::GetInvalidContext() { 913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetConstant(&constant_invalid_context_, 0xFFFFC0C7); 914b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 915b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 916b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HGraph::IsStandardConstant(HConstant* constant) { 918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstantUndefined(constant)) return true; 919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstant0(constant)) return true; 920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstant1(constant)) return true; 921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstantMinus1(constant)) return true; 922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstantTrue(constant)) return true; 923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstantFalse(constant)) return true; 924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstantHole(constant)) return true; 925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstantNull(constant)) return true; 926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 927b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 928b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 929b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraphBuilder::IfBuilder::IfBuilder() : builder_(NULL), needs_compare_(true) {} 931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder) 934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : needs_compare_(true) { 935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Initialize(builder); 936b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 937b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 938b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, 940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIfContinuation* continuation) 941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : needs_compare_(false), first_true_block_(NULL), first_false_block_(NULL) { 942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeDontCreateBlocks(builder); 943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continuation->Continue(&first_true_block_, &first_false_block_); 944b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 945b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 946b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::InitializeDontCreateBlocks( 948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HGraphBuilder* builder) { 949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_ = builder; 950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch finished_ = false; 951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_then_ = false; 952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_else_ = false; 953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_else_if_ = false; 954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_and_ = false; 955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_or_ = false; 956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch captured_ = false; 957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pending_merge_block_ = false; 958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch split_edge_merge_block_ = NULL; 959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch merge_at_join_blocks_ = NULL; 960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch normal_merge_at_join_block_count_ = 0; 961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deopt_merge_at_join_block_count_ = 0; 962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 963b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 964b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::Initialize(HGraphBuilder* builder) { 966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeDontCreateBlocks(builder); 967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = builder->environment(); 968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_true_block_ = builder->CreateBasicBlock(env->Copy()); 969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_false_block_ = builder->CreateBasicBlock(env->Copy()); 970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 971b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 972b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHControlInstruction* HGraphBuilder::IfBuilder::AddCompare( 974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HControlInstruction* compare) { 975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(did_then_ == did_else_); 976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (did_else_) { 977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle if-then-elseif 978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_else_if_ = true; 979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_else_ = false; 980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_then_ = false; 981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_and_ = false; 982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_or_ = false; 983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pending_merge_block_ = false; 984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch split_edge_merge_block_ = NULL; 985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = builder()->environment(); 986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_true_block_ = builder()->CreateBasicBlock(env->Copy()); 987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_false_block_ = builder()->CreateBasicBlock(env->Copy()); 988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (split_edge_merge_block_ != NULL) { 990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = first_false_block_->last_environment(); 991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* split_edge = builder()->CreateBasicBlock(env->Copy()); 992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (did_or_) { 993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare->SetSuccessorAt(0, split_edge); 994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare->SetSuccessorAt(1, first_false_block_); 995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare->SetSuccessorAt(0, first_true_block_); 997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare->SetSuccessorAt(1, split_edge); 998b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->GotoNoSimulate(split_edge, split_edge_merge_block_); 1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare->SetSuccessorAt(0, first_true_block_); 1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare->SetSuccessorAt(1, first_false_block_); 1003b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->FinishCurrentBlock(compare); 1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch needs_compare_ = false; 1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return compare; 1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1009b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::Or() { 1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!needs_compare_); 1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!did_and_); 1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_or_ = true; 1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = first_false_block_->last_environment(); 1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (split_edge_merge_block_ == NULL) { 1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch split_edge_merge_block_ = builder()->CreateBasicBlock(env->Copy()); 1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->GotoNoSimulate(first_true_block_, split_edge_merge_block_); 1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_true_block_ = split_edge_merge_block_; 1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->set_current_block(first_false_block_); 1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_false_block_ = builder()->CreateBasicBlock(env->Copy()); 1022b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1023b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1024b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::And() { 1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!needs_compare_); 1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!did_or_); 1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_and_ = true; 1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = first_false_block_->last_environment(); 1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (split_edge_merge_block_ == NULL) { 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch split_edge_merge_block_ = builder()->CreateBasicBlock(env->Copy()); 1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->GotoNoSimulate(first_false_block_, split_edge_merge_block_); 1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_false_block_ = split_edge_merge_block_; 1034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->set_current_block(first_true_block_); 1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_true_block_ = builder()->CreateBasicBlock(env->Copy()); 1037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1038b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1039b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::CaptureContinuation( 1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIfContinuation* continuation) { 1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!did_else_if_); 1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!finished_); 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!captured_); 1045b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* true_block = NULL; 1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* false_block = NULL; 1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Finish(&true_block, &false_block); 1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(true_block != NULL); 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(false_block != NULL); 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continuation->Capture(true_block, false_block); 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch captured_ = true; 1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->set_current_block(NULL); 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch End(); 1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1056b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) { 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!did_else_if_); 1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!finished_); 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!captured_); 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* true_block = NULL; 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* false_block = NULL; 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Finish(&true_block, &false_block); 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch merge_at_join_blocks_ = NULL; 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (true_block != NULL && !true_block->IsFinished()) { 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(continuation->IsTrueReachable()); 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->GotoNoSimulate(true_block, continuation->true_branch()); 1069b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (false_block != NULL && !false_block->IsFinished()) { 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(continuation->IsFalseReachable()); 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->GotoNoSimulate(false_block, continuation->false_branch()); 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch captured_ = true; 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch End(); 1076b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1077b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1078b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::Then() { 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!captured_); 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!finished_); 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_then_ = true; 1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (needs_compare_) { 1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle if's without any expressions, they jump directly to the "else" 1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // branch. However, we must pretend that the "then" branch is reachable, 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // so that the graph builder visits it and sees any live range extending 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // constructs within it. 1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* constant_false = builder()->graph()->GetConstantFalse(); 1089c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ToBooleanHints boolean_type = ToBooleanHint::kBoolean; 1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBranch* branch = builder()->New<HBranch>( 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_false, boolean_type, first_true_block_, first_false_block_); 1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->FinishCurrentBlock(branch); 1093b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->set_current_block(first_true_block_); 1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pending_merge_block_ = true; 1096b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1097b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1098b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::Else() { 1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(did_then_); 1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!captured_); 1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!finished_); 1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddMergeAtJoinBlock(false); 1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->set_current_block(first_false_block_); 1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pending_merge_block_ = true; 1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch did_else_ = true; 1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid HGraphBuilder::IfBuilder::Deopt(DeoptimizeReason reason) { 1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(did_then_); 1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->Add<HDeoptimize>(reason, Deoptimizer::EAGER); 1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddMergeAtJoinBlock(true); 1113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::Return(HValue* value) { 1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* parameter_count = builder()->graph()->GetConstantMinus1(); 1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->FinishExitCurrentBlock( 1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->New<HReturn>(value, parameter_count)); 1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddMergeAtJoinBlock(false); 1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::AddMergeAtJoinBlock(bool deopt) { 1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!pending_merge_block_) return; 1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block = builder()->current_block(); 1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(block == NULL || !block->IsFinished()); 1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MergeAtJoinBlock* record = new (builder()->zone()) 1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MergeAtJoinBlock(block, deopt, merge_at_join_blocks_); 1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch merge_at_join_blocks_ = record; 1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block != NULL) { 1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(block->end() == NULL); 1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (deopt) { 1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch normal_merge_at_join_block_count_++; 1135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deopt_merge_at_join_block_count_++; 1137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->set_current_block(NULL); 1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pending_merge_block_ = false; 114169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 11423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::Finish() { 1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!finished_); 1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!did_then_) { 1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Then(); 11483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddMergeAtJoinBlock(false); 1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!did_else_) { 1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Else(); 1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddMergeAtJoinBlock(false); 1153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch finished_ = true; 1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::Finish(HBasicBlock** then_continuation, 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock** else_continuation) { 1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Finish(); 1161257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MergeAtJoinBlock* else_record = merge_at_join_blocks_; 1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (else_continuation != NULL) { 1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *else_continuation = else_record->block_; 116544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MergeAtJoinBlock* then_record = else_record->next_; 1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (then_continuation != NULL) { 1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *then_continuation = then_record->block_; 1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(then_record->next_ == NULL); 117144f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 117244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 117344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HGraphBuilder::IfBuilder::EndUnreachable() { 1175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (captured_) return; 1176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Finish(); 1177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder()->set_current_block(nullptr); 1178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::IfBuilder::End() { 1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (captured_) return; 1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Finish(); 118444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int total_merged_blocks = normal_merge_at_join_block_count_ + 1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deopt_merge_at_join_block_count_; 1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(total_merged_blocks >= 1); 1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* merge_block = 1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total_merged_blocks == 1 ? NULL : builder()->graph()->CreateBasicBlock(); 119044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Merge non-deopt blocks first to ensure environment has right size for 1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // padding. 1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MergeAtJoinBlock* current = merge_at_join_blocks_; 1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (current != NULL) { 1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!current->deopt_ && current->block_ != NULL) { 1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there is only one block that makes it through to the end of the 1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // if, then just set it as the current block and continue rather then 1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // creating an unnecessary merge block. 1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (total_merged_blocks == 1) { 1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->set_current_block(current->block_); 1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 120244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->GotoNoSimulate(current->block_, merge_block); 120444f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current = current->next_; 120644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 120744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Merge deopt blocks, padding when necessary. 1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current = merge_at_join_blocks_; 1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (current != NULL) { 1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current->deopt_ && current->block_ != NULL) { 1212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch current->block_->FinishExit( 1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HAbnormalExit::New(builder()->isolate(), builder()->zone(), NULL), 1214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SourcePosition::Unknown()); 1215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current = current->next_; 1217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder()->set_current_block(merge_block); 1219b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder) { 1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Initialize(builder, NULL, kWhileTrue, NULL); 1224257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1225257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1226257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, HValue* context, 1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder::Direction direction) { 1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Initialize(builder, context, direction, builder->graph()->GetConstant1()); 12303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 12313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, HValue* context, 1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder::Direction direction, 1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* increment_amount) { 1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Initialize(builder, context, direction, increment_amount); 1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch increment_amount_ = increment_amount; 12383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 12393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::LoopBuilder::Initialize(HGraphBuilder* builder, 1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context, 1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Direction direction, 1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* increment_amount) { 1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_ = builder; 1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context_ = context; 1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch direction_ = direction; 1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch increment_amount_ = increment_amount; 1249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch finished_ = false; 1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch header_block_ = builder->CreateLoopHeaderBlock(); 1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_block_ = NULL; 1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exit_block_ = NULL; 1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exit_trampoline_block_ = NULL; 1255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1256b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::LoopBuilder::BeginBody( 1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* initial, 1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* terminating, 1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::Value token) { 1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(direction_ != kWhileTrue); 1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = builder_->environment(); 1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch phi_ = header_block_->AddNewPhi(env->values()->length()); 1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch phi_->AddInput(initial); 1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Push(initial); 1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->GotoNoSimulate(header_block_); 1268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* body_env = env->Copy(); 1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* exit_env = env->Copy(); 1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remove the phi from the expression stack 1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_env->Pop(); 1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exit_env->Pop(); 1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_block_ = builder_->CreateBasicBlock(body_env); 1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exit_block_ = builder_->CreateBasicBlock(exit_env); 1276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->set_current_block(header_block_); 1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Pop(); 1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->FinishCurrentBlock(builder_->New<HCompareNumericAndBranch>( 1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch phi_, terminating, token, body_block_, exit_block_)); 1281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->set_current_block(body_block_); 1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (direction_ == kPreIncrement || direction_ == kPreDecrement) { 1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate = builder_->isolate(); 1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* one = builder_->graph()->GetConstant1(); 1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (direction_ == kPreIncrement) { 1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch increment_ = HAdd::New(isolate, zone(), context_, phi_, one); 1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch increment_ = HSub::New(isolate, zone(), context_, phi_, one); 1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch increment_->ClearFlag(HValue::kCanOverflow); 1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->AddInstruction(increment_); 1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return increment_; 1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return phi_; 1296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::LoopBuilder::BeginBody(int drop_count) { 1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(direction_ == kWhileTrue); 1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = builder_->environment(); 1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->GotoNoSimulate(header_block_); 1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->set_current_block(header_block_); 1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Drop(drop_count); 1306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::LoopBuilder::Break() { 1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (exit_trampoline_block_ == NULL) { 1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Its the first time we saw a break. 1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (direction_ == kWhileTrue) { 1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = builder_->environment()->Copy(); 1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exit_trampoline_block_ = builder_->CreateBasicBlock(env); 1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = exit_block_->last_environment()->Copy(); 1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exit_trampoline_block_ = builder_->CreateBasicBlock(env); 1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->GotoNoSimulate(exit_block_, exit_trampoline_block_); 1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->GotoNoSimulate(exit_trampoline_block_); 1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->set_current_block(NULL); 1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::LoopBuilder::EndBody() { 1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!finished_); 1329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (direction_ == kPostIncrement || direction_ == kPostDecrement) { 1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate = builder_->isolate(); 1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (direction_ == kPostIncrement) { 1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch increment_ = 1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HAdd::New(isolate, zone(), context_, phi_, increment_amount_); 1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch increment_ = 1337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HSub::New(isolate, zone(), context_, phi_, increment_amount_); 1338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch increment_->ClearFlag(HValue::kCanOverflow); 1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->AddInstruction(increment_); 1341b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (direction_ != kWhileTrue) { 1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Push the new increment value on the expression stack to merge into 1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the phi. 1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->environment()->Push(increment_); 1347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* last_block = builder_->current_block(); 1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->GotoNoSimulate(last_block, header_block_); 1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch header_block_->loop_information()->RegisterBackEdge(last_block); 1351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (exit_trampoline_block_ != NULL) { 1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->set_current_block(exit_trampoline_block_); 1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder_->set_current_block(exit_block_); 1356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch finished_ = true; 1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHGraph* HGraphBuilder::CreateGraph() { 1362f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(!FLAG_minimal); 1363109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch graph_ = new (zone()) HGraph(info_, descriptor_); 1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_); 1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompilationPhase phase("H_Block building", info_); 1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(graph()->entry_block()); 1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!BuildGraph()) return NULL; 1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->FinalizeUniqueness(); 1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return graph_; 1370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { 1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 1375c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK(!FLAG_hydrogen_track_positions || position_.IsKnown() || 1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !info_->IsOptimizing()); 1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_block()->AddInstruction(instr, source_position()); 1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (graph()->IsInsideNoSideEffectsScope()) { 1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetFlag(HValue::kHasNoObservableSideEffects); 1380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return instr; 1382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) { 1386c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK(!FLAG_hydrogen_track_positions || !info_->IsOptimizing() || 1387c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch position_.IsKnown()); 1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_block()->Finish(last, source_position()); 1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (last->IsReturn() || last->IsAbnormalExit()) { 1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) { 1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!FLAG_hydrogen_track_positions || !info_->IsOptimizing() || 1397c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch position_.IsKnown()); 1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_block()->FinishExit(instruction, source_position()); 1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instruction->IsReturn() || instruction->IsAbnormalExit()) { 1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 1401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { 1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_native_code_counters && counter->Enabled()) { 1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* reference = Add<HConstant>(ExternalReference(counter)); 1408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* old_value = 1409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HLoadNamedField>(reference, nullptr, HObjectAccess::ForCounter()); 1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1()); 1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow 1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), 1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_value, STORE_TO_INITIALIZED_ENTRY); 1414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::AddSimulate(BailoutId id, 1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RemovableSimulate removable) { 1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!graph()->IsInsideNoSideEffectsScope()); 1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_block()->AddNewSimulate(id, source_position(), removable); 1423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1424b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { 1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* b = graph()->CreateBasicBlock(); 1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch b->SetInitialEnvironment(env); 1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return b; 1430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { 1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* header = graph()->CreateBasicBlock(); 1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); 1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch header->SetInitialEnvironment(entry_env); 1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch header->AttachLoopInformation(); 1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return header; 1439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildGetElementsKind(HValue* object) { 1443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* map = Add<HLoadNamedField>(object, nullptr, HObjectAccess::ForMap()); 1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* bit_field2 = 1446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField2()); 1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildDecodeField<Map::ElementsKindBits>(bit_field2); 1448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1451109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochHValue* HGraphBuilder::BuildEnumLength(HValue* map) { 1452109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch NoObservableSideEffectsScope scope(this); 1453109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HValue* bit_field3 = 1454109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField3()); 1455109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return BuildDecodeField<Map::EnumLengthBits>(bit_field3); 1456109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1457109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1458109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { 1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (obj->type().IsHeapObject()) return obj; 1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HCheckHeapObject>(obj); 1462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1464f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid HGraphBuilder::FinishExitWithHardDeoptimization(DeoptimizeReason reason) { 1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HDeoptimize>(reason, Deoptimizer::EAGER); 1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishExitCurrentBlock(New<HAbnormalExit>()); 1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildCheckString(HValue* string) { 1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!string->type().IsString()) { 1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!string->IsConstant() || 1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !HConstant::cast(string)->HasStringValue()); 1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(string); 1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HCheckInstanceType>(string, HCheckInstanceType::IS_STRING); 1476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return string; 1478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 14803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochHValue* HGraphBuilder::BuildWrapReceiver(HValue* object, HValue* checked) { 1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object->type().IsJSObject()) return object; 14823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HValue* function = checked->ActualValue(); 1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function->IsConstant() && 1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(function)->handle(isolate())->IsJSFunction()) { 1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> f = Handle<JSFunction>::cast( 1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(function)->handle(isolate())); 1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedFunctionInfo* shared = f->shared(); 1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_strict(shared->language_mode()) || shared->native()) return object; 1489b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 14903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return Add<HWrapReceiver>(object, checked); 1491b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1492b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHValue* HGraphBuilder::BuildCheckAndGrowElementsCapacity( 1495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* object, HValue* elements, ElementsKind kind, HValue* length, 1496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* capacity, HValue* key) { 1497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap)); 1498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* max_capacity = AddUncasted<HAdd>(capacity, max_gap); 1499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HBoundsCheck>(key, max_capacity); 1500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* new_capacity = BuildNewElementsCapacity(key); 1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* new_elements = BuildGrowElementsCapacity(object, elements, kind, kind, 1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch length, new_capacity); 1504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return new_elements; 1505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildCheckForCapacityGrow( 1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object, 1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements, 1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length, 1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key, 1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_js_array, 1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessType access_type) { 1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder length_checker(this); 1517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ; 1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.If<HCompareNumericAndBranch>(key, length, token); 1520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.Then(); 1522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* current_capacity = AddLoadFixedArrayLength(elements); 1524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (top_info()->IsStub()) { 1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IfBuilder capacity_checker(this); 1527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity, 1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Token::GTE); 1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch capacity_checker.Then(); 1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* new_elements = BuildCheckAndGrowElementsCapacity( 1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object, elements, kind, length, current_capacity, key); 1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Push(new_elements); 1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch capacity_checker.Else(); 1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Push(elements); 1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch capacity_checker.End(); 1536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* result = Add<HMaybeGrowElements>( 1538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object, elements, key, current_capacity, is_js_array, kind); 1539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Push(result); 1540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_js_array) { 1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_length = AddUncasted<HAdd>(key, graph_->GetConstant1()); 1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_length->ClearFlag(HValue::kCanOverflow); 1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind), 1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_length); 1548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == STORE && kind == FAST_SMI_ELEMENTS) { 1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_elements = environment()->Top(); 1552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Write zero to ensure that the new element is initialized with some smi. 1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreKeyed>(checked_elements, key, graph()->GetConstant0(), nullptr, 1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kind); 1556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.Else(); 1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HBoundsCheck>(key, length); 1560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(elements); 1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.End(); 1563b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return environment()->Pop(); 1565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1567b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, 1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements, 1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length) { 1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate()->factory(); 1573b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder cow_checker(this); 1575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cow_checker.If<HCompareMap>(elements, factory->fixed_cow_array_map()); 1577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cow_checker.Then(); 1578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* capacity = AddLoadFixedArrayLength(elements); 1580b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_elements = BuildGrowElementsCapacity(object, elements, kind, 1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind, length, capacity); 1583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(new_elements); 1585257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cow_checker.Else(); 1587257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(elements); 1589257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cow_checker.End(); 1591257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return environment()->Pop(); 1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1594257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildElementIndexHash(HValue* index) { 1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t seed_value = static_cast<uint32_t>(isolate()->heap()->HashSeed()); 1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* seed = Add<HConstant>(seed_value); 1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, index, seed); 1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // hash = ~hash + (hash << 15); 1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* shifted_hash = AddUncasted<HShl>(hash, Add<HConstant>(15)); 1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* not_hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash, 1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstantMinus1()); 1604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hash = AddUncasted<HAdd>(shifted_hash, not_hash); 1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // hash = hash ^ (hash >> 12); 1607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(12)); 1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); 1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // hash = hash + (hash << 2); 1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shifted_hash = AddUncasted<HShl>(hash, Add<HConstant>(2)); 1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hash = AddUncasted<HAdd>(hash, shifted_hash); 1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // hash = hash ^ (hash >> 4); 1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(4)); 1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); 1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // hash = hash * 2057; 1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hash = AddUncasted<HMul>(hash, Add<HConstant>(2057)); 1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hash->ClearFlag(HValue::kCanOverflow); 1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // hash = hash ^ (hash >> 16); 1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(16)); 1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); 1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1627109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochHValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver, 1628109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HValue* elements, 1629109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HValue* key, 1630109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HValue* hash) { 1631958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* capacity = 1632958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HLoadKeyed>(elements, Add<HConstant>(NameDictionary::kCapacityIndex), 1633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch nullptr, nullptr, FAST_ELEMENTS); 1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1()); 1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mask->ChangeRepresentation(Representation::Integer32()); 1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mask->ClearFlag(HValue::kCanOverflow); 1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* entry = hash; 1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* count = graph()->GetConstant1(); 1641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(entry); 1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(count); 1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIfContinuation return_or_loop_continuation(graph()->CreateBasicBlock(), 1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->CreateBasicBlock()); 1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIfContinuation found_key_match_continuation(graph()->CreateBasicBlock(), 1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->CreateBasicBlock()); 1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder probe_loop(this); 1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch probe_loop.BeginBody(2); // Drop entry, count from last environment to 1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // appease live range building without simulates. 1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch count = Pop(); 1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry = Pop(); 1654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry = AddUncasted<HBitwise>(Token::BIT_AND, entry, mask); 1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int entry_size = SeededNumberDictionary::kEntrySize; 1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* base_index = AddUncasted<HMul>(entry, Add<HConstant>(entry_size)); 1657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base_index->ClearFlag(HValue::kCanOverflow); 1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int start_offset = SeededNumberDictionary::kElementsStartIndex; 1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key_index = 1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset)); 1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key_index->ClearFlag(HValue::kCanOverflow); 1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* candidate_key = 1664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HLoadKeyed>(elements, key_index, nullptr, nullptr, FAST_ELEMENTS); 1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_undefined(this); 1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_undefined.If<HCompareObjectEqAndBranch>(candidate_key, 1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstantUndefined()); 1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_undefined.Then(); 1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // element == undefined means "not found". Call the runtime. 1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(jkummerow): walk the prototype chain instead. 1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(receiver, key); 1673109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kKeyedGetProperty), 1674109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 2)); 1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_undefined.Else(); 1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_match(this); 1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_match.If<HCompareObjectEqAndBranch>(candidate_key, key); 1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_match.Then(); 1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_match.Else(); 1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update non-internalized string in the dictionary with internalized key? 1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_update_with_internalized(this); 1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* smi_check = 1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.IfNot<HIsSmiAndBranch>(candidate_key); 1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.And(); 1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* map = AddLoadMap(candidate_key, smi_check); 1689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* instance_type = 1690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapInstanceType()); 1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* not_internalized_bit = AddUncasted<HBitwise>( 1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, instance_type, 1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int>(kIsNotInternalizedMask))); 1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.If<HCompareNumericAndBranch>( 1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch not_internalized_bit, graph()->GetConstant0(), Token::NE); 1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.And(); 1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.IfNot<HCompareObjectEqAndBranch>( 1698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch candidate_key, graph()->GetConstantHole()); 1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.AndIf<HStringCompareAndBranch>(candidate_key, 1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key, Token::EQ); 1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.Then(); 1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Replace a key that is a non-internalized string by the equivalent 1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // internalized string for faster further lookups. 1704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreKeyed>(elements, key_index, key, nullptr, FAST_ELEMENTS); 1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.Else(); 1706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_update_with_internalized.JoinContinuation(&found_key_match_continuation); 1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_match.JoinContinuation(&found_key_match_continuation); 1709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder found_key_match(this, &found_key_match_continuation); 1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch found_key_match.Then(); 1712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Key at current probe matches. Relevant bits in the |details| field must 1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // be zero, otherwise the dictionary element requires special handling. 1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* details_index = 1715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 2)); 1716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch details_index->ClearFlag(HValue::kCanOverflow); 1717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* details = Add<HLoadKeyed>(elements, details_index, nullptr, nullptr, 1718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FAST_ELEMENTS); 171962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int details_mask = PropertyDetails::KindField::kMask; 1720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch details = AddUncasted<HBitwise>(Token::BIT_AND, details, 1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(details_mask)); 1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder details_compare(this); 172362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch details_compare.If<HCompareNumericAndBranch>(details, New<HConstant>(kData), 172462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Token::EQ); 1725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch details_compare.Then(); 1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result_index = 1727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 1)); 1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result_index->ClearFlag(HValue::kCanOverflow); 1729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(Add<HLoadKeyed>(elements, result_index, nullptr, nullptr, 1730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FAST_ELEMENTS)); 1731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch details_compare.Else(); 1732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(receiver, key); 1733109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kKeyedGetProperty), 1734109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 2)); 1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch details_compare.End(); 1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch found_key_match.Else(); 1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch found_key_match.JoinContinuation(&return_or_loop_continuation); 1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_undefined.JoinContinuation(&return_or_loop_continuation); 1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder return_or_loop(this, &return_or_loop_continuation); 1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return_or_loop.Then(); 1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch probe_loop.Break(); 1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return_or_loop.Else(); 1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry = AddUncasted<HAdd>(entry, count); 1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry->ClearFlag(HValue::kCanOverflow); 1749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch count = AddUncasted<HAdd>(count, graph()->GetConstant1()); 1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch count->ClearFlag(HValue::kCanOverflow); 1751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(entry); 1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(count); 1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch probe_loop.EndBody(); 1755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return_or_loop.End(); 1757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Pop(); 1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHValue* HGraphBuilder::BuildCreateIterResultObject(HValue* value, 1762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* done) { 1763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NoObservableSideEffectsScope scope(this); 1764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allocate the JSIteratorResult object. 1766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* result = 1767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HAllocate>(Add<HConstant>(JSIteratorResult::kSize), HType::JSObject(), 1768bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NOT_TENURED, JS_OBJECT_TYPE, graph()->GetConstant0()); 1769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Initialize the JSIteratorResult object. 1771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* native_context = BuildGetNativeContext(); 1772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* map = Add<HLoadNamedField>( 1773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch native_context, nullptr, 1774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess::ForContextSlot(Context::ITERATOR_RESULT_MAP_INDEX)); 1775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForMap(), map); 1776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* empty_fixed_array = Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex); 1777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForPropertiesPointer(), 1778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch empty_fixed_array); 1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForElementsPointer(), 1780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch empty_fixed_array); 1781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForObservableJSObjectOffset( 1782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSIteratorResult::kValueOffset), 1783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value); 1784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForObservableJSObjectOffset( 1785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSIteratorResult::kDoneOffset), 1786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch done); 1787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); 1788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result; 1789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1792f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHValue* HGraphBuilder::BuildNumberToString(HValue* object, AstType* type) { 1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope scope(this); 1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert constant numbers at compile time. 1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object->IsConstant() && HConstant::cast(object)->HasNumberValue()) { 1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> number = HConstant::cast(object)->handle(isolate()); 1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> result = isolate()->factory()->NumberToString(number); 1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HConstant>(result); 1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create a joinable continuation. 1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIfContinuation found(graph()->CreateBasicBlock(), 1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->CreateBasicBlock()); 1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the number string cache. 1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* number_string_cache = 1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadRoot>(Heap::kNumberStringCacheRootIndex); 1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make the hash mask from the length of the number string cache. It 1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // contains two elements (number and string) for each cache entry. 1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* mask = AddLoadFixedArrayLength(number_string_cache); 1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mask->set_type(HType::Smi()); 1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mask = AddUncasted<HSar>(mask, graph()->GetConstant1()); 1815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mask = AddUncasted<HSub>(mask, graph()->GetConstant1()); 1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check whether object is a smi. 1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_objectissmi(this); 1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectissmi.If<HIsSmiAndBranch>(object); 1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectissmi.Then(); 1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute hash for smi similar to smi_get_hash(). 1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* hash = AddUncasted<HBitwise>(Token::BIT_AND, object, mask); 1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the key. 1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); 1827958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, nullptr, 1828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch nullptr, FAST_ELEMENTS, ALLOW_RETURN_HOLE); 1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if object == key. 1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_objectiskey(this); 1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectiskey.If<HCompareObjectEqAndBranch>(object, key); 1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectiskey.Then(); 1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make the key_index available. 1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(key_index); 1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectiskey.JoinContinuation(&found); 1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectissmi.Else(); 1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1842f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (type->Is(AstType::SignedSmall())) { 1843f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if_objectissmi.Deopt(DeoptimizeReason::kExpectedSmi); 1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if the object is a heap number. 1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_objectisnumber(this); 1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* objectisnumber = if_objectisnumber.If<HCompareMap>( 1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, isolate()->factory()->heap_number_map()); 1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectisnumber.Then(); 1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute hash for heap number similar to double_get_hash(). 1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* low = Add<HLoadNamedField>( 1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, objectisnumber, 1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForHeapNumberValueLowestBits()); 1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* high = Add<HLoadNamedField>( 1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, objectisnumber, 1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForHeapNumberValueHighestBits()); 1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, low, high); 1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hash = AddUncasted<HBitwise>(Token::BIT_AND, hash, mask); 1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the key. 1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); 1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* key = 1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HLoadKeyed>(number_string_cache, key_index, nullptr, nullptr, 1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FAST_ELEMENTS, ALLOW_RETURN_HOLE); 1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if the key is a heap number and compare it with the object. 1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_keyisnotsmi(this); 1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* keyisnotsmi = if_keyisnotsmi.IfNot<HIsSmiAndBranch>(key); 1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_keyisnotsmi.Then(); 1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_keyisheapnumber(this); 1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_keyisheapnumber.If<HCompareMap>( 1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key, isolate()->factory()->heap_number_map()); 1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_keyisheapnumber.Then(); 1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if values of key and object match. 1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_keyeqobject(this); 1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_keyeqobject.If<HCompareNumericAndBranch>( 1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadNamedField>(key, keyisnotsmi, 1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForHeapNumberValue()), 1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HLoadNamedField>(object, objectisnumber, 1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForHeapNumberValue()), 1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::EQ); 1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_keyeqobject.Then(); 1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make the key_index available. 1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(key_index); 1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_keyeqobject.JoinContinuation(&found); 18913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_keyisheapnumber.JoinContinuation(&found); 18933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_keyisnotsmi.JoinContinuation(&found); 1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectisnumber.Else(); 1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1898f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (type->Is(AstType::Number())) { 1899f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if_objectisnumber.Deopt(DeoptimizeReason::kExpectedHeapNumber); 19003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1901b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectisnumber.JoinContinuation(&found); 1903b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1904b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_objectissmi.JoinContinuation(&found); 1906b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check for cache hit. 1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_found(this, &found); 1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_found.Then(); 1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count number to string operation in native code. 1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddIncrementCounter(isolate()->counters()->number_to_string_native()); 19131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the value in case of cache hit. 1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key_index = Pop(); 1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1()); 1917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(Add<HLoadKeyed>(number_string_cache, value_index, nullptr, nullptr, 1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FAST_ELEMENTS, ALLOW_RETURN_HOLE)); 1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_found.Else(); 1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Cache miss, fallback to runtime. 1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(object); 1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Add<HCallRuntime>( 1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::FunctionForId(Runtime::kNumberToStringSkipCache), 1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1)); 1927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_found.End(); 1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Pop(); 1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1933109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochHValue* HGraphBuilder::BuildToNumber(HValue* input) { 1934c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (input->type().IsTaggedNumber() || 1935c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch input->representation().IsSpecialization()) { 1936109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return input; 1937109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1938109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Callable callable = CodeFactory::ToNumber(isolate()); 1939109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HValue* stub = Add<HConstant>(callable.code()); 1940c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* values[] = {input}; 1941bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HCallWithDescriptor* instr = Add<HCallWithDescriptor>( 1942bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch stub, 0, callable.descriptor(), ArrayVector(values)); 1943109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch instr->set_type(HType::TaggedNumber()); 1944109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return instr; 1945109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1946109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHValue* HGraphBuilder::BuildToObject(HValue* receiver) { 1949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NoObservableSideEffectsScope scope(this); 1950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Create a joinable continuation. 1952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HIfContinuation wrap(graph()->CreateBasicBlock(), 1953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->CreateBasicBlock()); 1954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Determine the proper global constructor function required to wrap 1956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // {receiver} into a JSValue, unless {receiver} is already a {JSReceiver}, in 1957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // which case we just return it. Deopts to Runtime::kToObject if {receiver} 1958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // is undefined or null. 1959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IfBuilder receiver_is_smi(this); 1960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver_is_smi.If<HIsSmiAndBranch>(receiver); 1961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver_is_smi.Then(); 1962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 1963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Use global Number function. 1964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(Add<HConstant>(Context::NUMBER_FUNCTION_INDEX)); 1965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver_is_smi.Else(); 1967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 1968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Determine {receiver} map and instance type. 1969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* receiver_map = 1970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap()); 1971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* receiver_instance_type = Add<HLoadNamedField>( 1972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver_map, nullptr, HObjectAccess::ForMapInstanceType()); 1973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // First check whether {receiver} is already a spec object (fast case). 1975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IfBuilder receiver_is_not_spec_object(this); 1976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver_is_not_spec_object.If<HCompareNumericAndBranch>( 1977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver_instance_type, Add<HConstant>(FIRST_JS_RECEIVER_TYPE), 1978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Token::LT); 1979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver_is_not_spec_object.Then(); 1980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 1981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Load the constructor function index from the {receiver} map. 1982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* constructor_function_index = Add<HLoadNamedField>( 1983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver_map, nullptr, 1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess::ForMapInObjectPropertiesOrConstructorFunctionIndex()); 1985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if {receiver} has a constructor (null and undefined have no 1987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // constructors, so we deoptimize to the runtime to throw an exception). 1988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IfBuilder constructor_function_index_is_invalid(this); 1989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constructor_function_index_is_invalid.If<HCompareNumericAndBranch>( 1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constructor_function_index, 1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HConstant>(Map::kNoConstructorFunctionIndex), Token::EQ); 1992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constructor_function_index_is_invalid.ThenDeopt( 1993f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason::kUndefinedOrNullInToObject); 1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constructor_function_index_is_invalid.End(); 1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Use the global constructor function. 1997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(constructor_function_index); 1998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver_is_not_spec_object.JoinContinuation(&wrap); 2000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver_is_smi.JoinContinuation(&wrap); 2002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Wrap the receiver if necessary. 2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IfBuilder if_wrap(this, &wrap); 2005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_wrap.Then(); 2006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 2007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Grab the constructor function index. 2008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* constructor_index = Pop(); 2009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Load native context. 2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* native_context = BuildGetNativeContext(); 2012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Determine the initial map for the global constructor. 2014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* constructor = Add<HLoadKeyed>(native_context, constructor_index, 2015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch nullptr, nullptr, FAST_ELEMENTS); 2016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* constructor_initial_map = Add<HLoadNamedField>( 2017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constructor, nullptr, HObjectAccess::ForPrototypeOrInitialMap()); 2018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allocate and initialize a JSValue wrapper. 2019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* value = 2020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildAllocate(Add<HConstant>(JSValue::kSize), HType::JSObject(), 2021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JS_VALUE_TYPE, HAllocationMode()); 2022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(value, HObjectAccess::ForMap(), 2023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constructor_initial_map); 2024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* empty_fixed_array = Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex); 2025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(value, HObjectAccess::ForPropertiesPointer(), 2026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch empty_fixed_array); 2027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(value, HObjectAccess::ForElementsPointer(), 2028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch empty_fixed_array); 2029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(value, HObjectAccess::ForObservableJSObjectOffset( 2030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSValue::kValueOffset), 2031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver); 2032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(value); 2033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_wrap.Else(); 2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { Push(receiver); } 2036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_wrap.End(); 2037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Pop(); 2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHAllocate* HGraphBuilder::BuildAllocate( 2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object_size, 2043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HType type, 2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstanceType instance_type, 2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocationMode allocation_mode) { 2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the effective allocation size. 2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* size = object_size; 2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (allocation_mode.CreateAllocationMementos()) { 2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size = AddUncasted<HAdd>(size, Add<HConstant>(AllocationMemento::kSize)); 2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size->ClearFlag(HValue::kCanOverflow); 2051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Perform the actual allocation. 2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocate* object = Add<HAllocate>( 2055bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch size, type, allocation_mode.GetPretenureMode(), instance_type, 2056bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch graph()->GetConstant0(), allocation_mode.feedback_site()); 2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Setup the allocation memento. 2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (allocation_mode.CreateAllocationMementos()) { 2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCreateAllocationMemento( 2061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, object_size, allocation_mode.current_site()); 2062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return object; 2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildAddStringLengths(HValue* left_length, 2069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right_length) { 2070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the combined string length and check against max string length. 2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length = AddUncasted<HAdd>(left_length, right_length); 2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that length <= kMaxLength <=> length < MaxLength + 1. 2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* max_length = Add<HConstant>(String::kMaxLength + 1); 2074f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (top_info()->IsStub() || !isolate()->IsStringLengthOverflowIntact()) { 2075f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // This is a mitigation for crbug.com/627934; the real fix 2076f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // will be to migrate the StringAddStub to TurboFan one day. 2077f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch IfBuilder if_invalid(this); 2078f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if_invalid.If<HCompareNumericAndBranch>(length, max_length, Token::GT); 2079f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if_invalid.Then(); 2080f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 2081f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Add<HCallRuntime>( 2082f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Runtime::FunctionForId(Runtime::kThrowInvalidStringLength), 0); 2083f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2084f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if_invalid.End(); 2085f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2086f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->MarkDependsOnStringLengthOverflow(); 2087f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Add<HBoundsCheck>(length, max_length); 2088f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return length; 2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildCreateConsString( 2094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length, 2095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left, 2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right, 2097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocationMode allocation_mode) { 2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Determine the string instance types. 2099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* left_instance_type = AddLoadStringInstanceType(left); 2100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* right_instance_type = AddLoadStringInstanceType(right); 2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate the cons string object. HAllocate does not care whether we 2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pass CONS_STRING_TYPE or CONS_ONE_BYTE_STRING_TYPE here, so we just use 2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // CONS_STRING_TYPE here. Below we decide whether the cons string is 2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // one-byte or two-byte and set the appropriate map. 2106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(HAllocate::CompatibleInstanceTypes(CONS_STRING_TYPE, 2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CONS_ONE_BYTE_STRING_TYPE)); 2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocate* result = BuildAllocate(Add<HConstant>(ConsString::kSize), 2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HType::String(), CONS_STRING_TYPE, 2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_mode); 2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute intersection and difference of instance types. 2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* anded_instance_types = AddUncasted<HBitwise>( 2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, left_instance_type, right_instance_type); 2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* xored_instance_types = AddUncasted<HBitwise>( 2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_XOR, left_instance_type, right_instance_type); 2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We create a one-byte cons string if 2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 1. both strings are one-byte, or 2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2. at least one of the strings is two-byte, but happens to contain only 2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // one-byte characters. 2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // To do this, we check 2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 1. if both strings are one-byte, or if the one-byte data hint is set in 2124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // both strings, or 2125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2. if one of the strings has the one-byte data hint set and the other 2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // string is one-byte. 2127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_onebyte(this); 2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kOneByteStringTag != 0); 2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kOneByteDataHintMask != 0); 2130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.If<HCompareNumericAndBranch>( 2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HBitwise>( 2132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, anded_instance_types, 2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>( 2134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kStringEncodingMask | kOneByteDataHintMask))), 2135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0(), Token::NE); 2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.Or(); 2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kOneByteStringTag != 0 && 2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kOneByteDataHintTag != 0 && 2139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kOneByteDataHintTag != kOneByteStringTag); 2140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.If<HCompareNumericAndBranch>( 2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HBitwise>( 2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, xored_instance_types, 2143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>( 2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kOneByteStringTag | kOneByteDataHintTag))), 2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>( 2146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kOneByteStringTag | kOneByteDataHintTag)), Token::EQ); 2147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.Then(); 2148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We can safely skip the write barrier for storing the map here. 2150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 2151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, HObjectAccess::ForMap(), 2152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(isolate()->factory()->cons_one_byte_string_map())); 2153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.Else(); 2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We can safely skip the write barrier for storing the map here. 2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, HObjectAccess::ForMap(), 2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(isolate()->factory()->cons_string_map())); 2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.End(); 2162e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize the cons string fields. 2164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(), 2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(String::kEmptyHashField)); 2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length); 2167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForConsStringFirst(), left); 2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForConsStringSecond(), right); 2169e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count the native string addition. 2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddIncrementCounter(isolate()->counters()->string_add_native()); 2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 2174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildCopySeqStringChars(HValue* src, 2178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* src_offset, 2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String::Encoding src_encoding, 2180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dst, 2181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dst_offset, 2182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String::Encoding dst_encoding, 2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length) { 2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(dst_encoding != String::ONE_BYTE_ENCODING || 2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch src_encoding == String::ONE_BYTE_ENCODING); 2186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); 2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT); 2188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* src_index = AddUncasted<HAdd>(src_offset, index); 2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = 2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HSeqStringGetChar>(src_encoding, src, src_index); 2192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dst_index = AddUncasted<HAdd>(dst_offset, index); 2193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSeqStringSetChar>(dst_encoding, dst, dst_index, value); 2194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.EndBody(); 2196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildObjectSizeAlignment( 2200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* unaligned_size, int header_size) { 2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((header_size & kObjectAlignmentMask) == 0); 2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* size = AddUncasted<HAdd>( 2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unaligned_size, Add<HConstant>(static_cast<int32_t>( 2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch header_size + kObjectAlignmentMask))); 2205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size->ClearFlag(HValue::kCanOverflow); 2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddUncasted<HBitwise>( 2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>( 2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~kObjectAlignmentMask))); 2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildUncheckedStringAdd( 2213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left, 2214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right, 2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocationMode allocation_mode) { 2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Determine the string lengths. 2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left_length = AddLoadStringLength(left); 2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right_length = AddLoadStringLength(right); 2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the combined string length. 2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length = BuildAddStringLengths(left_length, right_length); 2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Do some manual constant folding here. 2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (left_length->IsConstant()) { 2225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* c_left_length = HConstant::cast(left_length); 2226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NE(0, c_left_length->Integer32Value()); 2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (c_left_length->Integer32Value() + 1 >= ConsString::kMinLength) { 2228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The right string contains at least one character. 2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildCreateConsString(length, left, right, allocation_mode); 2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (right_length->IsConstant()) { 2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* c_right_length = HConstant::cast(right_length); 2233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NE(0, c_right_length->Integer32Value()); 2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (c_right_length->Integer32Value() + 1 >= ConsString::kMinLength) { 2235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The left string contains at least one character. 2236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildCreateConsString(length, left, right, allocation_mode); 2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if we should create a cons string. 2241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_createcons(this); 2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_createcons.If<HCompareNumericAndBranch>( 2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length, Add<HConstant>(ConsString::kMinLength), Token::GTE); 224462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if_createcons.And(); 224562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if_createcons.If<HCompareNumericAndBranch>( 224662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch length, Add<HConstant>(ConsString::kMaxLength), Token::LTE); 2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_createcons.Then(); 2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create a cons string. 2250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(BuildCreateConsString(length, left, right, allocation_mode)); 2251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_createcons.Else(); 2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Determine the string instance types. 2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left_instance_type = AddLoadStringInstanceType(left); 2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right_instance_type = AddLoadStringInstanceType(right); 2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute union and difference of instance types. 2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* ored_instance_types = AddUncasted<HBitwise>( 2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_OR, left_instance_type, right_instance_type); 2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* xored_instance_types = AddUncasted<HBitwise>( 2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_XOR, left_instance_type, right_instance_type); 2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if both strings have the same encoding and both are 2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // sequential. 2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_sameencodingandsequential(this); 2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_sameencodingandsequential.If<HCompareNumericAndBranch>( 2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HBitwise>( 2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, xored_instance_types, 2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))), 2271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0(), Token::EQ); 2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_sameencodingandsequential.And(); 2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kSeqStringTag == 0); 2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_sameencodingandsequential.If<HCompareNumericAndBranch>( 2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HBitwise>( 2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, ored_instance_types, 2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>(kStringRepresentationMask))), 2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0(), Token::EQ); 2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_sameencodingandsequential.Then(); 2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* string_map = 2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(isolate()->factory()->string_map()); 2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* one_byte_string_map = 2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(isolate()->factory()->one_byte_string_map()); 2285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Determine map and size depending on whether result is one-byte string. 2287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_onebyte(this); 2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kOneByteStringTag != 0); 2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.If<HCompareNumericAndBranch>( 2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HBitwise>( 2291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::BIT_AND, ored_instance_types, 2292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))), 2293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0(), Token::NE); 2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.Then(); 2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate sequential one-byte string object. 2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(length); 2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(one_byte_string_map); 2299257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.Else(); 2301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate sequential two-byte string object. 2303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* size = AddUncasted<HShl>(length, graph()->GetConstant1()); 2304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size->ClearFlag(HValue::kCanOverflow); 2305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size->SetFlag(HValue::kUint32); 2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(size); 2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(string_map); 2308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_onebyte.End(); 2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* map = Pop(); 2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calculate the number of bytes needed for the characters in the 2313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // string while observing object alignment. 2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0); 2315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* size = BuildObjectSizeAlignment(Pop(), SeqString::kHeaderSize); 2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IfBuilder if_size(this); 2318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_size.If<HCompareNumericAndBranch>( 2319f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch size, Add<HConstant>(kMaxRegularHeapObjectSize), Token::LT); 2320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_size.Then(); 2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allocate the string object. HAllocate does not care whether we pass 2323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // STRING_TYPE or ONE_BYTE_STRING_TYPE here, so we just use STRING_TYPE. 2324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HAllocate* result = 2325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildAllocate(size, HType::String(), STRING_TYPE, allocation_mode); 2326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForMap(), map); 2327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Initialize the string fields. 2329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(), 2330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HConstant>(String::kEmptyHashField)); 2331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length); 2332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Copy characters to the result string. 2334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IfBuilder if_twobyte(this); 2335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_twobyte.If<HCompareObjectEqAndBranch>(map, string_map); 2336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_twobyte.Then(); 2337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 2338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Copy characters from the left string. 2339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildCopySeqStringChars( 2340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left, graph()->GetConstant0(), String::TWO_BYTE_ENCODING, result, 2341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->GetConstant0(), String::TWO_BYTE_ENCODING, left_length); 2342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Copy characters from the right string. 2344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildCopySeqStringChars( 2345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch right, graph()->GetConstant0(), String::TWO_BYTE_ENCODING, result, 2346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left_length, String::TWO_BYTE_ENCODING, right_length); 2347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_twobyte.Else(); 2349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 2350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Copy characters from the left string. 2351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildCopySeqStringChars( 2352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left, graph()->GetConstant0(), String::ONE_BYTE_ENCODING, result, 2353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->GetConstant0(), String::ONE_BYTE_ENCODING, left_length); 2354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Copy characters from the right string. 2356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildCopySeqStringChars( 2357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch right, graph()->GetConstant0(), String::ONE_BYTE_ENCODING, result, 2358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left_length, String::ONE_BYTE_ENCODING, right_length); 2359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_twobyte.End(); 2361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Count the native string addition. 2363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddIncrementCounter(isolate()->counters()->string_add_native()); 2364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Return the sequential string. 2366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(result); 2367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_size.Else(); 2369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 2370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Fallback to the runtime to add the two strings. The string has to be 2371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // allocated in LO space. 2372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HPushArguments>(left, right); 2373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kStringAdd), 2)); 2374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_size.End(); 2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_sameencodingandsequential.Else(); 2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fallback to the runtime to add the two strings. 2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(left, right); 2381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kStringAdd), 2)); 2382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_sameencodingandsequential.End(); 2384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_createcons.End(); 2386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Pop(); 2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildStringAdd( 2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left, 2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right, 2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocationMode allocation_mode) { 2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 2396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Determine string lengths. 2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left_length = AddLoadStringLength(left); 2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right_length = AddLoadStringLength(right); 2400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if left string is empty. 2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_leftempty(this); 2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_leftempty.If<HCompareNumericAndBranch>( 2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left_length, graph()->GetConstant0(), Token::EQ); 2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_leftempty.Then(); 2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count the native string addition. 2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddIncrementCounter(isolate()->counters()->string_add_native()); 24098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Just return the right string. 2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(right); 2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_leftempty.Else(); 2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if right string is empty. 2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_rightempty(this); 2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_rightempty.If<HCompareNumericAndBranch>( 2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right_length, graph()->GetConstant0(), Token::EQ); 2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_rightempty.Then(); 2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count the native string addition. 2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddIncrementCounter(isolate()->counters()->string_add_native()); 2423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Just return the left string. 2425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(left); 2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_rightempty.Else(); 2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Add the two non-empty strings. 2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(BuildUncheckedStringAdd(left, right, allocation_mode)); 2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_rightempty.End(); 2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_leftempty.End(); 2435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Pop(); 2437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( 2441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_object, 2442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key, 2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* val, 2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_js_array, 2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind, 2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessType access_type, 2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadKeyedHoleMode load_mode, 2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch KeyedAccessStoreMode store_mode) { 2449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(top_info()->IsStub() || checked_object->IsCompareMap() || 2450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch checked_object->IsCheckMaps()); 2451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!IsFixedTypedArrayElementsKind(elements_kind) || !is_js_array); 2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // No GVNFlag is necessary for ElementsKind if there is an explicit dependency 2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // on a HElementsTransition instruction. The flag can also be removed if the 2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // map to check has FAST_HOLEY_ELEMENTS, since there can be no further 2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ElementsKind transitions. Finally, the dependency can be removed for stores 2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the 2457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // generated store code. 2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((elements_kind == FAST_HOLEY_ELEMENTS) || 2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (elements_kind == FAST_ELEMENTS && access_type == STORE)) { 2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object->ClearDependsOnFlag(kElementsKind); 2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); 2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool fast_elements = IsFastObjectElementsKind(elements_kind); 2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements = AddLoadElements(checked_object); 2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == STORE && (fast_elements || fast_smi_only_elements) && 2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCheckMaps* check_cow_map = Add<HCheckMaps>( 2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, isolate()->factory()->fixed_array_map()); 2470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch check_cow_map->ClearDependsOnFlag(kElementsKind); 2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* length = NULL; 2473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_js_array) { 2474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length = Add<HLoadNamedField>( 2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object->ActualValue(), checked_object, 2476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForArrayLength(elements_kind)); 2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length = AddLoadFixedArrayLength(elements); 2479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length->set_type(HType::Smi()); 2481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_key = NULL; 2482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsFixedTypedArrayElementsKind(elements_kind)) { 2483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch checked_object = Add<HCheckArrayBufferNotNeutered>(checked_object); 2484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* external_pointer = Add<HLoadNamedField>( 2486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements, nullptr, 2487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess::ForFixedTypedArrayBaseExternalPointer()); 2488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* base_pointer = Add<HLoadNamedField>( 2489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements, nullptr, HObjectAccess::ForFixedTypedArrayBaseBasePointer()); 2490109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HValue* backing_store = AddUncasted<HAdd>(external_pointer, base_pointer, 2491109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AddOfExternalAndTagged); 2492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder length_checker(this); 2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); 2497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.Then(); 2498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder negative_checker(this); 2499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( 2500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key, graph()->GetConstant0(), Token::GTE); 2501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negative_checker.Then(); 2502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = AddElementAccess( 2503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch backing_store, key, val, bounds_check, checked_object->ActualValue(), 2504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements_kind, access_type); 2505f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch negative_checker.ElseDeopt(DeoptimizeReason::kNegativeKeyEncountered); 2506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negative_checker.End(); 2507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.End(); 2508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 2509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(store_mode == STANDARD_STORE); 2511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_key = Add<HBoundsCheck>(key, length); 2512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return AddElementAccess(backing_store, checked_key, val, checked_object, 2513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch checked_object->ActualValue(), elements_kind, 2514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch access_type); 2515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fast_smi_only_elements || 2518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fast_elements || 2519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsFastDoubleElementsKind(elements_kind)); 2520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // In case val is stored into a fast smi array, assure that the value is a smi 2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // before manipulating the backing store. Otherwise the actual store may 2523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // deopt, leaving the backing store in an invalid state. 2524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == STORE && IsFastSmiElementsKind(elements_kind) && 2525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !val->type().IsSmi()) { 2526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch val = AddUncasted<HForceRepresentation>(val, Representation::Smi()); 2527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsGrowStoreMode(store_mode)) { 2530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 2531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation representation = HStoreKeyed::RequiredValueRepresentation( 2532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind, STORE_TO_INITIALIZED_ENTRY); 2533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch val = AddUncasted<HForceRepresentation>(val, representation); 2534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements = BuildCheckForCapacityGrow(checked_object, elements, 2535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind, length, key, 2536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_js_array, access_type); 2537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_key = key; 2538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_key = Add<HBoundsCheck>(key, length); 2540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == STORE && (fast_elements || fast_smi_only_elements)) { 2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { 2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 2544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements = BuildCopyElementsOnWrite(checked_object, elements, 2545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind, length); 2546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCheckMaps* check_cow_map = Add<HCheckMaps>( 2548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, isolate()->factory()->fixed_array_map()); 2549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch check_cow_map->ClearDependsOnFlag(kElementsKind); 2550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 25513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return AddElementAccess(elements, checked_key, val, checked_object, nullptr, 2554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind, access_type, load_mode); 2555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildCalculateElementsSize(ElementsKind kind, 2559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* capacity) { 2560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int elements_size = IsFastDoubleElementsKind(kind) 2561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? kDoubleSize 2562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : kPointerSize; 2563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* elements_size_value = Add<HConstant>(elements_size); 2565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* mul = 2566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HMul::NewImul(isolate(), zone(), context(), capacity->ActualValue(), 2567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements_size_value); 2568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(mul); 2569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mul->ClearFlag(HValue::kCanOverflow); 2570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize); 2572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); 2574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* total_size = AddUncasted<HAdd>(mul, header_size); 2575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total_size->ClearFlag(HValue::kCanOverflow); 2576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return total_size; 2577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHAllocate* HGraphBuilder::AllocateJSArrayObject(AllocationSiteMode mode) { 2581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int base_size = JSArray::kSize; 2582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode == TRACK_ALLOCATION_SITE) { 2583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base_size += AllocationMemento::kSize; 2584b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* size_in_bytes = Add<HConstant>(base_size); 2586bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Add<HAllocate>(size_in_bytes, HType::JSArray(), NOT_TENURED, 2587bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch JS_OBJECT_TYPE, graph()->GetConstant0()); 2588b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHConstant* HGraphBuilder::EstablishElementsAllocationSize( 2592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 2593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int capacity) { 2594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int base_size = IsFastDoubleElementsKind(kind) 2595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? FixedDoubleArray::SizeFor(capacity) 2596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : FixedArray::SizeFor(capacity); 2597b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HConstant>(base_size); 2599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2600b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2601b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHAllocate* HGraphBuilder::BuildAllocateElements(ElementsKind kind, 2603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* size_in_bytes) { 2604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstanceType instance_type = IsFastDoubleElementsKind(kind) 2605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? FIXED_DOUBLE_ARRAY_TYPE 2606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : FIXED_ARRAY_TYPE; 2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HAllocate>(size_in_bytes, HType::HeapObject(), NOT_TENURED, 2609bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch instance_type, graph()->GetConstant0()); 2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2611589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 2612589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 2613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, 2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* capacity) { 2616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate()->factory(); 2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = IsFastDoubleElementsKind(kind) 2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? factory->fixed_double_array_map() 2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : factory->fixed_array_map(); 2620589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 2621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(elements, HObjectAccess::ForMap(), Add<HConstant>(map)); 2622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), 2623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch capacity); 2624b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2625b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2626b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierHValue* HGraphBuilder::BuildAllocateAndInitializeArray(ElementsKind kind, 2628958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* capacity) { 2629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The HForceRepresentation is to prevent possible deopt on int-smi 2630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // conversion after allocation but before the new object fields are set. 2631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi()); 2632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* size_in_bytes = BuildCalculateElementsSize(kind, capacity); 2633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* new_array = BuildAllocateElements(kind, size_in_bytes); 2634958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BuildInitializeElementsHeader(new_array, kind, capacity); 2635958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return new_array; 2636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2637b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2638b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildJSArrayHeader(HValue* array, 2640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* array_map, 2641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements, 2642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteMode mode, 2643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind, 2644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* allocation_site_payload, 2645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length_field) { 2646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map); 2647b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2648f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HValue* empty_fixed_array = Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex); 2649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 2651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array, HObjectAccess::ForPropertiesPointer(), empty_fixed_array); 2652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2653f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), 2654f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch elements != nullptr ? elements : empty_fixed_array); 2655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 2657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array, HObjectAccess::ForArrayLength(elements_kind), length_field); 2658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode == TRACK_ALLOCATION_SITE) { 2660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCreateAllocationMemento( 2661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array, Add<HConstant>(JSArray::kSize), allocation_site_payload); 2662257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2664257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2665b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::AddElementAccess( 2667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* elements, HValue* checked_key, HValue* val, HValue* dependency, 2668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* backing_store_owner, ElementsKind elements_kind, 2669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAccessType access_type, LoadKeyedHoleMode load_mode) { 2670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == STORE) { 2671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(val != NULL); 2672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (elements_kind == UINT8_CLAMPED_ELEMENTS) { 2673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch val = Add<HClampToUint8>(val); 2674b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Add<HStoreKeyed>(elements, checked_key, val, backing_store_owner, 2676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements_kind, STORE_TO_INITIALIZED_ENTRY); 2677b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(access_type == LOAD); 2680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(val == NULL); 2681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HLoadKeyed* load = 2682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HLoadKeyed>(elements, checked_key, dependency, backing_store_owner, 2683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements_kind, load_mode); 2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (elements_kind == UINT32_ELEMENTS) { 2685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->RecordUint32Instruction(load); 2686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return load; 2688b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2689b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2690b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHLoadNamedField* HGraphBuilder::AddLoadMap(HValue* object, 2692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dependency) { 2693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HLoadNamedField>(object, dependency, HObjectAccess::ForMap()); 2694b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2695b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2696b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, 2698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dependency) { 2699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HLoadNamedField>( 2700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, dependency, HObjectAccess::ForElementsPointer()); 2701b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2702b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2703b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength( 2705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* array, 2706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dependency) { 2707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HLoadNamedField>( 2708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array, dependency, HObjectAccess::ForFixedArrayLength()); 2709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2710b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2711b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHLoadNamedField* HGraphBuilder::AddLoadArrayLength(HValue* array, 2713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 2714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dependency) { 2715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HLoadNamedField>( 2716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array, dependency, HObjectAccess::ForArrayLength(kind)); 2717b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2718b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2719b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildNewElementsCapacity(HValue* old_capacity) { 2721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* half_old_capacity = AddUncasted<HShr>(old_capacity, 2722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph_->GetConstant1()); 2723b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_capacity = AddUncasted<HAdd>(half_old_capacity, old_capacity); 2725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_capacity->ClearFlag(HValue::kCanOverflow); 2726b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* min_growth = Add<HConstant>(16); 2728b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_capacity = AddUncasted<HAdd>(new_capacity, min_growth); 2730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_capacity->ClearFlag(HValue::kCanOverflow); 2731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new_capacity; 2733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, 2737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements, 2738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 2739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind new_kind, 2740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length, 2741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_capacity) { 2742f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Add<HBoundsCheck>( 2743f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch new_capacity, 2744f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Add<HConstant>((kMaxRegularHeapObjectSize - FixedArray::kHeaderSize) >> 2745f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ElementsKindToShiftSize(new_kind))); 2746257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2747958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* new_elements = 2748958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BuildAllocateAndInitializeArray(new_kind, new_capacity); 2749b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCopyElements(elements, kind, new_elements, 2751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_kind, length, new_capacity); 2752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 2754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_elements); 2755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new_elements; 2757b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2758b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2759b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildFillElementsWithValue(HValue* elements, 2761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind, 2762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* from, 2763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* to, 2764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value) { 2765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (to == NULL) { 2766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to = AddLoadFixedArrayLength(elements); 2767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Special loop unfolding case 2770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(JSArray::kPreallocatedArrayElements <= 2771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kElementLoopUnrollThreshold); 2772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int initial_capacity = -1; 2773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (from->IsInteger32Constant() && to->IsInteger32Constant()) { 2774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int constant_from = from->GetInteger32Constant(); 2775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int constant_to = to->GetInteger32Constant(); 2776b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (constant_from == 0 && constant_to <= kElementLoopUnrollThreshold) { 2778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch initial_capacity = constant_to; 2779b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2780b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (initial_capacity >= 0) { 2783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < initial_capacity; i++) { 2784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* key = Add<HConstant>(i); 2785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreKeyed>(elements, key, value, nullptr, elements_kind); 2786b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Carefully loop backwards so that the "from" remains live through the loop 2789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // rather than the to. This often corresponds to keeping length live rather 2790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // then capacity, which helps register allocation, since length is used more 2791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // other than capacity after filling with holes. 2792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); 2793b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = builder.BeginBody(to, from, Token::GT); 2795b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* adjusted_key = AddUncasted<HSub>(key, graph()->GetConstant1()); 2797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch adjusted_key->ClearFlag(HValue::kCanOverflow); 2798b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreKeyed>(elements, adjusted_key, value, nullptr, elements_kind); 2800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder.EndBody(); 28027d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch } 28037d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch} 28047d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch 28057d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch 2806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildFillElementsWithHole(HValue* elements, 2807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind, 2808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* from, 2809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* to) { 2810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fast elements kinds need to be initialized in case statements below cause a 2811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // garbage collection. 2812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) 2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? graph()->GetConstantHole() 2815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Add<HConstant>(HConstant::kHoleNaN); 2816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2817958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Since we're about to store a hole value, the store instruction below must 2818958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // assume an elements kind that supports heap object values. 2819958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IsFastSmiOrObjectElementsKind(elements_kind)) { 2820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier elements_kind = FAST_HOLEY_ELEMENTS; 2821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildFillElementsWithValue(elements, elements_kind, from, to, hole); 28247d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch} 28257d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch 28267d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch 2827958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid HGraphBuilder::BuildCopyProperties(HValue* from_properties, 2828958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* to_properties, HValue* length, 2829958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* capacity) { 2830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ElementsKind kind = FAST_ELEMENTS; 2831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2832958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BuildFillElementsWithValue(to_properties, kind, length, capacity, 2833958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier graph()->GetConstantUndefined()); 2834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2835958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); 2836958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2837958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* key = builder.BeginBody(length, graph()->GetConstant0(), Token::GT); 2838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier key = AddUncasted<HSub>(key, graph()->GetConstant1()); 2840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier key->ClearFlag(HValue::kCanOverflow); 2841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* element = 2843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HLoadKeyed>(from_properties, key, nullptr, nullptr, kind); 2844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreKeyed>(to_properties, key, element, nullptr, kind); 2846958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2847958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier builder.EndBody(); 2848958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2849958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2850958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildCopyElements(HValue* from_elements, 2852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind from_elements_kind, 2853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* to_elements, 2854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind to_elements_kind, 2855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length, 2856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* capacity) { 2857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int constant_capacity = -1; 2858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (capacity != NULL && 2859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch capacity->IsConstant() && 2860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(capacity)->HasInteger32Value()) { 2861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int constant_candidate = HConstant::cast(capacity)->Integer32Value(); 2862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (constant_candidate <= kElementLoopUnrollThreshold) { 2863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_capacity = constant_candidate; 28641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 28651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 28661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool pre_fill_with_holes = 2868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsFastDoubleElementsKind(from_elements_kind) && 2869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsFastObjectElementsKind(to_elements_kind); 2870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (pre_fill_with_holes) { 2871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the copy might trigger a GC, make sure that the FixedArray is 2872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pre-initialized with holes to make sure that it's always in a 2873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // consistent state. 2874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildFillElementsWithHole(to_elements, to_elements_kind, 2875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0(), NULL); 2876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 28771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (constant_capacity != -1) { 2879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Unroll the loop for small elements kinds. 2880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < constant_capacity; i++) { 2881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key_constant = Add<HConstant>(i); 2882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* value = Add<HLoadKeyed>( 2883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch from_elements, key_constant, nullptr, nullptr, from_elements_kind); 2884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreKeyed>(to_elements, key_constant, value, nullptr, 2885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch to_elements_kind); 2886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!pre_fill_with_holes && 2889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (capacity == NULL || !length->Equals(capacity))) { 2890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildFillElementsWithHole(to_elements, to_elements_kind, 2891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length, NULL); 2892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); 2895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = builder.BeginBody(length, graph()->GetConstant0(), 2897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::GT); 2898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key = AddUncasted<HSub>(key, graph()->GetConstant1()); 2900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key->ClearFlag(HValue::kCanOverflow); 2901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* element = Add<HLoadKeyed>(from_elements, key, nullptr, nullptr, 2903958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier from_elements_kind, ALLOW_RETURN_HOLE); 2904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind = (IsHoleyElementsKind(from_elements_kind) && 2906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsFastSmiElementsKind(to_elements_kind)) 2907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? FAST_HOLEY_ELEMENTS : to_elements_kind; 2908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsHoleyElementsKind(from_elements_kind) && 2910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch from_elements_kind != to_elements_kind) { 2911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_hole(this); 2912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_hole.If<HCompareHoleAndBranch>(element); 2913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_hole.Then(); 2914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* hole_constant = IsFastDoubleElementsKind(to_elements_kind) 2915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? Add<HConstant>(HConstant::kHoleNaN) 2916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : graph()->GetConstantHole(); 2917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreKeyed>(to_elements, key, hole_constant, nullptr, kind); 2918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_hole.Else(); 2919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HStoreKeyed* store = 2920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreKeyed>(to_elements, key, element, nullptr, kind); 2921c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch store->SetFlag(HValue::kTruncatingToNumber); 2922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_hole.End(); 2923e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 2924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HStoreKeyed* store = 2925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreKeyed>(to_elements, key, element, nullptr, kind); 2926c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch store->SetFlag(HValue::kTruncatingToNumber); 2927e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder.EndBody(); 2930e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2931e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Counters* counters = isolate()->counters(); 2933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddIncrementCounter(counters->inlined_copied_elements()); 2934e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 2935e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildCreateAllocationMemento( 2937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* previous_object, 2938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* previous_object_size, 2939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* allocation_site) { 2940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(allocation_site != NULL); 2941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInnerAllocatedObject* allocation_memento = Add<HInnerAllocatedObject>( 2942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch previous_object, previous_object_size, HType::HeapObject()); 2943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddStoreMapConstant( 2944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_memento, isolate()->factory()->allocation_memento_map()); 2945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 2946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_memento, 2947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForAllocationMementoSite(), 2948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_site); 2949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_allocation_site_pretenuring) { 2950958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* memento_create_count = 2951958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HLoadNamedField>(allocation_site, nullptr, 2952958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HObjectAccess::ForAllocationSiteOffset( 2953958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AllocationSite::kPretenureCreateCountOffset)); 2954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memento_create_count = AddUncasted<HAdd>( 2955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memento_create_count, graph()->GetConstant1()); 2956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This smi value is reset to zero after every gc, overflow isn't a problem 2957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // since the counter is bounded by the new space size. 2958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memento_create_count->ClearFlag(HValue::kCanOverflow); 2959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 2960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_site, HObjectAccess::ForAllocationSiteOffset( 2961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSite::kPretenureCreateCountOffset), memento_create_count); 2962257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2963b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 2964b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2965b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHInstruction* HGraphBuilder::BuildGetNativeContext() { 2967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Add<HLoadNamedField>( 2968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch context(), nullptr, 2969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess::ForContextSlot(Context::NATIVE_CONTEXT_INDEX)); 2970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::BuildGetNativeContext(HValue* closure) { 2974958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Get the global object, then the native context 2975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HInstruction* context = Add<HLoadNamedField>( 2976958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier closure, nullptr, HObjectAccess::ForFunctionContextPointer()); 2977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Add<HLoadNamedField>( 2978958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier context, nullptr, 2979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess::ForContextSlot(Context::NATIVE_CONTEXT_INDEX)); 2980958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2981958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2982958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHValue* HGraphBuilder::BuildGetParentContext(HValue* depth, int depth_value) { 2984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* script_context = context(); 2985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (depth != NULL) { 2986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* zero = graph()->GetConstant0(); 2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(script_context); 2989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(depth); 2990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoopBuilder loop(this); 2992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch loop.BeginBody(2); // Drop script_context and depth from last environment 2993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to appease live range building without simulates. 2994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch depth = Pop(); 2995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch script_context = Pop(); 2996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch script_context = Add<HLoadNamedField>( 2998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch script_context, nullptr, 2999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 3000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch depth = AddUncasted<HSub>(depth, graph()->GetConstant1()); 3001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch depth->ClearFlag(HValue::kCanOverflow); 3002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IfBuilder if_break(this); 3004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_break.If<HCompareNumericAndBranch, HValue*>(depth, zero, Token::EQ); 3005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_break.Then(); 3006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 3007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(script_context); // The result. 3008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch loop.Break(); 3009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_break.Else(); 3011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 3012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(script_context); 3013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(depth); 3014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch loop.EndBody(); 3016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_break.End(); 3017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch script_context = Pop(); 3019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (depth_value > 0) { 3020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unroll the above loop. 3021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < depth_value; i++) { 3022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch script_context = Add<HLoadNamedField>( 3023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch script_context, nullptr, 3024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 3025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return script_context; 3028b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3029b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3030b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::BuildGetArrayFunction() { 3032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* native_context = BuildGetNativeContext(); 3033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* index = 3034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX)); 3035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Add<HLoadKeyed>(native_context, index, nullptr, nullptr, 3036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FAST_ELEMENTS); 3037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHValue* HGraphBuilder::BuildArrayBufferViewFieldAccessor(HValue* object, 3041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* checked_object, 3042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FieldIndex index) { 3043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NoObservableSideEffectsScope scope(this); 3044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( 3045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch index.offset(), Representation::Tagged()); 3046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* buffer = Add<HLoadNamedField>( 3047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object, checked_object, HObjectAccess::ForJSArrayBufferViewBuffer()); 3048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* field = Add<HLoadNamedField>(object, checked_object, access); 3049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* flags = Add<HLoadNamedField>( 3051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer, nullptr, HObjectAccess::ForJSArrayBufferBitField()); 3052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* was_neutered_mask = 3053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HConstant>(1 << JSArrayBuffer::WasNeutered::kShift); 3054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* was_neutered_test = 3055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddUncasted<HBitwise>(Token::BIT_AND, flags, was_neutered_mask); 3056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IfBuilder if_was_neutered(this); 3058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_was_neutered.If<HCompareNumericAndBranch>( 3059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch was_neutered_test, graph()->GetConstant0(), Token::NE); 3060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_was_neutered.Then(); 3061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(graph()->GetConstant0()); 3062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_was_neutered.Else(); 3063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(field); 3064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_was_neutered.End(); 3065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Pop(); 30673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 30683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHValue* HGraphBuilder::AddLoadJSBuiltin(int context_index) { 3070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* native_context = BuildGetNativeContext(); 3071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess function_access = HObjectAccess::ForContextSlot(context_index); 3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Add<HLoadNamedField>(native_context, nullptr, function_access); 3073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3074b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3075f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, 3076f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch bool track_positions) 3077f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch : HGraphBuilder(info, CallInterfaceDescriptor(), track_positions), 3078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state_(NULL), 3079c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch initial_function_state_(this, info, NORMAL_RETURN, -1, 30803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode::kAllow), 3081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context_(NULL), 3082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_scope_(NULL), 3083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inlined_count_(0), 3084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch globals_(10, info->zone()), 3085bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch osr_(new (info->zone()) HOsrBuilder(this)), 3086bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch bounds_(info->zone()) { 3087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This is not initialized in the initializer list because the 3088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // constructor for the initial state relies on function_state_ == NULL 3089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to know it's the initial state. 3090958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function_state_ = &initial_function_state_; 3091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InitializeAstVisitor(info->isolate()); 3092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3093b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 309469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HOptimizedGraphBuilder::CreateJoin(HBasicBlock* first, 3096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* second, 3097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId join_id) { 3098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (first == NULL) { 3099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return second; 3100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (second == NULL) { 3101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return first; 3102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join_block = graph()->CreateBasicBlock(); 3104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(first, join_block); 3105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(second, join_block); 3106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch join_block->SetJoinId(join_id); 3107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return join_block; 3108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 311069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HOptimizedGraphBuilder::JoinContinue(IterationStatement* statement, 3112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BailoutId continue_id, 3113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* exit_block, 3114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* continue_block) { 3115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (continue_block != NULL) { 3116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (exit_block != NULL) Goto(exit_block, continue_block); 3117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch continue_block->SetJoinId(continue_id); 3118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return continue_block; 3119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return exit_block; 3121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HOptimizedGraphBuilder::CreateLoop(IterationStatement* statement, 3125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_entry, 3126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* body_exit, 3127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_successor, 3128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* break_block) { 3129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (body_exit != NULL) Goto(body_exit, loop_entry); 3130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_entry->PostProcessLoopHeader(statement); 3131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (break_block != NULL) { 3132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (loop_successor != NULL) Goto(loop_successor, break_block); 3133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_block->SetJoinId(statement->ExitId()); 3134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return break_block; 31357d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch } 3136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return loop_successor; 31377d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch} 31387d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch 31397d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch 3140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Build a new loop header block and set it as the current block. 3141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry() { 3142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_entry = CreateLoopHeaderBlock(); 3143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(loop_entry); 3144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(loop_entry); 3145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return loop_entry; 3146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry( 3150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IterationStatement* statement) { 31513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HBasicBlock* loop_entry; 31523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 31533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (osr()->HasOsrEntryAt(statement)) { 31543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch loop_entry = osr()->BuildOsrLoopEntry(statement); 31553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (function_state()->IsInsideDoExpressionScope()) { 31563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Bailout(kDoExpressionUnmodelable); 31573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 31583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 31593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch loop_entry = BuildLoopEntry(); 31603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 3161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return loop_entry; 3162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HBasicBlock::FinishExit(HControlInstruction* instruction, 3166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SourcePosition position) { 3167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Finish(instruction, position); 3168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearEnvironment(); 3169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os, const HBasicBlock& b) { 3173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return os << "B" << b.block_id(); 3174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3176109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochHGraph::HGraph(CompilationInfo* info, CallInterfaceDescriptor descriptor) 3177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : isolate_(info->isolate()), 3178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_block_id_(0), 3179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_block_(NULL), 3180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocks_(8, info->zone()), 3181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values_(16, info->zone()), 3182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch phi_list_(NULL), 3183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_instructions_(NULL), 3184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr_(NULL), 3185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info_(info), 3186109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch descriptor_(descriptor), 3187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone_(info->zone()), 3188bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch allow_code_motion_(false), 3189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_optimistic_licm_(false), 3190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch depends_on_empty_array_proto_elements_(false), 3191f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch depends_on_string_length_overflow_(false), 3192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch type_change_checksum_(0), 3193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch maximum_environment_size_(0), 3194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch no_side_effects_scope_count_(0), 3195c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch disallow_adding_new_values_(false) { 3196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->IsStub()) { 3197109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // For stubs, explicitly add the context to the environment. 3198f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch start_environment_ = 3199f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch new (zone_) HEnvironment(zone_, descriptor.GetParameterCount() + 1); 3200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch start_environment_ = 3202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); 3203b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch start_environment_->set_ast_id(BailoutId::FunctionContext()); 3205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_block_ = CreateBasicBlock(); 3206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_block_->SetInitialEnvironment(start_environment_); 3207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HGraph::CreateBasicBlock() { 3211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* result = new(zone()) HBasicBlock(this); 3212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocks_.Add(result, zone()); 3213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 3214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 32153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3216257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraph::FinalizeUniqueness() { 3218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 3219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < blocks()->length(); ++i) { 3220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { 3221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch it.Current()->FinalizeUniqueness(); 3222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3226257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Block ordering was implemented with two mutually recursive methods, 3228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// HGraph::Postorder and HGraph::PostorderLoopBlocks. 3229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The recursion could lead to stack overflow so the algorithm has been 3230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// implemented iteratively. 3231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// At a high level the algorithm looks like this: 3232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Postorder(block, loop_header) : { 3234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// if (block has already been visited or is of another loop) return; 3235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// mark block as visited; 3236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// if (block is a loop header) { 3237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// VisitLoopMembers(block, loop_header); 3238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// VisitSuccessorsOfLoopHeader(block); 3239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } else { 3240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// VisitSuccessors(block) 3241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 3242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// put block in result list; 3243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 3244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// VisitLoopMembers(block, outer_loop_header) { 3246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// foreach (block b in block loop members) { 3247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// VisitSuccessorsOfLoopMember(b, outer_loop_header); 3248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// if (b is loop header) VisitLoopMembers(b); 3249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 3250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 3251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// VisitSuccessorsOfLoopMember(block, outer_loop_header) { 3253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// foreach (block b in block successors) Postorder(b, outer_loop_header) 3254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 3255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// VisitSuccessorsOfLoopHeader(block) { 3257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// foreach (block b in block successors) Postorder(b, block) 3258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 3259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// VisitSuccessors(block, loop_header) { 3261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// foreach (block b in block successors) Postorder(b, loop_header) 3262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 3263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The ordering is started calling Postorder(entry, NULL). 3265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Each instance of PostorderProcessor represents the "stack frame" of the 3267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// recursion, and particularly keeps the state of the loop (iteration) of the 3268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// "Visit..." function it represents. 3269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// To recycle memory we keep all the frames in a double linked list but 3270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// this means that we cannot use constructors to initialize the frames. 3271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PostorderProcessor : public ZoneObject { 3273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 3274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Back link (towards the stack bottom). 3275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* parent() {return father_; } 3276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Forward link (towards the stack top). 3277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* child() {return child_; } 3278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block() { return block_; } 3279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoopInformation* loop() { return loop_; } 3280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_header() { return loop_header_; } 3281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static PostorderProcessor* CreateEntryProcessor(Zone* zone, 3283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block) { 3284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* result = new(zone) PostorderProcessor(NULL); 3285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result->SetupSuccessors(zone, block, NULL); 3286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* PerformStep(Zone* zone, 3289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<HBasicBlock*>* order) { 3290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* next = 3291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PerformNonBacktrackingStep(zone, order); 3292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (next != NULL) { 3293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return next; 3294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Backtrack(zone, order); 3296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 3300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit PostorderProcessor(PostorderProcessor* father) 3301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : father_(father), child_(NULL), successor_iterator(NULL) { } 3302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Each enum value states the cycle whose state is kept by this instance. 3304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum LoopKind { 3305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NONE, 3306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SUCCESSORS, 3307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SUCCESSORS_OF_LOOP_HEADER, 3308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOOP_MEMBERS, 3309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SUCCESSORS_OF_LOOP_MEMBER 3310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 3311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Each "Setup..." method is like a constructor for a cycle state. 3313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* SetupSuccessors(Zone* zone, 3314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block, 3315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_header) { 3316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block == NULL || block->IsOrdered() || 3317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block->parent_loop_header() != loop_header) { 3318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind_ = NONE; 3319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_ = NULL; 3320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_ = NULL; 3321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_header_ = NULL; 3322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return this; 3323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_ = block; 3325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_ = NULL; 3326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block->MarkAsOrdered(); 3327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block->IsLoopHeader()) { 3329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind_ = SUCCESSORS_OF_LOOP_HEADER; 3330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_header_ = block; 3331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeSuccessors(); 3332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* result = Push(zone); 3333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result->SetupLoopMembers(zone, block, block->loop_information(), 3334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_header); 3335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(block->IsFinished()); 3337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind_ = SUCCESSORS; 3338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_header_ = loop_header; 3339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeSuccessors(); 3340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return this; 3341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* SetupLoopMembers(Zone* zone, 3346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block, 3347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoopInformation* loop, 3348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_header) { 3349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind_ = LOOP_MEMBERS; 3350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_ = block; 3351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_ = loop; 3352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_header_ = loop_header; 3353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeLoopMembers(); 3354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return this; 3355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* SetupSuccessorsOfLoopMember( 3358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block, 3359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoopInformation* loop, 3360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_header) { 3361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind_ = SUCCESSORS_OF_LOOP_MEMBER; 3362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_ = block; 3363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_ = loop; 3364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_header_ = loop_header; 3365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeSuccessors(); 3366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return this; 3367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This method "allocates" a new stack frame. 3370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* Push(Zone* zone) { 3371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (child_ == NULL) { 3372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch child_ = new(zone) PostorderProcessor(this); 3373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return child_; 3375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClosePostorder(ZoneList<HBasicBlock*>* order, Zone* zone) { 3378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(block_->end()->FirstSuccessor() == NULL || 3379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch order->Contains(block_->end()->FirstSuccessor()) || 3380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_->end()->FirstSuccessor()->IsLoopHeader()); 3381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(block_->end()->SecondSuccessor() == NULL || 3382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch order->Contains(block_->end()->SecondSuccessor()) || 3383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_->end()->SecondSuccessor()->IsLoopHeader()); 3384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch order->Add(block_, zone); 3385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This method is the basic block to walk up the stack. 3388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* Pop(Zone* zone, 3389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<HBasicBlock*>* order) { 3390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (kind_) { 3391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case SUCCESSORS: 3392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case SUCCESSORS_OF_LOOP_HEADER: 3393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClosePostorder(order, zone); 3394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return father_; 3395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LOOP_MEMBERS: 3396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return father_; 3397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case SUCCESSORS_OF_LOOP_MEMBER: 3398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block()->IsLoopHeader() && block() != loop_->loop_header()) { 3399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // In this case we need to perform a LOOP_MEMBERS cycle so we 3400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // initialize it and return this instead of father. 3401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SetupLoopMembers(zone, block(), 3402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block()->loop_information(), loop_header_); 3403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return father_; 3405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case NONE: 3407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return father_; 3408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 3410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 3411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3412b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Walks up the stack. 3414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* Backtrack(Zone* zone, 3415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<HBasicBlock*>* order) { 3416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* parent = Pop(zone, order); 3417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (parent != NULL) { 3418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* next = 3419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch parent->PerformNonBacktrackingStep(zone, order); 3420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (next != NULL) { 3421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return next; 3422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch parent = parent->Pop(zone, order); 3424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3425257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 3426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 3427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3428b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* PerformNonBacktrackingStep( 3430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone, 3431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<HBasicBlock*>* order) { 3432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* next_block; 3433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (kind_) { 3434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case SUCCESSORS: 3435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_block = AdvanceSuccessors(); 3436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (next_block != NULL) { 3437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* result = Push(zone); 3438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result->SetupSuccessors(zone, next_block, loop_header_); 3439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 3441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case SUCCESSORS_OF_LOOP_HEADER: 3442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_block = AdvanceSuccessors(); 3443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (next_block != NULL) { 3444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* result = Push(zone); 3445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result->SetupSuccessors(zone, next_block, block()); 3446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 3448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LOOP_MEMBERS: 3449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_block = AdvanceLoopMembers(); 3450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (next_block != NULL) { 3451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* result = Push(zone); 3452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result->SetupSuccessorsOfLoopMember(next_block, 3453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_, loop_header_); 3454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 3456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case SUCCESSORS_OF_LOOP_MEMBER: 3457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_block = AdvanceSuccessors(); 3458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (next_block != NULL) { 3459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* result = Push(zone); 3460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result->SetupSuccessors(zone, next_block, loop_header_); 3461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 3463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case NONE: 3464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 3465257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 3466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 3467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The following two methods implement a "foreach b in successors" cycle. 3470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void InitializeSuccessors() { 3471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_index = 0; 3472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_length = 0; 3473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch successor_iterator = HSuccessorIterator(block_->end()); 3474b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* AdvanceSuccessors() { 3477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!successor_iterator.Done()) { 3478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* result = successor_iterator.Current(); 3479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch successor_iterator.Advance(); 3480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 3481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 3483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The following two methods implement a "foreach b in loop members" cycle. 3486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void InitializeLoopMembers() { 3487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_index = 0; 3488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_length = loop_->blocks()->length(); 3489e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 34903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* AdvanceLoopMembers() { 3492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (loop_index < loop_length) { 3493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* result = loop_->blocks()->at(loop_index); 3494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_index++; 3495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 3496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 3498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 34993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 35003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopKind kind_; 3502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* father_; 3503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* child_; 3504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoopInformation* loop_; 3505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block_; 3506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_header_; 3507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int loop_index; 3508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int loop_length; 3509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HSuccessorIterator successor_iterator; 3510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 3511e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3512e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraph::OrderBlocks() { 3514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompilationPhase phase("H_Block ordering", info()); 3515e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 3517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initially the blocks must not be ordered. 3518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < blocks_.length(); ++i) { 3519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!blocks_[i]->IsOrdered()); 3520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 3522e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor* postorder = 3524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostorderProcessor::CreateEntryProcessor(zone(), blocks_[0]); 3525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocks_.Rewind(0); 3526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (postorder) { 3527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch postorder = postorder->PerformStep(zone(), &blocks_); 3528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 3531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Now all blocks must be marked as ordered. 3532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < blocks_.length(); ++i) { 3533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(blocks_[i]->IsOrdered()); 3534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 3536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Reverse block list and assign block IDs. 3538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0, j = blocks_.length(); --j >= i; ++i) { 3539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* bi = blocks_[i]; 3540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* bj = blocks_[j]; 3541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bi->set_block_id(j); 3542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bj->set_block_id(i); 3543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocks_[i] = bj; 3544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocks_[j] = bi; 3545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraph::AssignDominators() { 3550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhase phase("H_Assign dominators", this); 3551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < blocks_.length(); ++i) { 3552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block = blocks_[i]; 3553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block->IsLoopHeader()) { 3554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Only the first predecessor of a loop header is from outside the loop. 3555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // All others are back edges, and thus cannot dominate the loop header. 3556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block->AssignCommonDominator(block->predecessors()->first()); 3557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block->AssignLoopSuccessorDominators(); 3558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 3559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int j = blocks_[i]->predecessors()->length() - 1; j >= 0; --j) { 3560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j)); 3561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3563b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3564b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HGraph::CheckArgumentsPhiUses() { 3568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int block_count = blocks_.length(); 3569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < block_count; ++i) { 3570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int j = 0; j < blocks_[i]->phis()->length(); ++j) { 3571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhi* phi = blocks_[i]->phis()->at(j); 3572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We don't support phi uses of arguments for now. 3573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (phi->CheckFlag(HValue::kIsArguments)) return false; 3574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 3577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3579b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HGraph::CheckConstPhiUses() { 3581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int block_count = blocks_.length(); 3582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < block_count; ++i) { 3583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int j = 0; j < blocks_[i]->phis()->length(); ++j) { 3584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhi* phi = blocks_[i]->phis()->at(j); 3585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check for the hole value (from an uninitialized const). 3586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int k = 0; k < phi->OperandCount(); k++) { 3587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (phi->OperandAt(k) == GetConstantHole()) return false; 3588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 359044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 3591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 3592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 359344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3594b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraph::CollectPhis() { 3596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int block_count = blocks_.length(); 3597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch phi_list_ = new(zone()) ZoneList<HPhi*>(block_count, zone()); 3598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < block_count; ++i) { 3599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int j = 0; j < blocks_[i]->phis()->length(); ++j) { 3600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhi* phi = blocks_[i]->phis()->at(j); 3601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch phi_list_->Add(phi, zone()); 3602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 36053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Implementation of utility class to encapsulate the translation state for 3608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// a (possibly inlined) function. 3609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochFunctionState::FunctionState(HOptimizedGraphBuilder* owner, 3610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompilationInfo* info, InliningKind inlining_kind, 36113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int inlining_id, TailCallMode tail_call_mode) 3612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : owner_(owner), 3613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compilation_info_(info), 3614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call_context_(NULL), 3615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inlining_kind_(inlining_kind), 36163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch tail_call_mode_(tail_call_mode), 3617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_return_(NULL), 3618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch test_context_(NULL), 3619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_(NULL), 3620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_object_(NULL), 3621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_elements_(NULL), 3622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inlining_id_(inlining_id), 3623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch outer_source_position_(SourcePosition::Unknown()), 36243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch do_expression_scope_count_(0), 3625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer_(owner->function_state()) { 3626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (outer_ != NULL) { 3627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // State for an inline function. 3628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (owner->ast_context()->IsTest()) { 3629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); 3630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); 3631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_true->MarkAsInlineReturnTarget(owner->current_block()); 3632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_false->MarkAsInlineReturnTarget(owner->current_block()); 3633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestContext* outer_test_context = TestContext::cast(owner->ast_context()); 3634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* cond = outer_test_context->condition(); 3635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The AstContext constructor pushed on the context stack. This newed 3636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instance is the reason that AstContext can't be BASE_EMBEDDED. 3637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch test_context_ = new TestContext(owner, cond, if_true, if_false); 3638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_return_ = owner->graph()->CreateBasicBlock(); 3640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_return()->MarkAsInlineReturnTarget(owner->current_block()); 3641b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set this after possibly allocating a new TestContext above. 3643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call_context_ = owner->ast_context(); 36443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3645592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 3646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Push on the state stack. 3647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner->set_function_state(this); 3648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3649f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (owner->is_tracking_positions()) { 3650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer_source_position_ = owner->source_position(); 3651c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch owner->EnterInlinedSource(inlining_id); 3652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner->SetSourcePosition(info->shared_info()->start_position()); 3653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 36553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochFunctionState::~FunctionState() { 3658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete test_context_; 3659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner_->set_function_state(outer_); 36603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3661f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (owner_->is_tracking_positions()) { 3662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner_->set_source_position(outer_source_position_); 3663c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch owner_->EnterInlinedSource(outer_->inlining_id()); 36643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 36663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Implementation of utility classes to represent an expression's context in 3669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the AST. 3670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) 3671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : owner_(owner), 3672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind_(kind), 3673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer_(owner->ast_context()), 3674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch typeof_mode_(NOT_INSIDE_TYPEOF) { 3675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner->set_ast_context(this); // Push. 3676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 36773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(JS_FUNCTION, owner->environment()->frame_type()); 3678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch original_length_ = owner->environment()->length(); 3679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 3680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 36813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstContext::~AstContext() { 3684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner_->set_ast_context(outer_); // Pop. 3685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 36863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochEffectContext::~EffectContext() { 36893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(owner()->HasStackOverflow() || owner()->current_block() == NULL || 3690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (owner()->environment()->length() == original_length_ && 36913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch (owner()->environment()->frame_type() == JS_FUNCTION || 36923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch owner()->environment()->frame_type() == TAIL_CALLER_FUNCTION))); 3693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 36943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochValueContext::~ValueContext() { 36973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(owner()->HasStackOverflow() || owner()->current_block() == NULL || 3698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (owner()->environment()->length() == original_length_ + 1 && 36993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch (owner()->environment()->frame_type() == JS_FUNCTION || 37003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch owner()->environment()->frame_type() == TAIL_CALLER_FUNCTION))); 3701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 370244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 370344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid EffectContext::ReturnValue(HValue* value) { 3705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The value is simply ignored. 3706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 37073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ValueContext::ReturnValue(HValue* value) { 3710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The value is tracked in the bailout environment, and communicated 3711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // through the environment as the result of the expression. 3712958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (value->CheckFlag(HValue::kIsArguments)) { 3713958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (flag_ == ARGUMENTS_FAKED) { 3714958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value = owner()->graph()->GetConstantUndefined(); 3715958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (!arguments_allowed()) { 3716958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier owner()->Bailout(kBadValueContextForArgumentsValue); 3717958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 3718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Push(value); 3720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 372144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3722b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid TestContext::ReturnValue(HValue* value) { 3724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildBranch(value); 3725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3726b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid EffectContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 3729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!instr->IsControlInstruction()); 3730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->AddInstruction(instr); 3731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 3732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 3733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid EffectContext::ReturnControl(HControlInstruction* instr, 3738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id) { 3739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!instr->HasObservableSideEffects()); 3740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); 3741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); 3742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetSuccessorAt(0, empty_true); 3743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetSuccessorAt(1, empty_false); 3744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->FinishCurrentBlock(instr); 3745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id); 3746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(join); 3747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid EffectContext::ReturnContinuation(HIfContinuation* continuation, 3751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id) { 3752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* true_branch = NULL; 3753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* false_branch = NULL; 3754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continuation->Continue(&true_branch, &false_branch); 3755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!continuation->IsTrueReachable()) { 3756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(false_branch); 3757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (!continuation->IsFalseReachable()) { 3758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(true_branch); 3759b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 3760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = owner()->CreateJoin(true_branch, false_branch, ast_id); 3761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(join); 3762b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3763b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3764b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 376544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 3767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!instr->IsControlInstruction()); 3768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 3769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return owner()->Bailout(kBadValueContextForArgumentsObjectValue); 3770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->AddInstruction(instr); 3772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Push(instr); 3773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 3774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 3775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3776b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3777b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3778b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { 3780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!instr->HasObservableSideEffects()); 3781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 3782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return owner()->Bailout(kBadValueContextForArgumentsObjectValue); 3783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock(); 3785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock(); 3786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetSuccessorAt(0, materialize_true); 3787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetSuccessorAt(1, materialize_false); 3788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->FinishCurrentBlock(instr); 3789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(materialize_true); 3790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Push(owner()->graph()->GetConstantTrue()); 3791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(materialize_false); 3792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Push(owner()->graph()->GetConstantFalse()); 3793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = 3794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->CreateJoin(materialize_true, materialize_false, ast_id); 3795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(join); 3796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3797b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3798b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ValueContext::ReturnContinuation(HIfContinuation* continuation, 3800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id) { 3801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* materialize_true = NULL; 3802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* materialize_false = NULL; 3803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continuation->Continue(&materialize_true, &materialize_false); 3804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (continuation->IsTrueReachable()) { 3805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(materialize_true); 3806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Push(owner()->graph()->GetConstantTrue()); 3807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(materialize_true); 3808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (continuation->IsFalseReachable()) { 3810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(materialize_false); 3811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Push(owner()->graph()->GetConstantFalse()); 3812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(materialize_false); 3813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (continuation->TrueAndFalseReachable()) { 3815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = 3816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->CreateJoin(materialize_true, materialize_false, ast_id); 3817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(join); 3818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3820b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 38213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 3823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!instr->IsControlInstruction()); 3824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HOptimizedGraphBuilder* builder = owner(); 3825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder->AddInstruction(instr); 3826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We expect a simulate after every expression with side effects, though 3827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this one isn't actually needed (and wouldn't work if it were targeted). 3828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 3829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder->Push(instr); 3830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 3831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder->Pop(); 38325d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 3833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildBranch(instr); 3834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 38355d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 3836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { 3838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!instr->HasObservableSideEffects()); 3839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); 3840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); 3841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetSuccessorAt(0, empty_true); 3842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetSuccessorAt(1, empty_false); 3843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->FinishCurrentBlock(instr); 3844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Goto(empty_true, if_true(), owner()->function_state()); 3845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Goto(empty_false, if_false(), owner()->function_state()); 3846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(NULL); 3847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid TestContext::ReturnContinuation(HIfContinuation* continuation, 3851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id) { 3852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* true_branch = NULL; 3853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* false_branch = NULL; 3854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continuation->Continue(&true_branch, &false_branch); 3855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (continuation->IsTrueReachable()) { 3856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Goto(true_branch, if_true(), owner()->function_state()); 38573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (continuation->IsFalseReachable()) { 3859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->Goto(false_branch, if_false(), owner()->function_state()); 3860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_current_block(NULL); 3862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 38633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid TestContext::BuildBranch(HValue* value) { 3866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We expect the graph to be in edge-split form: there is no edge that 3867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // connects a branch node to a join node. We conservatively ensure that 3868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // property by always adding an empty block on the outgoing edges of this 3869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // branch. 3870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HOptimizedGraphBuilder* builder = owner(); 3871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { 3872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder->Bailout(kArgumentsObjectValueInATestContext); 3873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3874c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ToBooleanHints expected(condition()->to_boolean_types()); 3875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ReturnControl(owner()->New<HBranch>(value, expected), BailoutId::None()); 3876b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3877b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3878b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// HOptimizedGraphBuilder infrastructure for bailing out and checking bailouts. 3880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define CHECK_BAILOUT(call) \ 3881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch do { \ 3882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call; \ 3883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasStackOverflow()) return; \ 3884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } while (false) 3885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define CHECK_ALIVE(call) \ 3888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch do { \ 3889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call; \ 3890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasStackOverflow() || current_block() == NULL) return; \ 3891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } while (false) 3892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define CHECK_ALIVE_OR_RETURN(call, value) \ 3895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch do { \ 3896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call; \ 3897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasStackOverflow() || current_block() == NULL) return value; \ 3898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } while (false) 3899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::Bailout(BailoutReason reason) { 3902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_info()->AbortOptimization(reason); 3903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetStackOverflow(); 39043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 39053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 39063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitForEffect(Expression* expr) { 3908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EffectContext for_effect(this); 3909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(expr); 3910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3911e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitForValue(Expression* expr, 3914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArgumentsAllowedFlag flag) { 3915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ValueContext for_value(this, flag); 3916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(expr); 3917b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3918b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3919b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitForTypeOf(Expression* expr) { 3921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); 3922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for_value.set_typeof_mode(INSIDE_TYPEOF); 3923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(expr); 3924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 39253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3926e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitForControl(Expression* expr, 3928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* true_block, 3929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* false_block) { 3930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TestContext for_control(this, expr, true_block, false_block); 3931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(expr); 3932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3933e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitExpressions( 3936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Expression*>* exprs) { 3937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < exprs->length(); ++i) { 3938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(exprs->at(i))); 3939b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3940b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 3941b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3942b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3943958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid HOptimizedGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs, 3944958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ArgumentsAllowedFlag flag) { 3945958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < exprs->length(); ++i) { 3946958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(exprs->at(i), flag)); 3947b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3948958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 3949958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3950958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 3951958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool HOptimizedGraphBuilder::BuildGraph() { 395262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (IsDerivedConstructor(current_info()->literal()->kind())) { 3953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Bailout(kSuperReference); 3954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 3955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3957f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeclarationScope* scope = current_info()->scope(); 3958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetUpScope(scope); 3959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Add an edge to the body entry. This is warty: the graph's start 3961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // environment will be used by the Lithium translation as the initial 3962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // environment on graph entry, but it has now been mutated by the 3963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Hydrogen translation of the instructions in the start block. This 3964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // environment uses values which have not been defined yet. These 3965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Hydrogen instructions will then be replayed by the Lithium 3966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // translation, so they cannot have an environment effect. The edge to 3967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the body's entry block (along with some special logic for the start 3968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // block in HInstruction::InsertAfter) seals the start block from 3969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // getting unwanted instructions inserted. 3970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 3971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(kmillikin): Fix this. Stop mutating the initial environment. 3972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make the Hydrogen instructions in the initial block into Hydrogen 3973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // values (but not instructions), present in the initial environment and 3974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // not replayed by the Lithium translation. 3975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* initial_env = environment()->CopyWithoutHistory(); 3976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* body_entry = CreateBasicBlock(initial_env); 3977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(body_entry); 3978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_entry->SetJoinId(BailoutId::FunctionEntry()); 3979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(body_entry); 3980b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitDeclarations(scope->declarations()); 3982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(BailoutId::Declarations()); 3983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStackCheck>(HStackCheck::kFunctionEntry); 3985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitStatements(current_info()->literal()->body()); 3987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasStackOverflow()) return false; 3988b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3989257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (current_block() != NULL) { 3990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HReturn>(graph()->GetConstantUndefined()); 3991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 3992b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3993b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the checksum of the number of type info changes is the same as the 3995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // last time this function was compiled, then this recompile is likely not 3996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // due to missing/inadequate type feedback, but rather too aggressive 3997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // optimization. Disable optimistic LICM in that case. 3998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> unoptimized_code(current_info()->shared_info()->code()); 3999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(unoptimized_code->kind() == Code::FUNCTION); 4000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<TypeFeedbackInfo> type_info( 4001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); 4002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int checksum = type_info->own_type_change_checksum(); 4003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int composite_checksum = graph()->update_type_change_checksum(checksum); 4004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->set_use_optimistic_licm( 4005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !type_info->matches_inlined_type_change_checksum(composite_checksum)); 4006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch type_info->set_inlined_type_change_checksum(composite_checksum); 4007e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4008bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Set this predicate early to avoid handle deref during graph optimization. 4009bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch graph()->set_allow_code_motion( 4010bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch current_info()->IsStub() || 4011bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch current_info()->shared_info()->opt_count() + 1 < FLAG_max_opt_count); 4012bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 4013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Perform any necessary OSR-specific cleanups or changes to the graph. 4014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr()->FinishGraph(); 4015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 4017b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4018b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4019b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HGraph::Optimize(BailoutReason* bailout_reason) { 4021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OrderBlocks(); 4022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssignDominators(); 40233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We need to create a HConstant "zero" now so that GVN will fold every 4025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // zero-valued constant in the graph together. 4026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The constant is needed to make idef-based bounds check work: the pass 4027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // evaluates relations with "zero" and that zero cannot be created after GVN. 4028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetConstant0(); 4029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 4031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Do a full verify after building the graph and computing dominators. 4032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Verify(true); 4033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 40343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_analyze_environment_liveness && maximum_environment_size() != 0) { 4036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HEnvironmentLivenessAnalysisPhase>(); 40373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 40383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!CheckConstPhiUses()) { 4040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *bailout_reason = kUnsupportedPhiUseOfConstVariable; 4041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 4042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HRedundantPhiEliminationPhase>(); 4044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!CheckArgumentsPhiUses()) { 4045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *bailout_reason = kUnsupportedPhiUseOfArguments; 4046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 40473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 40483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find and mark unreachable code to simplify optimizations, especially gvn, 4050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // where unreachable code could unnecessarily defeat LICM. 4051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HMarkUnreachableBlocksPhase>(); 40523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>(); 4054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_use_escape_analysis) Run<HEscapeAnalysisPhase>(); 40553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_load_elimination) Run<HLoadEliminationPhase>(); 40573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CollectPhis(); 40593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (has_osr()) osr()->FinishOsrValues(); 40613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HInferRepresentationPhase>(); 40633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remove HSimulate instructions that have turned out not to be needed 4065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // after all by folding them into the following HSimulate. 4066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This must happen after inferring representations. 4067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HMergeRemovableSimulatesPhase>(); 40683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HRepresentationChangesPhase>(); 40703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HInferTypesPhase>(); 40723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Must be performed before canonicalization to ensure that Canonicalize 4074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with 4075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // zero. 4076958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Run<HUint32AnalysisPhase>(); 40773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_use_canonicalizing) Run<HCanonicalizePhase>(); 40793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_use_gvn) Run<HGlobalValueNumberingPhase>(); 40813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_check_elimination) Run<HCheckEliminationPhase>(); 40833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_store_elimination) Run<HStoreEliminationPhase>(); 40853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HRangeAnalysisPhase>(); 40873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Eliminate redundant stack checks on backwards branches. 4089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HStackCheckEliminationPhase>(); 40903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_array_bounds_checks_elimination) Run<HBoundsCheckEliminationPhase>(); 4092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_array_index_dehoisting) Run<HDehoistIndexComputationsPhase>(); 4093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>(); 40943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RestoreActualValues(); 4096b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find unreachable code a second time, GVN and other optimizations may have 4098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // made blocks unreachable that were previously reachable. 4099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Run<HMarkUnreachableBlocksPhase>(); 4100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 4102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraph::RestoreActualValues() { 4106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhase phase("H_Restore actual values", this); 4107b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int block_index = 0; block_index < blocks()->length(); block_index++) { 4109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block = blocks()->at(block_index); 41108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 4112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < block->phis()->length(); i++) { 4113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhi* phi = block->phis()->at(i); 4114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(phi->ActualValue() == phi); 4115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 41178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (HInstructionIterator it(block); !it.Done(); it.Advance()) { 4119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instruction = it.Current(); 4120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instruction->ActualValue() == instruction) continue; 4121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instruction->CheckFlag(HValue::kIsDead)) { 4122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The instruction was marked as deleted but left in the graph 4123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // as a control flow dependency point for subsequent 4124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instructions. 4125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instruction->DeleteAndReplaceWith(instruction->ActualValue()); 4126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(instruction->IsInformativeDefinition()); 4128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instruction->IsPurelyInformativeDefinition()) { 4129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); 4130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instruction->ReplaceAllUsesWith(instruction->ActualValue()); 4132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 41338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 41348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 41358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 4136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::PushArgumentsFromEnvironment(int count) { 4140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<HValue*> arguments(count, zone()); 4141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < count; ++i) { 4142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments.Add(Pop(), zone()); 41438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 4144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPushArguments* push_args = New<HPushArguments>(); 4146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!arguments.is_empty()) { 4147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch push_args->AddInput(arguments.RemoveLast()); 4148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(push_args); 4150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4151b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <class Instruction> 4154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { 4155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(call->argument_count()); 4156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return call; 4157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid HOptimizedGraphBuilder::SetUpScope(DeclarationScope* scope) { 4160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HEnvironment* prolog_env = environment(); 4161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int parameter_count = environment()->parameter_count(); 4162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ZoneList<HValue*> parameters(parameter_count, zone()); 4163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < parameter_count; ++i) { 4164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* parameter = Add<HParameter>(static_cast<unsigned>(i)); 4165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parameters.Add(parameter, zone()); 4166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Bind(i, parameter); 4167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant* undefined_constant = graph()->GetConstantUndefined(); 4170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Initialize specials and locals to undefined. 4171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = parameter_count + 1; i < environment()->length(); ++i) { 4172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Bind(i, undefined_constant); 4173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HPrologue>(); 4175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HEnvironment* initial_env = environment()->CopyWithoutHistory(); 4177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HBasicBlock* body_entry = CreateBasicBlock(initial_env); 4178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GotoNoSimulate(body_entry); 4179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_current_block(body_entry); 4180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Initialize context of prolog environment to undefined. 4182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch prolog_env->BindContext(undefined_constant); 4183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // First special is HContext. 4185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* context = Add<HContext>(); 4186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->BindContext(context); 4187e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create an arguments object containing the initial parameters. Set the 4189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // initial values of parameters including "this" having parameter index 0. 4190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(scope->num_parameters() + 1, parameter_count); 4191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HArgumentsObject* arguments_object = New<HArgumentsObject>(parameter_count); 4192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < parameter_count; ++i) { 4193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* parameter = parameters.at(i); 4194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_object->AddArgument(parameter, zone()); 4195257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(arguments_object); 4198e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle the arguments and arguments shadow variables specially (they do 4200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // not have declarations). 4201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (scope->arguments() != NULL) { 4202109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch environment()->Bind(scope->arguments(), arguments_object); 4203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4205f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (scope->rest_parameter() != nullptr) { 4206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Bailout(kRestParameter); 420744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 4208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (scope->this_function_var() != nullptr || 4210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch scope->new_target_var() != nullptr) { 4211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Bailout(kSuperReference); 4212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4213b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Trace the call. 4215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_trace && top_info()->IsOptimizing()) { 4216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kTraceEnter), 0); 4217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 42181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 42191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 42201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { 4222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < statements->length(); i++) { 4223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Statement* stmt = statements->at(i); 4224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(Visit(stmt)); 4225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stmt->IsJump()) break; 42261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 4227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitBlock(Block* stmt) { 4231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* outer_scope = scope(); 4236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* scope = stmt->scope(); 4237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueInfo break_info(stmt, outer_scope); 4238589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 4239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { BreakAndContinueScope push(&break_info, this); 4240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (scope != NULL) { 4241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (scope->NeedsContext()) { 4242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Load the function object. 4243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeclarationScope* declaration_scope = scope->GetDeclarationScope(); 4244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* function; 4245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* outer_context = environment()->context(); 4246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (declaration_scope->is_script_scope() || 4247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch declaration_scope->is_eval_scope()) { 4248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch function = new (zone()) 4249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HLoadContextSlot(outer_context, Context::CLOSURE_INDEX, 4250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HLoadContextSlot::kNoCheck); 4251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 4252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch function = New<HThisFunction>(); 4253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddInstruction(function); 4255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allocate a block context and store it to the stack frame. 4256f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HValue* scope_info = Add<HConstant>(scope->scope_info()); 4257109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Add<HPushArguments>(scope_info, function); 4258109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HInstruction* inner_context = Add<HCallRuntime>( 4259109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Runtime::FunctionForId(Runtime::kPushBlockContext), 2); 4260109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inner_context->SetFlag(HValue::kHasNoObservableSideEffects); 4261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_scope(scope); 4262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->BindContext(inner_context); 4263589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 4264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitDeclarations(scope->declarations()); 4265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSimulate(stmt->DeclsId(), REMOVABLE_SIMULATE); 4266589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 4267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitStatements(stmt->statements())); 4268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_scope(outer_scope); 4270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (scope != NULL && current_block() != NULL && 4271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch scope->ContextLocalCount() > 0) { 4272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* inner_context = environment()->context(); 4273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* outer_context = Add<HLoadNamedField>( 4274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inner_context, nullptr, 4275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 4276589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 4277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier environment()->BindContext(outer_context); 4278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* break_block = break_info.break_block(); 4280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (break_block != NULL) { 4281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_block() != NULL) Goto(break_block); 4282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_block->SetJoinId(stmt->ExitId()); 4283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(break_block); 4284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitExpressionStatement( 4289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExpressionStatement* stmt) { 4290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForEffect(stmt->expression()); 4294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) { 4298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4302b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::VisitSloppyBlockFunctionStatement( 4305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SloppyBlockFunctionStatement* stmt) { 4306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Visit(stmt->statement()); 4307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) { 4311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stmt->condition()->ToBooleanIsTrue()) { 4315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(stmt->ThenId()); 4316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(stmt->then_statement()); 4317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (stmt->condition()->ToBooleanIsFalse()) { 4318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(stmt->ElseId()); 4319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(stmt->else_statement()); 4320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* cond_true = graph()->CreateBasicBlock(); 4322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* cond_false = graph()->CreateBasicBlock(); 4323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitForControl(stmt->condition(), cond_true, cond_false)); 43243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Technically, we should be able to handle the case when one side of 43263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // the test is not connected, but this can trip up liveness analysis 43273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // if we did not fully connect the test context based on some optimistic 43283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // assumption. If such an assumption was violated, we would end up with 43293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // an environment with optimized-out values. So we should always 43303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // conservatively connect the test context. 43313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CHECK(cond_true->HasPredecessor()); 43323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CHECK(cond_false->HasPredecessor()); 43333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cond_true->SetJoinId(stmt->ThenId()); 43353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch set_current_block(cond_true); 43363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CHECK_BAILOUT(Visit(stmt->then_statement())); 43373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cond_true = current_block(); 43383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 43393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cond_false->SetJoinId(stmt->ElseId()); 43403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch set_current_block(cond_false); 43413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CHECK_BAILOUT(Visit(stmt->else_statement())); 43423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cond_false = current_block(); 43433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId()); 4345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(join); 4346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 43473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 43483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get( 4351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakableStatement* stmt, 4352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakType type, 4353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope** scope, 4354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int* drop_extra) { 4355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *drop_extra = 0; 4356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueScope* current = this; 4357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (current != NULL && current->info()->target() != stmt) { 4358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *drop_extra += current->info()->drop_extra(); 4359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current = current->next(); 4360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current != NULL); // Always found (unless stack is malformed). 4362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *scope = current->info()->scope(); 43633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type == BREAK) { 4365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *drop_extra += current->info()->drop_extra(); 43663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 43673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* block = NULL; 4369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (type) { 4370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case BREAK: 4371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block = current->info()->break_block(); 4372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block == NULL) { 4373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block = current->owner()->graph()->CreateBasicBlock(); 4374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current->info()->set_break_block(block); 4375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 4377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CONTINUE: 4379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block = current->info()->continue_block(); 4380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block == NULL) { 4381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block = current->owner()->graph()->CreateBasicBlock(); 4382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current->info()->set_continue_block(block); 4383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 4385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return block; 4388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitContinueStatement( 4392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ContinueStatement* stmt) { 4393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 43963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 43973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (function_state()->IsInsideDoExpressionScope()) { 43983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return Bailout(kDoExpressionUnmodelable); 43993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 44003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 4401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* outer_scope = NULL; 4402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* inner_scope = scope(); 4403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int drop_extra = 0; 4404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* continue_block = break_scope()->Get( 4405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stmt->target(), BreakAndContinueScope::CONTINUE, 4406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &outer_scope, &drop_extra); 4407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = environment()->context(); 4408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(drop_extra); 4409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int context_pop_count = inner_scope->ContextChainLength(outer_scope); 4410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (context_pop_count > 0) { 4411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (context_pop_count-- > 0) { 4412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* context_instruction = Add<HLoadNamedField>( 4413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier context, nullptr, 4414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 4415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context = context_instruction; 4416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->BindContext(context); 4418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 441944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 4420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(continue_block); 4421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 4422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4424b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { 4426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 44293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 44303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (function_state()->IsInsideDoExpressionScope()) { 44313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return Bailout(kDoExpressionUnmodelable); 44323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 44333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 4434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* outer_scope = NULL; 4435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* inner_scope = scope(); 4436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int drop_extra = 0; 4437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* break_block = break_scope()->Get( 4438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stmt->target(), BreakAndContinueScope::BREAK, 4439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &outer_scope, &drop_extra); 4440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = environment()->context(); 4441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(drop_extra); 4442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int context_pop_count = inner_scope->ContextChainLength(outer_scope); 4443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (context_pop_count > 0) { 4444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (context_pop_count-- > 0) { 4445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* context_instruction = Add<HLoadNamedField>( 4446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier context, nullptr, 4447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 4448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context = context_instruction; 44493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->BindContext(context); 44513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(break_block); 4453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 4454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 44553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 44563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { 4458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FunctionState* state = function_state(); 4462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AstContext* context = call_context(); 4463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (context == NULL) { 4464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Not an inlined return, so an actual one. 4465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(stmt->expression())); 4466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result = environment()->Pop(); 4467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HReturn>(result); 4468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { 4469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return from an inlined construct call. In a test context the return value 4470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // will always evaluate to true, in a value context the return value needs 4471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to be a JSObject. 4472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (context->IsTest()) { 4473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForEffect(stmt->expression())); 4474109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch context->ReturnValue(graph()->GetConstantTrue()); 4475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (context->IsEffect()) { 4476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForEffect(stmt->expression())); 4477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(function_return(), state); 4478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(context->IsValue()); 4480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(stmt->expression())); 4481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* return_value = Pop(); 4482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver = environment()->arguments_environment()->Lookup(0); 4483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HHasInstanceTypeAndBranch* typecheck = 4484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HHasInstanceTypeAndBranch>(return_value, 4485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FIRST_JS_RECEIVER_TYPE, 4486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LAST_JS_RECEIVER_TYPE); 4487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_spec_object = graph()->CreateBasicBlock(); 4488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* not_spec_object = graph()->CreateBasicBlock(); 4489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typecheck->SetSuccessorAt(0, if_spec_object); 4490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typecheck->SetSuccessorAt(1, not_spec_object); 4491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(typecheck); 4492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddLeaveInlined(if_spec_object, return_value, state); 4493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddLeaveInlined(not_spec_object, receiver, state); 4494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (state->inlining_kind() == SETTER_CALL_RETURN) { 4496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return from an inlined setter call. The returned value is never used, the 4497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // value of an assignment is always the value of the RHS of the assignment. 4498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForEffect(stmt->expression())); 4499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (context->IsTest()) { 4500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* rhs = environment()->arguments_environment()->Lookup(1); 4501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context->ReturnValue(rhs); 4502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (context->IsEffect()) { 4503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(function_return(), state); 4504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(context->IsValue()); 4506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* rhs = environment()->arguments_environment()->Lookup(1); 4507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddLeaveInlined(rhs, state); 4508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 45093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 4510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return from a normal inlined function. Visit the subexpression in the 4511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // expression context of the call. 4512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (context->IsTest()) { 4513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestContext* test = TestContext::cast(context); 4514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForControl(stmt->expression(), test->if_true(), test->if_false()); 4515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (context->IsEffect()) { 4516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Visit in value context and ignore the result. This is needed to keep 4517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // environment in sync with full-codegen since some visitors (e.g. 4518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // VisitCountOperation) use the operand stack differently depending on 4519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // context. 4520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(stmt->expression())); 4521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(); 4522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(function_return(), state); 4523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(context->IsValue()); 4525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(stmt->expression())); 4526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddLeaveInlined(Pop(), state); 45273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 4530b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4531b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitWithStatement(WithStatement* stmt) { 4534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kWithStatement); 4538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { 4542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<CaseClause*>* clauses = stmt->cases(); 4547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int clause_count = clauses->length(); 4548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<HBasicBlock*> body_blocks(clause_count, zone()); 4549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(stmt->tag())); 4551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(stmt->EntryId()); 4552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* tag_value = Top(); 4553f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AstType* tag_type = bounds_.get(stmt->tag()).lower; 4554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 1. Build all the tests, with dangling true branches 4556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId default_id = BailoutId::None(); 4557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < clause_count; ++i) { 4558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CaseClause* clause = clauses->at(i); 4559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (clause->is_default()) { 4560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_blocks.Add(NULL, zone()); 4561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (default_id.IsNone()) default_id = clause->EntryId(); 4562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue; 4563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 45643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generate a compare and branch. 4566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_BAILOUT(VisitForValue(clause->label())); 4567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (current_block() == NULL) return Bailout(kUnsupportedSwitchStatement); 4568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* label_value = Pop(); 45693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4570f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AstType* label_type = bounds_.get(clause->label()).lower; 4571f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AstType* combined_type = clause->compare_type(); 4572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HControlInstruction* compare = BuildCompareInstruction( 4573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::EQ_STRICT, tag_value, label_value, tag_type, label_type, 4574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch combined_type, 4575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScriptPositionToSourcePosition(stmt->tag()->position()), 4576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScriptPositionToSourcePosition(clause->label()->position()), 4577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PUSH_BEFORE_SIMULATE, clause->id()); 45783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* next_test_block = graph()->CreateBasicBlock(); 4580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* body_block = graph()->CreateBasicBlock(); 4581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_blocks.Add(body_block, zone()); 4582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare->SetSuccessorAt(0, body_block); 4583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare->SetSuccessorAt(1, next_test_block); 4584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(compare); 45853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(body_block); 4587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // tag_value 45885d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 4589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(next_test_block); 4590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 45915d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 4592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Save the current block to use for the default or to join with the 4593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // exit. 4594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* last_block = current_block(); 4595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // tag_value 4596b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2. Loop over the clauses and the linked list of tests in lockstep, 4598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // translating the clause bodies. 4599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* fall_through_block = NULL; 4600b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueInfo break_info(stmt, scope()); 4602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { BreakAndContinueScope push(&break_info, this); 4603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < clause_count; ++i) { 4604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CaseClause* clause = clauses->at(i); 4605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Identify the block where normal (non-fall-through) control flow 4607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // goes to. 4608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* normal_block = NULL; 4609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (clause->is_default()) { 4610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (last_block == NULL) continue; 4611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch normal_block = last_block; 4612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_block = NULL; // Cleared to indicate we've handled it. 4613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch normal_block = body_blocks[i]; 4615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (fall_through_block == NULL) { 4618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(normal_block); 4619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = CreateJoin(fall_through_block, 4621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch normal_block, 4622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch clause->EntryId()); 4623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(join); 4624e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 4625e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitStatements(clause->statements())); 4627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fall_through_block = current_block(); 4628b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4629b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4630b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create an up-to-3-way join. Use the break block if it exists since 4632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // it's already a join block. 4633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* break_block = break_info.break_block(); 4634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (break_block == NULL) { 4635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(CreateJoin(fall_through_block, 4636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_block, 4637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stmt->ExitId())); 4638e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 4639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (fall_through_block != NULL) Goto(fall_through_block, break_block); 4640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (last_block != NULL) Goto(last_block, break_block); 4641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_block->SetJoinId(stmt->ExitId()); 4642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(break_block); 4643b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4644b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4645b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, 4647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BailoutId stack_check_id, 4648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_entry) { 4649f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Add<HSimulate>(stack_check_id); 4650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStackCheck* stack_check = 4651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStackCheck::cast(Add<HStackCheck>(HStackCheck::kBackwardsBranch)); 4652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(loop_entry->IsLoopHeader()); 4653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_entry->loop_information()->set_stack_check(stack_check); 4654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(Visit(stmt->body())); 4655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4656b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4657b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 4659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_entry = BuildLoopEntry(stmt); 4664b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueInfo break_info(stmt, scope()); 4666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 4667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueScope push(&break_info, this); 4668f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CHECK_BAILOUT(VisitLoopBody(stmt, stmt->StackCheckId(), loop_entry)); 4669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4670f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HBasicBlock* body_exit = JoinContinue( 4671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch stmt, stmt->ContinueId(), current_block(), break_info.continue_block()); 4672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_successor = NULL; 46733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (body_exit != NULL) { 4674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(body_exit); 4675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor = graph()->CreateBasicBlock(); 4676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stmt->cond()->ToBooleanIsFalse()) { 4677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_entry->loop_information()->stack_check()->Eliminate(); 4678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(loop_successor); 4679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit = NULL; 4680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The block for a true condition, the actual predecessor block of the 4682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // back edge. 4683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit = graph()->CreateBasicBlock(); 4684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitForControl(stmt->cond(), body_exit, loop_successor)); 4685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (body_exit != NULL && body_exit->HasPredecessor()) { 4687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit->SetJoinId(stmt->BackEdgeId()); 4688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit = NULL; 4690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (loop_successor->HasPredecessor()) { 4692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor->SetJoinId(stmt->ExitId()); 4693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor = NULL; 4695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_exit = CreateLoop(stmt, 4698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_entry, 4699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit, 4700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor, 4701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_info.break_block()); 4702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(loop_exit); 4703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4704b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4705b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { 4707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_entry = BuildLoopEntry(stmt); 4712b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the condition is constant true, do not generate a branch. 4714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_successor = NULL; 47153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HBasicBlock* body_entry = graph()->CreateBasicBlock(); 47163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch loop_successor = graph()->CreateBasicBlock(); 47173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); 47183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (body_entry->HasPredecessor()) { 47193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch body_entry->SetJoinId(stmt->BodyId()); 47203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch set_current_block(body_entry); 47213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 47223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (loop_successor->HasPredecessor()) { 47233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch loop_successor->SetJoinId(stmt->ExitId()); 47243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 47253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch loop_successor = NULL; 4726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4727b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueInfo break_info(stmt, scope()); 4729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_block() != NULL) { 4730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueScope push(&break_info, this); 4731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CHECK_BAILOUT(VisitLoopBody(stmt, stmt->StackCheckId(), loop_entry)); 4732b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HBasicBlock* body_exit = JoinContinue( 4734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch stmt, stmt->ContinueId(), current_block(), break_info.continue_block()); 4735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_exit = CreateLoop(stmt, 4736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_entry, 4737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit, 4738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor, 4739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_info.break_block()); 4740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(loop_exit); 4741b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4742b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4743b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) { 4745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stmt->init() != NULL) { 4749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(Visit(stmt->init())); 4750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_entry = BuildLoopEntry(stmt); 4753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 47543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HBasicBlock* loop_successor = graph()->CreateBasicBlock(); 47553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HBasicBlock* body_entry = graph()->CreateBasicBlock(); 4756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stmt->cond() != NULL) { 4757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); 4758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (body_entry->HasPredecessor()) { 4759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_entry->SetJoinId(stmt->BodyId()); 4760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(body_entry); 4761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (loop_successor->HasPredecessor()) { 4763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor->SetJoinId(stmt->ExitId()); 4764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor = NULL; 4766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 47673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 47683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Create dummy control flow so that variable liveness analysis 47693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // produces teh correct result. 47703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HControlInstruction* branch = New<HBranch>(graph()->GetConstantTrue()); 47713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch branch->SetSuccessorAt(0, body_entry); 47723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch branch->SetSuccessorAt(1, loop_successor); 47733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FinishCurrentBlock(branch); 47743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch set_current_block(body_entry); 4775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueInfo break_info(stmt, scope()); 4778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_block() != NULL) { 4779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueScope push(&break_info, this); 4780f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CHECK_BAILOUT(VisitLoopBody(stmt, stmt->StackCheckId(), loop_entry)); 4781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4782f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HBasicBlock* body_exit = JoinContinue( 4783f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch stmt, stmt->ContinueId(), current_block(), break_info.continue_block()); 4784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stmt->next() != NULL && body_exit != NULL) { 4786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(body_exit); 4787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(Visit(stmt->next())); 4788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit = current_block(); 4789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_exit = CreateLoop(stmt, 4792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_entry, 4793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit, 4794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor, 4795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_info.break_block()); 4796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(loop_exit); 4797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { 4801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 4802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 4803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 4804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!stmt->each()->IsVariableProxy() || 4806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) { 4807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kForInStatementWithNonLocalEachVariable); 4808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* each_var = stmt->each()->AsVariableProxy()->var(); 4811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(stmt->enumerable())); 4813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* enumerable = Top(); // Leave enumerable at the top. 4814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IfBuilder if_undefined_or_null(this); 4816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_undefined_or_null.If<HCompareObjectEqAndBranch>( 4817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enumerable, graph()->GetConstantUndefined()); 4818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_undefined_or_null.Or(); 4819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_undefined_or_null.If<HCompareObjectEqAndBranch>( 4820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enumerable, graph()->GetConstantNull()); 4821f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if_undefined_or_null.ThenDeopt(DeoptimizeReason::kUndefinedOrNullInForIn); 4822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if_undefined_or_null.End(); 4823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildForInBody(stmt, each_var, enumerable); 4824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::BuildForInBody(ForInStatement* stmt, 4828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Variable* each_var, 4829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* enumerable) { 4830109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Map> meta_map = isolate()->factory()->meta_map(); 4831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool fast = stmt->for_in_type() == ForInStatement::FAST_FOR_IN; 4832109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch BuildCheckHeapObject(enumerable); 4833109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Add<HCheckInstanceType>(enumerable, HCheckInstanceType::IS_JS_RECEIVER); 4834109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Add<HSimulate>(stmt->ToObjectId()); 4835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (fast) { 4836109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HForInPrepareMap* map = Add<HForInPrepareMap>(enumerable); 4837109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(map); 4838109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Add<HSimulate>(stmt->EnumId()); 4839109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Drop(1); 4840109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Add<HCheckMaps>(map, meta_map); 4841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4842109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HForInCacheArray* array = Add<HForInCacheArray>( 4843109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex); 4844109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HValue* enum_length = BuildEnumLength(map); 4845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4846109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HForInCacheArray* index_cache = Add<HForInCacheArray>( 4847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enumerable, map, DescriptorArray::kEnumCacheBridgeIndicesCacheIndex); 4848109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch array->set_index_cache(index_cache); 4849f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch 4850109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(map); 4851109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(array); 4852109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(enum_length); 4853109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Add<HSimulate>(stmt->PrepareId()); 4854109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 4855109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Runtime::FunctionId function_id = Runtime::kForInEnumerate; 4856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HPushArguments>(enumerable); 4857109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HCallRuntime* array = 4858109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Add<HCallRuntime>(Runtime::FunctionForId(function_id), 1); 4859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(array); 4860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HSimulate>(stmt->EnumId()); 4861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Drop(1); 4862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4863109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch IfBuilder if_fast(this); 4864109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if_fast.If<HCompareMap>(array, meta_map); 4865109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if_fast.Then(); 4866109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch { 4867109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HValue* cache_map = array; 4868109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HForInCacheArray* cache = Add<HForInCacheArray>( 4869109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch enumerable, cache_map, DescriptorArray::kEnumCacheBridgeCacheIndex); 4870109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HValue* enum_length = BuildEnumLength(cache_map); 4871109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(cache_map); 4872109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(cache); 4873109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(enum_length); 4874109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Add<HSimulate>(stmt->PrepareId(), FIXED_SIMULATE); 4875109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 4876109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if_fast.Else(); 4877109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch { 4878109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(graph()->GetConstant1()); 4879109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(array); 4880109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(AddLoadFixedArrayLength(array)); 4881109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Add<HSimulate>(stmt->PrepareId(), FIXED_SIMULATE); 4882109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 4883109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 4884f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch 4885109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(graph()->GetConstant0()); 4886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_entry = BuildLoopEntry(stmt); 4888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Reload the values to ensure we have up-to-date values inside of the loop. 4890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This is relevant especially for OSR where the values don't come from the 4891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // computation above, but from the OSR entry block. 4892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = environment()->ExpressionStackAt(0); 4893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* limit = environment()->ExpressionStackAt(1); 4894109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HValue* array = environment()->ExpressionStackAt(2); 4895109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HValue* type = environment()->ExpressionStackAt(3); 4896109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch enumerable = environment()->ExpressionStackAt(4); 4897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that we still have more keys. 4899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCompareNumericAndBranch* compare_index = 4900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HCompareNumericAndBranch>(index, limit, Token::LT); 4901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_index->set_observed_input_representation( 4902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation::Smi(), Representation::Smi()); 4903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_body = graph()->CreateBasicBlock(); 4905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_successor = graph()->CreateBasicBlock(); 4906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_index->SetSuccessorAt(0, loop_body); 4908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_index->SetSuccessorAt(1, loop_successor); 4909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(compare_index); 4910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(loop_successor); 4912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(5); 4913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(loop_body); 4915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4916109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Compute the next enumerated value. 4917109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HValue* key = Add<HLoadKeyed>(array, index, index, nullptr, FAST_ELEMENTS); 4918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4919109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HBasicBlock* continue_block = nullptr; 4920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (fast) { 4921109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Check if expected map still matches that of the enumerable. 4922109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Add<HCheckMapValue>(enumerable, type); 4923f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch Add<HSimulate>(stmt->FilterId()); 4924109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 4925109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // We need the continue block here to be able to skip over invalidated keys. 4926109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch continue_block = graph()->CreateBasicBlock(); 4927109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 4928109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // We cannot use the IfBuilder here, since we need to be able to jump 4929109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // over the loop body in case of undefined result from %ForInFilter, 4930109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // and the poor soul that is the IfBuilder get's really confused about 4931109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // such "advanced control flow requirements". 4932109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HBasicBlock* if_fast = graph()->CreateBasicBlock(); 4933109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HBasicBlock* if_slow = graph()->CreateBasicBlock(); 4934109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HBasicBlock* if_slow_pass = graph()->CreateBasicBlock(); 4935109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HBasicBlock* if_slow_skip = graph()->CreateBasicBlock(); 4936109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HBasicBlock* if_join = graph()->CreateBasicBlock(); 4937109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 4938109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Check if expected map still matches that of the enumerable. 4939109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HValue* enumerable_map = 4940109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Add<HLoadNamedField>(enumerable, nullptr, HObjectAccess::ForMap()); 4941109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FinishCurrentBlock( 4942109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch New<HCompareObjectEqAndBranch>(enumerable_map, type, if_fast, if_slow)); 4943109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch set_current_block(if_fast); 4944109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch { 4945109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // The enum cache for enumerable is still valid, no need to check key. 4946109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(key); 4947109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Goto(if_join); 4948109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 4949109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch set_current_block(if_slow); 4950109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch { 4951c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Callable callable = CodeFactory::ForInFilter(isolate()); 4952c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* values[] = {key, enumerable}; 4953c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HConstant* stub_value = Add<HConstant>(callable.code()); 4954c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Push(Add<HCallWithDescriptor>(stub_value, 0, callable.descriptor(), 4955f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ArrayVector(values))); 4956109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Add<HSimulate>(stmt->FilterId()); 4957109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FinishCurrentBlock(New<HCompareObjectEqAndBranch>( 4958109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Top(), graph()->GetConstantUndefined(), if_slow_skip, if_slow_pass)); 4959109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 4960109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch set_current_block(if_slow_pass); 4961109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch { Goto(if_join); } 4962109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch set_current_block(if_slow_skip); 4963109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch { 4964109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // The key is no longer valid for enumerable, skip it. 4965109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Drop(1); 4966109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Goto(continue_block); 4967109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 4968109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if_join->SetJoinId(stmt->FilterId()); 4969109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch set_current_block(if_join); 4970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch key = Pop(); 4971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4973109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Bind(each_var, key); 4974109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Add<HSimulate>(stmt->AssignmentId()); 4975109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 4976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueInfo break_info(stmt, scope(), 5); 4977109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break_info.set_continue_block(continue_block); 4978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 4979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakAndContinueScope push(&break_info, this); 4980f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CHECK_BAILOUT(VisitLoopBody(stmt, stmt->StackCheckId(), loop_entry)); 4981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4983f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HBasicBlock* body_exit = JoinContinue( 4984c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch stmt, stmt->IncrementId(), current_block(), break_info.continue_block()); 4985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (body_exit != NULL) { 4987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(body_exit); 4988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* current_index = Pop(); 4990109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HValue* increment = 4991109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AddUncasted<HAdd>(current_index, graph()->GetConstant1()); 4992109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch increment->ClearFlag(HValue::kCanOverflow); 4993109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(increment); 4994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit = current_block(); 4995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* loop_exit = CreateLoop(stmt, 4998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_entry, 4999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch body_exit, 5000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_successor, 5001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_info.break_block()); 5002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(loop_exit); 5004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { 5008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kForOfStatement); 5012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { 5016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kTryCatchStatement); 5020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitTryFinallyStatement( 5024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TryFinallyStatement* stmt) { 5025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kTryFinallyStatement); 5029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { 5033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kDebuggerStatement); 5037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitCaseClause(CaseClause* clause) { 5041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 5042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { 5046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SharedFunctionInfo> shared_info = Compiler::GetSharedFunctionInfo( 5050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch expr, current_info()->script(), top_info()); 5051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We also have a stack overflow if the recursive compilation did. 5052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasStackOverflow()) return; 5053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Use the fast case closure allocation code that allocates in new 505413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // space for nested functions that don't need pretenuring. 5055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant* shared_info_value = Add<HConstant>(shared_info); 5056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* instr; 505762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FeedbackVector> vector(current_feedback_vector(), isolate()); 505862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HValue* vector_value = Add<HConstant>(vector); 505962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int index = FeedbackVector::GetIndex(expr->LiteralFeedbackSlot()); 506062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HValue* index_value = Add<HConstant>(index); 506113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!expr->pretenure()) { 506262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Callable callable = CodeFactory::FastNewClosure(isolate()); 506362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HValue* values[] = {shared_info_value, vector_value, index_value}; 506462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HConstant* stub_value = Add<HConstant>(callable.code()); 506562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch instr = New<HCallWithDescriptor>(stub_value, 0, callable.descriptor(), 5066bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ArrayVector(values)); 5067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 5068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HPushArguments>(shared_info_value); 506962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Add<HPushArguments>(vector_value); 507062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Add<HPushArguments>(index_value); 5071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Runtime::FunctionId function_id = 5072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch expr->pretenure() ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure; 507362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch instr = New<HCallRuntime>(Runtime::FunctionForId(function_id), 3); 5074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 5075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 5076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitClassLiteral(ClassLiteral* lit) { 5080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kClassLiteral); 5084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitNativeFunctionLiteral( 5088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NativeFunctionLiteral* expr) { 5089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kNativeFunctionLiteral); 5093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::VisitDoExpression(DoExpression* expr) { 50973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DoExpressionScope scope(this); 5098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!HasStackOverflow()); 5099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(current_block() != NULL); 5100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(current_block()->HasPredecessor()); 51013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CHECK_ALIVE(VisitBlock(expr->block())); 51023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Visit(expr->result()); 5103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 5104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitConditional(Conditional* expr) { 5107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* cond_true = graph()->CreateBasicBlock(); 5111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* cond_false = graph()->CreateBasicBlock(); 5112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(VisitForControl(expr->condition(), cond_true, cond_false)); 5113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Visit the true and false subexpressions in the same AST context as the 5115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // whole expression. 5116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cond_true->HasPredecessor()) { 5117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_true->SetJoinId(expr->ThenId()); 5118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(cond_true); 5119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(Visit(expr->then_expression())); 5120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_true = current_block(); 5121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_true = NULL; 5123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cond_false->HasPredecessor()) { 5126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_false->SetJoinId(expr->ElseId()); 5127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(cond_false); 5128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_BAILOUT(Visit(expr->else_expression())); 5129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_false = current_block(); 5130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cond_false = NULL; 5132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsTest()) { 5135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id()); 5136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(join); 5137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (join != NULL && !ast_context()->IsEffect()) { 5138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 5139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5143c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochbool HOptimizedGraphBuilder::CanInlineGlobalPropertyAccess( 5144c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Variable* var, LookupIterator* it, PropertyAccessType access_type) { 5145c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (var->is_this()) return false; 5146c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return CanInlineGlobalPropertyAccess(it, access_type); 5147c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 5148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5149c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochbool HOptimizedGraphBuilder::CanInlineGlobalPropertyAccess( 5150c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch LookupIterator* it, PropertyAccessType access_type) { 5151c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!current_info()->has_global_object()) { 5152c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return false; 5153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (it->state()) { 5156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::ACCESSOR: 5157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::ACCESS_CHECK: 5158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::INTERCEPTOR: 5159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case LookupIterator::INTEGER_INDEXED_EXOTIC: 5160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::NOT_FOUND: 5161c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return false; 5162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::DATA: 5163c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (access_type == STORE && it->IsReadOnly()) return false; 5164c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!it->GetHolder<JSObject>()->IsJSGlobalObject()) return false; 5165c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return true; 5166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::JSPROXY: 5167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::TRANSITION: 5168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 5169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 5171c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return false; 5172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { 5176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(var->IsContextSlot()); 5177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = environment()->context(); 5178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length = scope()->ContextChainLength(var->scope()); 5179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (length-- > 0) { 5180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context = Add<HLoadNamedField>( 5181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier context, nullptr, 5182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 5183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return context; 5185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5187c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid HOptimizedGraphBuilder::InlineGlobalPropertyLoad(LookupIterator* it, 5188c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch BailoutId ast_id) { 5189c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<PropertyCell> cell = it->GetPropertyCell(); 5190c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch top_info()->dependencies()->AssumePropertyCell(cell); 5191c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch auto cell_type = it->property_details().cell_type(); 5192c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (cell_type == PropertyCellType::kConstant || 5193c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch cell_type == PropertyCellType::kUndefined) { 5194c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Object> constant_object(cell->value(), isolate()); 5195c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (constant_object->IsConsString()) { 5196c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch constant_object = String::Flatten(Handle<String>::cast(constant_object)); 5197c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 5198c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HConstant* constant = New<HConstant>(constant_object); 5199c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return ast_context()->ReturnInstruction(constant, ast_id); 5200c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 5201c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch auto access = HObjectAccess::ForPropertyCellValue(); 5202c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch UniqueSet<Map>* field_maps = nullptr; 5203c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (cell_type == PropertyCellType::kConstantType) { 5204c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch switch (cell->GetConstantType()) { 5205c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case PropertyCellConstantType::kSmi: 5206c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch access = access.WithRepresentation(Representation::Smi()); 5207c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch break; 5208c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case PropertyCellConstantType::kStableMap: { 5209c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Check that the map really is stable. The heap object could 5210c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // have mutated without the cell updating state. In that case, 5211c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // make no promises about the loaded value except that it's a 5212c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // heap object. 5213c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch access = access.WithRepresentation(Representation::HeapObject()); 5214c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Map> map(HeapObject::cast(cell->value())->map()); 5215c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (map->is_stable()) { 5216c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch field_maps = new (zone()) 5217c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch UniqueSet<Map>(Unique<Map>::CreateImmovable(map), zone()); 5218c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 5219c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch break; 5220c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 5221c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 5222c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 5223c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HConstant* cell_constant = Add<HConstant>(cell); 5224c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HLoadNamedField* instr; 5225c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (field_maps == nullptr) { 5226c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch instr = New<HLoadNamedField>(cell_constant, nullptr, access); 5227c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 5228c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch instr = New<HLoadNamedField>(cell_constant, nullptr, access, field_maps, 5229c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HType::HeapObject()); 5230c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 5231c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch instr->ClearDependsOnFlag(kInobjectFields); 5232c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch instr->SetDependsOnFlag(kGlobalVars); 5233c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return ast_context()->ReturnInstruction(instr, ast_id); 5234c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 5235c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 5236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 5238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* variable = expr->var(); 5242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (variable->location()) { 5243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::UNALLOCATED: { 5244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsLexicalVariableMode(variable->mode())) { 5245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(rossberg): should this be an DCHECK? 5246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kReferenceToGlobalLexicalVariable); 5247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle known global constants like 'undefined' specially to avoid a 5249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // load from a global cell for them. 5250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> constant_value = 5251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->GlobalConstantFor(variable->name()); 5252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!constant_value.is_null()) { 5253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* instr = New<HConstant>(constant_value); 5254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 5255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSGlobalObject> global(current_info()->global_object()); 5258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 5259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Lookup in script contexts. 5260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 5261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<ScriptContextTable> script_contexts( 5262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier global->native_context()->script_context_table()); 5263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ScriptContextTable::LookupResult lookup; 5264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ScriptContextTable::Lookup(script_contexts, variable->name(), 5265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier &lookup)) { 5266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> script_context = ScriptContextTable::GetContext( 5267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier script_contexts, lookup.context_index); 5268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> current_value = 5269109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FixedArray::get(*script_context, lookup.slot_index, isolate()); 5270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the values is not the hole, it will stay initialized, 5272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // so no need to generate a check. 527313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (current_value->IsTheHole(isolate())) { 5274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Bailout(kReferenceToUninitializedVariable); 5275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 5276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HInstruction* result = New<HLoadNamedField>( 5277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HConstant>(script_context), nullptr, 5278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HObjectAccess::ForContextSlot(lookup.slot_index)); 5279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ast_context()->ReturnInstruction(result, expr->id()); 5280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 5281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 5282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 5283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LookupIterator it(global, variable->name(), LookupIterator::OWN); 5284c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch it.TryLookupCachedProperty(); 5285c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (CanInlineGlobalPropertyAccess(variable, &it, LOAD)) { 5286c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InlineGlobalPropertyLoad(&it, expr->id()); 5287c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 5288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 528962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FeedbackVector> vector(current_feedback_vector(), isolate()); 529062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FeedbackSlot slot = expr->VariableFeedbackSlot(); 529162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(vector->IsLoadGlobalIC(slot)); 5292c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 5293c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* vector_value = Add<HConstant>(vector); 529462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HValue* slot_value = Add<HConstant>(vector->GetIndex(slot)); 5295c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Callable callable = CodeFactory::LoadGlobalICInOptimizedCode( 5296c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch isolate(), ast_context()->typeof_mode()); 5297c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* stub = Add<HConstant>(callable.code()); 529862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HValue* name = Add<HConstant>(variable->name()); 529962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HValue* values[] = {name, slot_value, vector_value}; 5300c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HCallWithDescriptor* instr = New<HCallWithDescriptor>( 5301c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Code::LOAD_GLOBAL_IC, stub, 0, callable.descriptor(), 5302c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ArrayVector(values)); 5303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 5304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::PARAMETER: 5308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOCAL: { 5309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = LookupAndMakeLive(variable); 5310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value == graph()->GetConstantHole()) { 5311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsDeclaredVariableMode(variable->mode()) && 5312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch variable->mode() != VAR); 5313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kReferenceToUninitializedVariable); 5314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(value); 5316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::CONTEXT: { 5319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = BuildContextChainWalk(variable); 5320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoadContextSlot::Mode mode; 5321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (variable->mode()) { 5322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LET: 5323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CONST: 5324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode = HLoadContextSlot::kCheckDeoptimize; 5325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 5327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode = HLoadContextSlot::kNoCheck; 5328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HLoadContextSlot* instr = 5331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new(zone()) HLoadContextSlot(context, variable->index(), mode); 5332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 5333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOOKUP: 5336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kReferenceToAVariableWhichRequiresDynamicLookup); 5337f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 5338f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case VariableLocation::MODULE: 5339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 5340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitLiteral(Literal* expr) { 5345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* instr = New<HConstant>(expr->value()); 5349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 5350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 5354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Callable callable = CodeFactory::FastCloneRegExp(isolate()); 535862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int index = FeedbackVector::GetIndex(expr->literal_slot()); 535962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HValue* values[] = {AddThisFunction(), Add<HConstant>(index), 5360c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Add<HConstant>(expr->pattern()), 5361c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Add<HConstant>(expr->flags())}; 5362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant* stub_value = Add<HConstant>(callable.code()); 5363bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HInstruction* instr = New<HCallWithDescriptor>( 5364bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch stub_value, 0, callable.descriptor(), ArrayVector(values)); 5365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 5366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic bool CanInlinePropertyAccess(Handle<Map> map) { 5370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->instance_type() == HEAP_NUMBER_TYPE) return true; 5371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->instance_type() < FIRST_NONSTRING_TYPE) return true; 5372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return map->IsJSObjectMap() && !map->is_dictionary_map() && 5373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !map->has_named_interceptor() && 5374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(verwaest): Whitelist contexts to which we have access. 5375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !map->is_access_check_needed(); 5376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Determines whether the given array or object literal boilerplate satisfies 5380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// all limits to be considered for fast deep-copying and computes the total 5381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// size of all objects that are part of the graph. 5382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool IsFastLiteral(Handle<JSObject> boilerplate, 5383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int max_depth, 5384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int* max_properties) { 5385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (boilerplate->map()->is_deprecated() && 5386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !JSObject::TryMigrateInstance(boilerplate)) { 5387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 5388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(max_depth >= 0 && *max_properties >= 0); 5391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (max_depth == 0) return false; 5392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = boilerplate->GetIsolate(); 5394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArrayBase> elements(boilerplate->elements()); 5395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (elements->length() > 0 && 5396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements->map() != isolate->heap()->fixed_cow_array_map()) { 5397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (boilerplate->HasFastSmiOrObjectElements()) { 5398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); 5399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length = elements->length(); 5400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < length; i++) { 5401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((*max_properties)-- == 0) return false; 5402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> value(fast_elements->get(i), isolate); 5403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value->IsJSObject()) { 5404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> value_object = Handle<JSObject>::cast(value); 5405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsFastLiteral(value_object, 5406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_depth - 1, 5407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_properties)) { 5408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 5409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 541262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (boilerplate->HasFastDoubleElements()) { 541362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (elements->Size() > kMaxRegularHeapObjectSize) return false; 541462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 5415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 5416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> properties(boilerplate->properties()); 5420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (properties->length() > 0) { 5421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 5422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<DescriptorArray> descriptors( 5424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate->map()->instance_descriptors()); 5425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int limit = boilerplate->map()->NumberOfOwnDescriptors(); 5426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < limit; i++) { 5427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyDetails details = descriptors->GetDetails(i); 542862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (details.location() != kField) continue; 542962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(kData, details.kind()); 5430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((*max_properties)-- == 0) return false; 5431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FieldIndex field_index = FieldIndex::ForDescriptor(boilerplate->map(), i); 5432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (boilerplate->IsUnboxedDoubleField(field_index)) continue; 5433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> value(boilerplate->RawFastPropertyAt(field_index), 5434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate); 5435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value->IsJSObject()) { 5436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> value_object = Handle<JSObject>::cast(value); 5437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsFastLiteral(value_object, 5438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_depth - 1, 5439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch max_properties)) { 5440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 5441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 5446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 5450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 5455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* literal; 5456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check whether to use fast or slow deep-copying for boilerplate. 5458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int max_properties = kMaxFastLiteralProperties; 5459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> literals_cell( 546062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch closure->feedback_vector()->Get(expr->literal_slot()), isolate()); 5461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> site; 5462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> boilerplate; 546313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!literals_cell->IsUndefined(isolate())) { 5464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Retrieve the boilerplate 5465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site = Handle<AllocationSite>::cast(literals_cell); 5466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()), 5467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()); 5468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!boilerplate.is_null() && 5471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) { 5472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllocationSiteUsageContext site_context(isolate(), site, false); 5473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch site_context.EnterNewScope(); 5474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch literal = BuildFastLiteral(boilerplate, &site_context); 5475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch site_context.ExitScope(site, boilerplate); 5476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 547862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<BoilerplateDescription> constant_properties = 547962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch expr->GetOrBuildConstantProperties(isolate()); 548062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int literal_index = FeedbackVector::GetIndex(expr->literal_slot()); 5481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int flags = expr->ComputeFlags(true); 5482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HPushArguments>(AddThisFunction(), Add<HConstant>(literal_index), 5484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(constant_properties), 5485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(flags)); 5486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::FunctionId function_id = Runtime::kCreateObjectLiteral; 5488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch literal = Add<HCallRuntime>(Runtime::FunctionForId(function_id), 4); 5489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The object is expected in the bailout environment during computation 5492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of the property values and is the value of the entire expression. 5493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(literal); 5494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < expr->properties()->length(); i++) { 5495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ObjectLiteral::Property* property = expr->properties()->at(i); 5496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (property->is_computed_name()) return Bailout(kComputedPropertyName); 5497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (property->IsCompileTimeValue()) continue; 5498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Literal* key = property->key()->AsLiteral(); 5500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* value = property->value(); 5501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (property->kind()) { 5503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ObjectLiteral::Property::MATERIALIZED_LITERAL: 5504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); 5505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fall through. 5506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ObjectLiteral::Property::COMPUTED: 5507958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // It is safe to use [[Put]] here because the boilerplate already 5508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // contains computed properties with an uninitialized value. 5509f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (key->IsStringLiteral()) { 5510f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(key->IsPropertyName()); 5511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (property->emit_store()) { 5512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(value)); 5513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 5514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 5515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = property->GetReceiverType(); 5516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<String> name = key->AsPropertyName(); 5517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* store; 551862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FeedbackSlot slot = property->GetSlot(); 5519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is_null()) { 5520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we don't know the monomorphic type, do a generic store. 5521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_ALIVE(store = BuildNamedGeneric(STORE, NULL, slot, literal, 5522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch name, value)); 5523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAccessInfo info(this, STORE, map, name); 5525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info.CanAccessMonomorphic()) { 5526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_literal = Add<HCheckMaps>(literal, map); 5527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!info.IsAccessorConstant()); 552862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch info.MarkAsInitializingStore(); 5529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store = BuildMonomorphicAccess( 5530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &info, literal, checked_literal, value, 5531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId::None(), BailoutId::None()); 553262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_NOT_NULL(store); 5533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_ALIVE(store = BuildNamedGeneric(STORE, NULL, slot, 5535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch literal, name, value)); 5536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (store->IsInstruction()) { 5539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddInstruction(HInstruction::cast(store)); 5540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 5541958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(store->HasObservableSideEffects()); 5542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HSimulate>(key->id(), REMOVABLE_SIMULATE); 5543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Add [[HomeObject]] to function literals. 5545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FunctionLiteral::NeedsHomeObject(property->value())) { 5546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Symbol> sym = isolate()->factory()->home_object_symbol(); 5547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* store_home = BuildNamedGeneric( 5548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STORE, NULL, property->GetSlot(1), value, sym, literal); 5549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddInstruction(store_home); 5550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(store_home->HasObservableSideEffects()); 5551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HSimulate>(property->value()->id(), REMOVABLE_SIMULATE); 5552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 5553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForEffect(value)); 5555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 5557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fall through. 5559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ObjectLiteral::Property::PROTOTYPE: 5560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ObjectLiteral::Property::SETTER: 5561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ObjectLiteral::Property::GETTER: 5562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kObjectLiteralWithComplexProperty); 5563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: UNREACHABLE(); 5564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 55673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return ast_context()->ReturnValue(Pop()); 5568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 5572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 5573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 5574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 5575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Expression*>* subexprs = expr->values(); 5576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length = subexprs->length(); 5577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* literal; 5578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> site; 558062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FeedbackVector> vector(environment()->closure()->feedback_vector(), 558162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate()); 558262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> literals_cell(vector->Get(expr->literal_slot()), isolate()); 5583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> boilerplate_object; 558413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!literals_cell->IsUndefined(isolate())) { 5585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(literals_cell->IsAllocationSite()); 5586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site = Handle<AllocationSite>::cast(literals_cell); 5587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate_object = Handle<JSObject>( 5588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::cast(site->transition_info()), isolate()); 5589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check whether to use fast or slow deep-copying for boilerplate. 5592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int max_properties = kMaxFastLiteralProperties; 5593bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!boilerplate_object.is_null() && 5594bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch IsFastLiteral(boilerplate_object, kMaxFastLiteralDepth, 5595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &max_properties)) { 5596bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(site->SitePointsToLiteral()); 5597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllocationSiteUsageContext site_context(isolate(), site, false); 5598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch site_context.EnterNewScope(); 5599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch literal = BuildFastLiteral(boilerplate_object, &site_context); 5600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch site_context.ExitScope(site, boilerplate_object); 5601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 560362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<ConstantElementsPair> constants = 560462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch expr->GetOrBuildConstantElements(isolate()); 560562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int literal_index = FeedbackVector::GetIndex(expr->literal_slot()); 5606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int flags = expr->ComputeFlags(true); 5607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HPushArguments>(AddThisFunction(), Add<HConstant>(literal_index), 5609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HConstant>(constants), Add<HConstant>(flags)); 5610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral; 5612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch literal = Add<HCallRuntime>(Runtime::FunctionForId(function_id), 4); 5613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Register to deopt if the boilerplate ElementsKind changes. 5615bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!site.is_null()) { 5616bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch top_info()->dependencies()->AssumeTransitionStable(site); 5617bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 5618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The array is expected in the bailout environment during computation 5621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of the property values and is the value of the entire expression. 5622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(literal); 5623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* elements = NULL; 5625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < length; i++) { 5627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* subexpr = subexprs->at(i); 5628109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(!subexpr->IsSpread()); 5629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the subexpression is a literal or a simple materialized literal it 5631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is already set in the cloned array. 5632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 5633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(subexpr)); 5635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 5636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!Smi::IsValid(i)) return Bailout(kNonSmiKeyInArrayLiteral); 5637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements = AddLoadElements(literal); 5639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = Add<HConstant>(i); 5641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5642bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!boilerplate_object.is_null()) { 5643bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ElementsKind boilerplate_elements_kind = 5644bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch boilerplate_object->GetElementsKind(); 5645bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch switch (boilerplate_elements_kind) { 5646bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case FAST_SMI_ELEMENTS: 5647bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case FAST_HOLEY_SMI_ELEMENTS: 5648bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case FAST_ELEMENTS: 5649bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case FAST_HOLEY_ELEMENTS: 5650bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case FAST_DOUBLE_ELEMENTS: 5651bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case FAST_HOLEY_DOUBLE_ELEMENTS: { 5652bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Add<HStoreKeyed>(elements, key, value, nullptr, 5653bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch boilerplate_elements_kind); 5654bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 5655bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 5656bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch default: 5657bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UNREACHABLE(); 5658bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 5659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5660bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 5661bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HInstruction* instr = BuildKeyedGeneric( 5662bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch STORE, expr, expr->LiteralFeedbackSlot(), literal, key, value); 5663bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch AddInstruction(instr); 5664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->GetIdForElement(i)); 5667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 5670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object, 5674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map) { 5675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(object); 5676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HCheckMaps>(object, map); 5677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildLoadNamedField( 5681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessInfo* info, 5682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_object) { 568362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Check if this is a load of an immutable or constant property. 5684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (checked_object->ActualValue()->IsConstant()) { 5685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> object( 5686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(checked_object->ActualValue())->handle(isolate())); 5687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object->IsJSObject()) { 5689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupIterator it(object, info->name(), 5690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupIterator::OWN_SKIP_INTERCEPTOR); 569162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (it.IsFound()) { 569262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool is_reaonly_non_configurable = 569362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch it.IsReadOnly() && !it.IsConfigurable(); 569462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (is_reaonly_non_configurable || 569562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch (FLAG_track_constant_fields && info->IsDataConstantField())) { 569662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> value = JSReceiver::GetDataProperty(&it); 569762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!is_reaonly_non_configurable) { 569862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(!it.is_dictionary_holder()); 569962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Add dependency on the map that introduced the field. 570062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Map> field_owner_map = it.GetFieldOwnerMap(); 570162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch top_info()->dependencies()->AssumeFieldOwner(field_owner_map); 570262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 570362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return New<HConstant>(value); 570462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 5705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = info->access(); 5710958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (access.representation().IsDouble() && 5711958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (!FLAG_unbox_double_fields || !access.IsInobject())) { 5712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the heap number. 5713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object = Add<HLoadNamedField>( 5714958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier checked_object, nullptr, 5715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch access.WithRepresentation(Representation::Tagged())); 5716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the double value from it. 5717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch access = HObjectAccess::ForHeapNumberValue(); 5718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList* map_list = info->field_maps(); 5721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map_list->length() == 0) { 5722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HLoadNamedField>(checked_object, checked_object, access); 5723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniqueSet<Map>* maps = new(zone()) UniqueSet<Map>(map_list->length(), zone()); 5726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < map_list->length(); ++i) { 5727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch maps->Add(Unique<Map>::CreateImmovable(map_list->at(i)), zone()); 5728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HLoadNamedField>( 5730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object, checked_object, access, maps, info->field_type()); 5731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 573362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochHValue* HOptimizedGraphBuilder::BuildStoreNamedField(PropertyAccessInfo* info, 573462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HValue* checked_object, 573562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HValue* value) { 5736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool transition_to_field = info->IsTransition(); 5737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(verwaest): Move this logic into PropertyAccessInfo. 5738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess field_access = info->access(); 5739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 574062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool store_to_constant_field = FLAG_track_constant_fields && 574162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch info->StoreMode() != INITIALIZING_STORE && 574262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch info->IsDataConstantField(); 574362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 5744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreNamedField *instr; 5745958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (field_access.representation().IsDouble() && 5746958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (!FLAG_unbox_double_fields || !field_access.IsInobject())) { 5747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess heap_number_access = 5748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch field_access.WithRepresentation(Representation::Tagged()); 5749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (transition_to_field) { 5750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The store requires a mutable HeapNumber to be allocated. 5751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_side_effects(this); 5752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); 5753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(hpayer): Allocation site pretenuring support. 5755bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HInstruction* heap_number = 5756bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Add<HAllocate>(heap_number_size, HType::HeapObject(), NOT_TENURED, 5757bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch MUTABLE_HEAP_NUMBER_TYPE, graph()->GetConstant0()); 5758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddStoreMapConstant( 5759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_number, isolate()->factory()->mutable_heap_number_map()); 5760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), 5761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value); 5762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = New<HStoreNamedField>(checked_object->ActualValue(), 5763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_number_access, 5764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_number); 5765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Already holds a HeapNumber; load the box and write its value field. 5767958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HInstruction* heap_number = 5768958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HLoadNamedField>(checked_object, nullptr, heap_number_access); 576962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 577062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (store_to_constant_field) { 577162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // If the field is constant check that the value we are going to store 577262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // matches current value. 577362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HInstruction* current_value = Add<HLoadNamedField>( 577462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch heap_number, nullptr, HObjectAccess::ForHeapNumberValue()); 577562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch IfBuilder value_checker(this); 577662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value_checker.IfNot<HCompareNumericAndBranch>(current_value, value, 577762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Token::EQ); 577862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value_checker.ThenDeopt(DeoptimizeReason::kValueMismatch); 577962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value_checker.End(); 578062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return nullptr; 578162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 578262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 578362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch instr = New<HStoreNamedField>(heap_number, 578462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HObjectAccess::ForHeapNumberValue(), 578562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value, STORE_TO_INITIALIZED_ENTRY); 578662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 5787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 578962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (store_to_constant_field) { 579062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // If the field is constant check that the value we are going to store 579162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // matches current value. 579262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HInstruction* current_value = Add<HLoadNamedField>( 579362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch checked_object->ActualValue(), checked_object, field_access); 579462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 579562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch IfBuilder value_checker(this); 579662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (field_access.representation().IsDouble()) { 579762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value_checker.IfNot<HCompareNumericAndBranch>(current_value, value, 579862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Token::EQ); 579962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 580062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value_checker.IfNot<HCompareObjectEqAndBranch>(current_value, value); 580162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 580262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value_checker.ThenDeopt(DeoptimizeReason::kValueMismatch); 580362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value_checker.End(); 580462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return nullptr; 5805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 580662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 580762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (field_access.representation().IsHeapObject()) { 580862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BuildCheckHeapObject(value); 580962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 581062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 581162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!info->field_maps()->is_empty()) { 581262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(field_access.representation().IsHeapObject()); 581362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value = Add<HCheckMaps>(value, info->field_maps()); 581462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 5815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 581662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // This is a normal store. 581762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch instr = New<HStoreNamedField>(checked_object->ActualValue(), field_access, 581862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value, info->StoreMode()); 581962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 5820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (transition_to_field) { 5823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> transition(info->transition()); 5824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!transition->is_deprecated()); 5825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetTransition(Add<HConstant>(transition)); 5826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return instr; 5828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5830109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochHandle<FieldType> 5831109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochHOptimizedGraphBuilder::PropertyAccessInfo::GetFieldTypeFromMap( 5832109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Map> map) const { 5833109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(IsFound()); 5834109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(number_ < map->NumberOfOwnDescriptors()); 5835109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return handle(map->instance_descriptors()->GetFieldType(number_), isolate()); 5836109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 5837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible( 5839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessInfo* info) { 5840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!CanInlinePropertyAccess(map_)) return false; 5841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5842f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Currently only handle AstType::Number as a polymorphic case. 5843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber 5844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instruction. 5845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsNumberType()) return false; 5846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Values are only compatible for monomorphic load if they all behave the same 5848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // regarding value wrappers. 5849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsValueWrapped() != info->IsValueWrapped()) return false; 5850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!LookupDescriptor()) return false; 5852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsFound()) { 5854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return (!info->IsFound() || info->has_holder()) && 5855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map()->prototype() == info->map()->prototype(); 5856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mismatch if the other access info found the property in the prototype 5859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chain. 5860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->has_holder()) return false; 5861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsAccessorConstant()) { 5863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return accessor_.is_identical_to(info->accessor_) && 5864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch api_holder_.is_identical_to(info->api_holder_); 5865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsDataConstant()) { 5868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return constant_.is_identical_to(info->constant_); 5869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsData()); 5872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!info->IsData()) return false; 5873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation r = access_.representation(); 5875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsLoad()) { 5876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info->access_.representation().IsCompatibleForLoad(r)) return false; 5877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info->access_.representation().IsCompatibleForStore(r)) return false; 5879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->access_.offset() != access_.offset()) return false; 5881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->access_.IsInobject() != access_.IsInobject()) return false; 5882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsLoad()) { 5883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (field_maps_.is_empty()) { 5884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->field_maps_.Clear(); 5885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (!info->field_maps_.is_empty()) { 5886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < field_maps_.length(); ++i) { 5887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->field_maps_.AddMapIfMissing(field_maps_.at(i), info->zone()); 5888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->field_maps_.Sort(); 5890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 5892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We can only merge stores that agree on their field maps. The comparison 5893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // below is safe, since we keep the field maps sorted. 5894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (field_maps_.length() != info->field_maps_.length()) return false; 5895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < field_maps_.length(); ++i) { 5896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!field_maps_.at(i).is_identical_to(info->field_maps_.at(i))) { 5897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 5898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->GeneralizeRepresentation(r); 5902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->field_type_ = info->field_type_.Combine(field_type_); 5903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 5904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::PropertyAccessInfo::LookupDescriptor() { 5908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!map_->IsJSObjectMap()) return true; 5909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LookupDescriptor(*map_, *name_); 5910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return LoadResult(map_); 5911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) { 5915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsLoad() && IsProperty() && IsReadOnly()) { 5916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 5917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsData()) { 5920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Construct the object field access. 5921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = GetLocalFieldIndexFromMap(map); 5922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch access_ = HObjectAccess::ForField(map, index, representation(), name_); 5923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load field map for heap objects. 5925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return LoadFieldMaps(map); 5926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (IsAccessorConstant()) { 5927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> accessors = GetAccessorsFromMap(map); 5928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!accessors->IsAccessorPair()) return false; 5929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* raw_accessor = 5930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsLoad() ? Handle<AccessorPair>::cast(accessors)->getter() 5931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Handle<AccessorPair>::cast(accessors)->setter(); 5932109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!raw_accessor->IsJSFunction() && 5933109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch !raw_accessor->IsFunctionTemplateInfo()) 5934109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return false; 5935109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> accessor = handle(HeapObject::cast(raw_accessor)); 5936109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CallOptimization call_optimization(accessor); 5937109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (call_optimization.is_simple_api_call()) { 5938109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CallOptimization::HolderLookup holder_lookup; 5939109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch api_holder_ = 5940109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch call_optimization.LookupHolderOfExpectedType(map_, &holder_lookup); 5941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch accessor_ = accessor; 5943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (IsDataConstant()) { 5944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant_ = GetConstantFromMap(map); 5945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 5948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool HOptimizedGraphBuilder::PropertyAccessInfo::LoadFieldMaps( 5952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map) { 5953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Clear any previously collected field maps/type. 5954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch field_maps_.Clear(); 5955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch field_type_ = HType::Tagged(); 5956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Figure out the field type from the accessor map. 5958109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<FieldType> field_type = GetFieldTypeFromMap(map); 5959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Collect the (stable) maps from the field type. 5961109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (field_type->IsClass()) { 5962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(access_.representation().IsHeapObject()); 5963109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Map> field_map = field_type->AsClass(); 5964109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (field_map->is_stable()) { 5965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch field_maps_.Add(field_map, zone()); 5966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (field_maps_.is_empty()) { 5970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Store is not safe if the field map was cleared. 5971109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return IsLoad() || !field_type->IsNone(); 5972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 5973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5974109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Determine field HType from field type. 5975109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch field_type_ = HType::FromFieldType(field_type, zone()); 5976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(field_type_.IsHeapObject()); 5977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Add dependency on the map that introduced the field. 5979c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch top_info()->dependencies()->AssumeFieldOwner(GetFieldOwnerFromMap(map)); 5980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 5981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { 5985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = this->map(); 5986109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (name_->IsPrivate()) { 5987109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch NotFound(); 5988109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return !map->has_hidden_prototype(); 5989109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 5990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (map->prototype()->IsJSObject()) { 5992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch holder_ = handle(JSObject::cast(map->prototype())); 5993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (holder_->map()->is_deprecated()) { 5994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::TryMigrateInstance(holder_); 5995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map = Handle<Map>(holder_->map()); 5997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!CanInlinePropertyAccess(map)) { 5998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NotFound(); 5999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 6000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LookupDescriptor(*map, *name_); 6002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFound()) return LoadResult(map); 6003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NotFound(); 6006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return !map->prototype()->IsJSReceiver(); 6007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool HOptimizedGraphBuilder::PropertyAccessInfo::IsIntegerIndexedExotic() { 6011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstanceType instance_type = map_->instance_type(); 6012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return instance_type == JS_TYPED_ARRAY_TYPE && name_->IsString() && 6013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsSpecialIndex(isolate()->unicode_cache(), String::cast(*name_)); 6014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 6015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() { 6018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!CanInlinePropertyAccess(map_)) return false; 6019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsJSObjectFieldAccessor()) return IsLoad(); 6020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map_->IsJSFunctionMap() && map_->is_constructor() && 6021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !map_->has_non_instance_prototype() && 6022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch name_.is_identical_to(isolate()->factory()->prototype_string())) { 6023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return IsLoad(); 6024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!LookupDescriptor()) return false; 6026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFound()) return IsLoad() || !IsReadOnly(); 6027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsIntegerIndexedExotic()) return false; 6028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!LookupInPrototypes()) return false; 6029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsLoad()) return true; 6030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsAccessorConstant()) return true; 6032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LookupTransition(*map_, *name_, NONE); 6033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsTransitionToData() && map_->unused_property_fields() > 0) { 6034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Construct the object field access. 6035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int descriptor = transition()->LastAdded(); 6036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = 6037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch transition()->instance_descriptors()->GetFieldIndex(descriptor) - 6038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch map_->GetInObjectProperties(); 6039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyDetails details = 6040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch transition()->instance_descriptors()->GetDetails(descriptor); 6041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation representation = details.representation(); 6042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch access_ = HObjectAccess::ForField(map_, index, representation, name_); 6043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load field map for heap objects. 6045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return LoadFieldMaps(transition()); 6046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 6048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic( 6052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmallMapList* maps) { 6053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(map_.is_identical_to(maps->first())); 6054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!CanAccessMonomorphic()) return false; 6055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism); 6056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (maps->length() > kMaxLoadPolymorphism) return false; 6057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = HObjectAccess::ForMap(); // bogus default 6058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (GetJSObjectFieldAccess(&access)) { 6059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 1; i < maps->length(); ++i) { 6060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAccessInfo test_info(builder_, access_type_, maps->at(i), name_); 6061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess test_access = HObjectAccess::ForMap(); // bogus default 6062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!test_info.GetJSObjectFieldAccess(&test_access)) return false; 6063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!access.Equals(test_access)) return false; 6064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 6066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Currently only handle numbers as a polymorphic case. 6069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber 6070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instruction. 6071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsNumberType()) return false; 6072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Multiple maps cannot transition to the same target map. 6074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsLoad() || !IsTransition()); 6075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsTransition() && maps->length() > 1) return false; 6076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 1; i < maps->length(); ++i) { 6078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAccessInfo test_info(builder_, access_type_, maps->at(i), name_); 6079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!test_info.IsCompatible(this)) return false; 6080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 6083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Map> HOptimizedGraphBuilder::PropertyAccessInfo::map() { 6087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction> ctor; 6088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (Map::GetConstructorFunction( 6089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch map_, handle(current_info()->closure()->context()->native_context())) 6090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch .ToHandle(&ctor)) { 6091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return handle(ctor->initial_map()); 6092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 6093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return map_; 6094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic bool NeedsWrapping(Handle<Map> map, Handle<JSFunction> target) { 6098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return !map->IsJSObjectMap() && 6099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch is_sloppy(target->shared()->language_mode()) && 6100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !target->shared()->native(); 6101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool HOptimizedGraphBuilder::PropertyAccessInfo::NeedsWrappingFor( 6105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction> target) const { 6106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return NeedsWrapping(map_, target); 6107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 6108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHValue* HOptimizedGraphBuilder::BuildMonomorphicAccess( 6111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAccessInfo* info, HValue* object, HValue* checked_object, 6112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* value, BailoutId ast_id, BailoutId return_id, 6113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool can_inline_accessor) { 6114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = HObjectAccess::ForMap(); // bogus default 6115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->GetJSObjectFieldAccess(&access)) { 6116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(info->IsLoad()); 6117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HLoadNamedField>(object, checked_object, access); 6118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->name().is_identical_to(isolate()->factory()->prototype_string()) && 6121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch info->map()->IsJSFunctionMap() && info->map()->is_constructor()) { 6122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!info->map()->has_non_instance_prototype()); 6123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HLoadFunctionPrototype>(checked_object); 6124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_holder = checked_object; 6127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->has_holder()) { 6128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> prototype(JSObject::cast(info->map()->prototype())); 6129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_holder = BuildCheckPrototypeMaps(prototype, info->holder()); 6130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info->IsFound()) { 6133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(info->IsLoad()); 61343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return graph()->GetConstantUndefined(); 6135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info->IsData()) { 6138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->IsLoad()) { 6139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildLoadNamedField(info, checked_holder); 6140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildStoreNamedField(info, checked_object, value); 6142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->IsTransition()) { 6146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!info->IsLoad()); 6147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildStoreNamedField(info, checked_object, value); 6148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info->IsAccessorConstant()) { 6151c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch MaybeHandle<Name> maybe_name = 6152c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch FunctionTemplateInfo::TryGetCachedPropertyName(isolate(), 6153c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch info->accessor()); 6154c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!maybe_name.is_null()) { 6155c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Name> name = maybe_name.ToHandleChecked(); 6156c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch PropertyAccessInfo cache_info(this, LOAD, info->map(), name); 6157c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Load new target. 6158c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (cache_info.CanAccessMonomorphic()) { 6159c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return BuildLoadNamedField(&cache_info, checked_object); 6160c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 6161c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 6162c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 6163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(checked_object); 6164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = 1; 6165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info->IsLoad()) { 6166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch argument_count = 2; 6167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(value); 6168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6170109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (info->accessor()->IsJSFunction() && 6171109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch info->NeedsWrappingFor(Handle<JSFunction>::cast(info->accessor()))) { 6172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = Add<HConstant>(info->accessor()); 6173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argument_count); 61743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return NewCallFunction(function, argument_count, TailCallMode::kDisallow, 61753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ConvertReceiverMode::kNotNullOrUndefined, 61763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode::kDisallow); 6177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (FLAG_inline_accessors && can_inline_accessor) { 6178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool success = info->IsLoad() 6179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) 6180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : TryInlineSetter( 6181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->accessor(), info->map(), ast_id, return_id, value); 6182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (success || HasStackOverflow()) return NULL; 6183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argument_count); 6186109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!info->accessor()->IsJSFunction()) { 6187109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Bailout(kInliningBailedOut); 6188109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return nullptr; 6189109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 61903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return NewCallConstantFunction(Handle<JSFunction>::cast(info->accessor()), 61913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch argument_count, TailCallMode::kDisallow, 61923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode::kDisallow); 6193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(info->IsDataConstant()); 6196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->IsLoad()) { 6197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HConstant>(info->constant()); 6198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant())); 6200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( 620462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PropertyAccessType access_type, Expression* expr, FeedbackSlot slot, 6205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BailoutId ast_id, BailoutId return_id, HValue* object, HValue* value, 6206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmallMapList* maps, Handle<Name> name) { 6207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Something did not match; must use a polymorphic load. 6208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int count = 0; 6209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = NULL; 6210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* number_block = NULL; 6211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool handled_string = false; 6212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool handle_smi = false; 6214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism); 6215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int i; 6216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (i = 0; i < maps->length() && count < kMaxLoadPolymorphism; ++i) { 6217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAccessInfo info(this, access_type, maps->at(i), name); 6218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info.IsStringType()) { 6219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (handled_string) continue; 6220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handled_string = true; 6221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info.CanAccessMonomorphic()) { 6223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch count++; 6224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info.IsNumberType()) { 6225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle_smi = true; 6226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 6227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (i < maps->length()) { 6232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch count = -1; 6233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch maps->Clear(); 6234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch count = 0; 6236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HControlInstruction* smi_check = NULL; 6238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handled_string = false; 6239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (i = 0; i < maps->length() && count < kMaxLoadPolymorphism; ++i) { 6241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAccessInfo info(this, access_type, maps->at(i), name); 6242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info.IsStringType()) { 6243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (handled_string) continue; 6244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handled_string = true; 6245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info.CanAccessMonomorphic()) continue; 6247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (count == 0) { 6249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch join = graph()->CreateBasicBlock(); 6250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (handle_smi) { 6251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); 6252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); 6253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_block = graph()->CreateBasicBlock(); 6254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch smi_check = New<HIsSmiAndBranch>( 6255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, empty_smi_block, not_smi_block); 6256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(smi_check); 6257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GotoNoSimulate(empty_smi_block, number_block); 6258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(not_smi_block); 6259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(object); 6261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++count; 6264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_true = graph()->CreateBasicBlock(); 6265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_false = graph()->CreateBasicBlock(); 6266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HUnaryControlInstruction* compare; 6267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dependency; 6269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info.IsNumberType()) { 6270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); 6271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare = New<HCompareMap>(object, heap_number_map, if_true, if_false); 6272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dependency = smi_check; 6273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (info.IsStringType()) { 6274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare = New<HIsStringAndBranch>(object, if_true, if_false); 6275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dependency = compare; 6276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare = New<HCompareMap>(object, info.map(), if_true, if_false); 6278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dependency = compare; 6279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(compare); 6281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info.IsNumberType()) { 6283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GotoNoSimulate(if_true, number_block); 6284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_true = number_block; 6285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(if_true); 6288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* access = 6290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildMonomorphicAccess(&info, object, dependency, value, ast_id, 6291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return_id, FLAG_polymorphic_inlining); 6292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result = NULL; 6294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (access_type) { 6295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LOAD: 6296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = access; 6297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 6298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case STORE: 6299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = value; 6300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 6301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access == NULL) { 6304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasStackOverflow()) return; 6305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (access->IsInstruction()) { 6307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* instr = HInstruction::cast(access); 6308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!instr->IsLinked()) AddInstruction(instr); 6309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 6310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(result); 6311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_block() != NULL) Goto(join); 6314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(if_false); 6315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Finish up. Unconditionally deoptimize if we've handled all the maps we 6318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // know about and do not want to handle ones we've never seen. Otherwise 6319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // use a generic IC. 6320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (count == maps->length() && FLAG_deoptimize_uncommon_cases) { 6321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FinishExitWithHardDeoptimization( 6322f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason::kUnknownMapInPolymorphicAccess); 6323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* instr = 6325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildNamedGeneric(access_type, expr, slot, object, name, value); 6326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(instr); 6327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value); 6328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (join != NULL) { 6330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(join); 6331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 6335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(join != NULL); 6339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (join->HasPredecessor()) { 6340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch join->SetJoinId(ast_id); 6341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(join); 6342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 6345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6348109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochstatic bool ComputeReceiverTypes(Expression* expr, HValue* receiver, 6349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList** t, 6350109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HOptimizedGraphBuilder* builder) { 6351109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Zone* zone = builder->zone(); 6352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmallMapList* maps = expr->GetReceiverTypes(); 6353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *t = maps; 6354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool monomorphic = expr->IsMonomorphic(); 6355f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (maps != nullptr && receiver->HasMonomorphicJSObjectType()) { 6356109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (maps->length() > 0) { 6357109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap(); 6358109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch maps->FilterForPossibleTransitions(root_map); 6359109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch monomorphic = maps->length() == 1; 6360109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 6361109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // No type feedback, see if we can infer the type. This is safely 6362109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // possible if the receiver had a known map at some point, and no 6363109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // map-changing stores have happened to it since. 6364109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Map> candidate_map = receiver->GetMonomorphicJSObjectMap(); 6365109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (HInstruction* current = builder->current_block()->last(); 6366109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch current != nullptr; current = current->previous()) { 6367109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (current->IsBlockEntry()) break; 6368109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (current->CheckChangesFlag(kMaps)) { 6369109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Only allow map changes that store the candidate map. We don't 6370109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // need to care which object the map is being written into. 6371109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!current->IsStoreNamedField()) break; 6372109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HStoreNamedField* map_change = HStoreNamedField::cast(current); 6373109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!map_change->value()->IsConstant()) break; 6374109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HConstant* map_constant = HConstant::cast(map_change->value()); 6375109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!map_constant->representation().IsTagged()) break; 6376109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> map = map_constant->handle(builder->isolate()); 6377109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!map.is_identical_to(candidate_map)) break; 6378109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 6379109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (current == receiver) { 6380109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // We made it all the way back to the receiver without encountering 6381109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // a map change! So we can assume that the receiver still has the 6382109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // candidate_map we know about. 6383109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch maps->Add(candidate_map, zone); 6384109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch monomorphic = true; 6385109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 6386109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 6387109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 6388109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 6389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return monomorphic && CanInlinePropertyAccess(maps->first()); 6391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic bool AreStringTypes(SmallMapList* maps) { 6395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < maps->length(); i++) { 6396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (maps->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false; 6397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 6399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::BuildStore(Expression* expr, Property* prop, 640262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FeedbackSlot slot, BailoutId ast_id, 640362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BailoutId return_id, 6404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_uninitialized) { 6405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!prop->key()->IsPropertyName()) { 6406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keyed store. 6407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 6408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = Pop(); 6409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object = Pop(); 6410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_side_effects = false; 6411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* result = 6412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleKeyedElementAccess(object, key, value, expr, slot, ast_id, 6413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return_id, STORE, &has_side_effects); 6414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (has_side_effects) { 6415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(value); 6416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Drop(1); 6418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (result == NULL) return; 6420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(value); 6421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Named store. 6424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 6425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object = Pop(); 6426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Literal* key = prop->key()->AsLiteral(); 6428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> name = Handle<String>::cast(key->value()); 6429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!name.is_null()); 6430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* access = BuildNamedAccess(STORE, ast_id, return_id, expr, slot, 6432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object, name, value, is_uninitialized); 6433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (access == NULL) return; 6434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(value); 6436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (access->IsInstruction()) AddInstruction(HInstruction::cast(access)); 6437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (access->HasObservableSideEffects()) { 6438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Drop(1); 6441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(value); 6442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 6446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Property* prop = expr->target()->AsProperty(); 6447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(prop != NULL); 6448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(prop->obj())); 6449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!prop->key()->IsPropertyName()) { 6450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(prop->key())); 6451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->value())); 6453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildStore(expr, prop, expr->AssignmentSlot(), expr->id(), 6454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->AssignmentId(), expr->IsUninitialized()); 6455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6457c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochHInstruction* HOptimizedGraphBuilder::InlineGlobalPropertyStore( 6458c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch LookupIterator* it, HValue* value, BailoutId ast_id) { 6459c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<PropertyCell> cell = it->GetPropertyCell(); 6460c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch top_info()->dependencies()->AssumePropertyCell(cell); 6461c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch auto cell_type = it->property_details().cell_type(); 6462c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (cell_type == PropertyCellType::kConstant || 6463c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch cell_type == PropertyCellType::kUndefined) { 6464c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Object> constant(cell->value(), isolate()); 6465c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (value->IsConstant()) { 6466c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HConstant* c_value = HConstant::cast(value); 6467c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!constant.is_identical_to(c_value->handle(isolate()))) { 6468c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Add<HDeoptimize>(DeoptimizeReason::kConstantGlobalVariableAssignment, 6469c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Deoptimizer::EAGER); 6470c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 6471c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 6472c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* c_constant = Add<HConstant>(constant); 6473c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch IfBuilder builder(this); 6474c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (constant->IsNumber()) { 6475c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ); 6476c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 6477c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch builder.If<HCompareObjectEqAndBranch>(value, c_constant); 6478c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 6479c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch builder.Then(); 6480c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch builder.Else(); 6481c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Add<HDeoptimize>(DeoptimizeReason::kConstantGlobalVariableAssignment, 6482c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Deoptimizer::EAGER); 6483c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch builder.End(); 6484c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 6485c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 6486c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HConstant* cell_constant = Add<HConstant>(cell); 6487c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch auto access = HObjectAccess::ForPropertyCellValue(); 6488c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (cell_type == PropertyCellType::kConstantType) { 6489c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch switch (cell->GetConstantType()) { 6490c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case PropertyCellConstantType::kSmi: 6491c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch access = access.WithRepresentation(Representation::Smi()); 6492c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch break; 6493c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case PropertyCellConstantType::kStableMap: { 6494c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // First check that the previous value of the {cell} still has the 6495c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // map that we are about to check the new {value} for. If not, then 6496c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // the stable map assumption was invalidated and we cannot continue 6497c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // with the optimized code. 6498c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<HeapObject> cell_value(HeapObject::cast(cell->value())); 6499c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Map> cell_value_map(cell_value->map()); 6500c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!cell_value_map->is_stable()) { 6501c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Bailout(kUnstableConstantTypeHeapObject); 6502c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return nullptr; 6503c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 6504c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch top_info()->dependencies()->AssumeMapStable(cell_value_map); 6505c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Now check that the new {value} is a HeapObject with the same map 6506c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Add<HCheckHeapObject>(value); 6507c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch value = Add<HCheckMaps>(value, cell_value_map); 6508c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch access = access.WithRepresentation(Representation::HeapObject()); 6509c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch break; 6510c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 6511c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 6512c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 6513c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HInstruction* instr = New<HStoreNamedField>(cell_constant, access, value); 6514c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch instr->ClearChangesFlag(kInobjectFields); 6515c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch instr->SetChangesFlag(kGlobalVars); 6516c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return instr; 6517c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 6518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Because not every expression has a position and there is not common 6520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// superclass of Assignment and CountOperation, we cannot just pass the 6521b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// owning expression instead of position and ast_id separately. 652262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid HOptimizedGraphBuilder::HandleGlobalVariableAssignment(Variable* var, 652362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HValue* value, 652462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FeedbackSlot slot, 652562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BailoutId ast_id) { 6526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSGlobalObject> global(current_info()->global_object()); 6527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 6528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Lookup in script contexts. 6529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 6530958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<ScriptContextTable> script_contexts( 6531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier global->native_context()->script_context_table()); 6532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ScriptContextTable::LookupResult lookup; 6533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ScriptContextTable::Lookup(script_contexts, var->name(), &lookup)) { 6534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (lookup.mode == CONST) { 6535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Bailout(kNonInitializerAssignmentToConst); 6536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 6537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> script_context = 6538958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ScriptContextTable::GetContext(script_contexts, lookup.context_index); 6539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> current_value = 6541109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FixedArray::get(*script_context, lookup.slot_index, isolate()); 6542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the values is not the hole, it will stay initialized, 6544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // so no need to generate a check. 654513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (current_value->IsTheHole(isolate())) { 6546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Bailout(kReferenceToUninitializedVariable); 6547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 6548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HStoreNamedField* instr = Add<HStoreNamedField>( 6550958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HConstant>(script_context), 6551958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HObjectAccess::ForContextSlot(lookup.slot_index), value); 6552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier USE(instr); 6553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(instr->HasObservableSideEffects()); 6554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 6556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 6557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 6558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 6559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LookupIterator it(global, var->name(), LookupIterator::OWN); 6560c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (CanInlineGlobalPropertyAccess(var, &it, STORE)) { 6561c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HInstruction* instr = InlineGlobalPropertyStore(&it, value, ast_id); 6562c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!instr) return; 6563c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AddInstruction(instr); 6564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 6565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* global_object = Add<HLoadNamedField>( 6569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildGetNativeContext(), nullptr, 6570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess::ForContextSlot(Context::EXTENSION_INDEX)); 657162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FeedbackVector> vector = 6572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch handle(current_feedback_vector(), isolate()); 6573f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HValue* name = Add<HConstant>(var->name()); 6574f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HValue* vector_value = Add<HConstant>(vector); 6575f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HValue* slot_value = Add<HConstant>(vector->GetIndex(slot)); 657662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(vector->GetLanguageMode(slot), function_language_mode()); 6577f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Callable callable = CodeFactory::StoreICInOptimizedCode( 6578f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch isolate(), function_language_mode()); 6579f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HValue* stub = Add<HConstant>(callable.code()); 6580c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* values[] = {global_object, name, value, slot_value, vector_value}; 6581f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HCallWithDescriptor* instr = Add<HCallWithDescriptor>( 6582c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Code::STORE_IC, stub, 0, callable.descriptor(), ArrayVector(values)); 6583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch USE(instr); 6584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(instr->HasObservableSideEffects()); 6585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 6591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* target = expr->target(); 6592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VariableProxy* proxy = target->AsVariableProxy(); 6593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Property* prop = target->AsProperty(); 6594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(proxy == NULL || prop == NULL); 6595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have a second position recorded in the FullCodeGenerator to have 6597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // type feedback for the binary operation. 6598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BinaryOperation* operation = expr->binary_operation(); 6599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (proxy != NULL) { 6601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* var = proxy->var(); 6602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (var->mode() == LET) { 6603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kUnsupportedLetCompoundAssignment); 6604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(operation)); 6607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (var->location()) { 6609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::UNALLOCATED: 6610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleGlobalVariableAssignment(var, Top(), expr->AssignmentSlot(), 6611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->AssignmentId()); 6612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 6613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::PARAMETER: 6615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOCAL: 6616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (var->mode() == CONST) { 6617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Bailout(kNonInitializerAssignmentToConst); 6618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 6619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BindIfLive(var, Top()); 6620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 6621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::CONTEXT: { 6623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bail out if we try to mutate a parameter value in a function 6624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // using the arguments object. We do not (yet) correctly handle the 6625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // arguments property of the function. 6626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_info()->scope()->arguments() != NULL) { 6627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Parameters will be allocated to context slots. We have no 6628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // direct way to detect that the variable is a parameter so we do 6629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a linear search of the parameter variables. 6630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int count = current_info()->scope()->num_parameters(); 6631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < count; ++i) { 6632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (var == current_info()->scope()->parameter(i)) { 6633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bailout(kAssignmentToParameterFunctionUsesArgumentsObject); 6634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreContextSlot::Mode mode; 6639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (var->mode()) { 6641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LET: 6642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode = HStoreContextSlot::kCheckDeoptimize; 6643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 6644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CONST: 6645f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (var->throw_on_const_assignment(function_language_mode())) { 6646bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Bailout(kNonInitializerAssignmentToConst); 6647bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 6648bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return ast_context()->ReturnValue(Pop()); 6649bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 6650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 6651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode = HStoreContextSlot::kNoCheck; 6652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = BuildContextChainWalk(var); 6655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreContextSlot* instr = Add<HStoreContextSlot>( 6656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context, var->index(), mode, Top()); 6657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 6658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 6659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 6661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOOKUP: 6664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kCompoundAssignmentToLookupSlot); 6665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 6666f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case VariableLocation::MODULE: 6667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 6668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 6670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (prop != NULL) { 6672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(prop->obj())); 6673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object = Top(); 6674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = NULL; 6675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!prop->key()->IsPropertyName() || prop->IsStringAccess()) { 6676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(prop->key())); 6677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key = Top(); 6678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(PushLoad(prop, object, key)); 6681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->value())); 6683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right = Pop(); 6684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left = Pop(); 6685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(BuildBinaryOperation(operation, left, right, PUSH_BEFORE_SIMULATE)); 6687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildStore(expr, prop, expr->AssignmentSlot(), expr->id(), 6689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->AssignmentId(), expr->IsUninitialized()); 6690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kInvalidLhsInCompoundAssignment); 6692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { 6697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 6698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 6699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 6700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VariableProxy* proxy = expr->target()->AsVariableProxy(); 6702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Property* prop = expr->target()->AsProperty(); 6703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(proxy == NULL || prop == NULL); 6704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->is_compound()) { 6706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleCompoundAssignment(expr); 6707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 6708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (prop != NULL) { 6711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandlePropertyAssignment(expr); 6712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (proxy != NULL) { 6713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* var = proxy->var(); 6714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (var->mode() == CONST) { 6716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (expr->op() != Token::INIT) { 6717f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (var->throw_on_const_assignment(function_language_mode())) { 6718bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Bailout(kNonInitializerAssignmentToConst); 6719bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 6720bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CHECK_ALIVE(VisitForValue(expr->value())); 6721bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return ast_context()->ReturnValue(Pop()); 6722bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 6723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle the assignment. 6727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (var->location()) { 6728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::UNALLOCATED: 6729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->value())); 6730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleGlobalVariableAssignment(var, Top(), expr->AssignmentSlot(), 6731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->AssignmentId()); 6732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 6733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::PARAMETER: 6735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOCAL: { 6736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Perform an initialization check for let declared variables 6737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // or parameters. 6738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (var->mode() == LET && expr->op() == Token::ASSIGN) { 6739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* env_value = environment()->Lookup(var); 6740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (env_value == graph()->GetConstantHole()) { 6741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kAssignmentToLetVariableBeforeInitialization); 6742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We do not allow the arguments object to occur in a context where it 6745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // may escape, but assignments to stack-allocated locals are 6746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // permitted. 6747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); 6748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 6749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BindIfLive(var, value); 6750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(value); 6751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::CONTEXT: { 6754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bail out if we try to mutate a parameter value in a function using 6755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the arguments object. We do not (yet) correctly handle the 6756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // arguments property of the function. 6757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_info()->scope()->arguments() != NULL) { 6758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Parameters will rewrite to context slots. We have no direct way 6759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to detect that the variable is a parameter. 6760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int count = current_info()->scope()->num_parameters(); 6761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < count; ++i) { 6762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (var == current_info()->scope()->parameter(i)) { 6763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kAssignmentToParameterInArgumentsObject); 6764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->value())); 6769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreContextSlot::Mode mode; 6770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->op() == Token::ASSIGN) { 6771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (var->mode()) { 6772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LET: 6773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode = HStoreContextSlot::kCheckDeoptimize; 6774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 6775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CONST: 6776f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // If we reached this point, the only possibility 6777f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // is a sloppy assignment to a function name. 6778f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(function_language_mode() == SLOPPY && 6779f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch !var->throw_on_const_assignment(SLOPPY)); 6780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 6781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 6782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode = HStoreContextSlot::kNoCheck; 6783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(Token::INIT, expr->op()); 6786bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch mode = HStoreContextSlot::kNoCheck; 6787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = BuildContextChainWalk(var); 6790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreContextSlot* instr = Add<HStoreContextSlot>( 6791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context, var->index(), mode, Top()); 6792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasObservableSideEffects()) { 6793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 6794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 6796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOOKUP: 6799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kAssignmentToLOOKUPVariable); 6800f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 6801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case VariableLocation::MODULE: 6802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 6803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kInvalidLeftHandSideInAssignment); 6806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitYield(Yield* expr) { 6811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generators are not optimized, so we should never get here. 6812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 6813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitThrow(Throw* expr) { 6817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 6818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 6819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 6820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) { 6821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The parser turns invalid left-hand sides in assignments into throw 6822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // statements, which may not be in effect contexts. We might still try 6823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to optimize such functions; bail out now if we do. 6824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kInvalidLeftHandSideInAssignment); 6825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->exception())); 6827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = environment()->Pop(); 6829f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!is_tracking_positions()) SetSourcePosition(expr->position()); 6830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(value); 6831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kThrow), 1); 6832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->id()); 6833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the throw definitely exits the function, we can finish with a dummy 6835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // control flow at this point. This is not the case if the throw is inside 6836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // an inlined function which may be replaced. 6837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (call_context() == NULL) { 6838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishExitCurrentBlock(New<HAbnormalExit>()); 6839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) { 6844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (string->IsConstant()) { 6845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* c_string = HConstant::cast(string); 6846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (c_string->HasStringValue()) { 6847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HConstant>(c_string->StringValue()->map()->instance_type()); 6848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HLoadNamedField>( 6851958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HLoadNamedField>(string, nullptr, HObjectAccess::ForMap()), nullptr, 6852958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HObjectAccess::ForMapInstanceType()); 6853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::AddLoadStringLength(HValue* string) { 6857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return AddInstruction(BuildLoadStringLength(string)); 6858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 6859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHInstruction* HGraphBuilder::BuildLoadStringLength(HValue* string) { 6862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (string->IsConstant()) { 6863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* c_string = HConstant::cast(string); 6864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (c_string->HasStringValue()) { 6865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return New<HConstant>(c_string->StringValue()->length()); 6866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return New<HLoadNamedField>(string, nullptr, 6869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForStringLength()); 6870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( 687362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PropertyAccessType access_type, Expression* expr, FeedbackSlot slot, 6874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* object, Handle<Name> name, HValue* value, bool is_uninitialized) { 6875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_uninitialized) { 6876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HDeoptimize>( 6877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess, 6878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Deoptimizer::SOFT); 6879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 688062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FeedbackVector> vector(current_feedback_vector(), isolate()); 6881c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 6882c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* key = Add<HConstant>(name); 6883c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* vector_value = Add<HConstant>(vector); 6884c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* slot_value = Add<HConstant>(vector->GetIndex(slot)); 6885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6886c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (access_type == LOAD) { 6887c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* values[] = {object, key, slot_value, vector_value}; 6888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!expr->AsProperty()->key()->IsPropertyName()) { 688962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(vector->IsKeyedLoadIC(slot)); 6890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // It's possible that a keyed load of a constant string was converted 6891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to a named load. Here, at the last minute, we need to make sure to 6892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // use a generic Keyed Load if we are using the type vector, because 6893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // it has to share information with full code. 6894c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Callable callable = CodeFactory::KeyedLoadICInOptimizedCode(isolate()); 6895c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* stub = Add<HConstant>(callable.code()); 6896c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HCallWithDescriptor* result = 6897c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch New<HCallWithDescriptor>(Code::KEYED_LOAD_IC, stub, 0, 6898c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch callable.descriptor(), ArrayVector(values)); 6899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result; 6900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 690162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(vector->IsLoadIC(slot)); 6902c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Callable callable = CodeFactory::LoadICInOptimizedCode(isolate()); 6903c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* stub = Add<HConstant>(callable.code()); 6904c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HCallWithDescriptor* result = New<HCallWithDescriptor>( 6905c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Code::LOAD_IC, stub, 0, callable.descriptor(), ArrayVector(values)); 6906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 6907f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 6908c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 6909c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* values[] = {object, key, value, slot_value, vector_value}; 691062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (vector->IsKeyedStoreIC(slot)) { 6911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // It's possible that a keyed store of a constant string was converted 6912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to a named store. Here, at the last minute, we need to make sure to 6913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // use a generic Keyed Store if we are using the type vector, because 6914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // it has to share information with full code. 691562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(vector->GetLanguageMode(slot), function_language_mode()); 6916f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Callable callable = CodeFactory::KeyedStoreICInOptimizedCode( 6917f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch isolate(), function_language_mode()); 6918f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HValue* stub = Add<HConstant>(callable.code()); 6919c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HCallWithDescriptor* result = 6920c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch New<HCallWithDescriptor>(Code::KEYED_STORE_IC, stub, 0, 6921c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch callable.descriptor(), ArrayVector(values)); 6922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result; 6923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 692462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HCallWithDescriptor* result; 692562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (vector->IsStoreOwnIC(slot)) { 692662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Callable callable = CodeFactory::StoreOwnICInOptimizedCode(isolate()); 692762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HValue* stub = Add<HConstant>(callable.code()); 692862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch result = New<HCallWithDescriptor>( 692962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Code::STORE_IC, stub, 0, callable.descriptor(), ArrayVector(values)); 693062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 693162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(vector->IsStoreIC(slot)); 693262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(vector->GetLanguageMode(slot), function_language_mode()); 693362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Callable callable = CodeFactory::StoreICInOptimizedCode( 693462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate(), function_language_mode()); 693562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HValue* stub = Add<HConstant>(callable.code()); 693662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch result = New<HCallWithDescriptor>( 693762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Code::STORE_IC, stub, 0, callable.descriptor(), ArrayVector(values)); 693862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 6939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result; 6940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric( 694462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PropertyAccessType access_type, Expression* expr, FeedbackSlot slot, 6945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* object, HValue* key, HValue* value) { 694662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FeedbackVector> vector(current_feedback_vector(), isolate()); 6947c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* vector_value = Add<HConstant>(vector); 6948c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* slot_value = Add<HConstant>(vector->GetIndex(slot)); 6949c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 6950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == LOAD) { 6951c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* values[] = {object, key, slot_value, vector_value}; 6952c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 6953c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Callable callable = CodeFactory::KeyedLoadICInOptimizedCode(isolate()); 6954c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* stub = Add<HConstant>(callable.code()); 6955c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HCallWithDescriptor* result = 6956c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch New<HCallWithDescriptor>(Code::KEYED_LOAD_IC, stub, 0, 6957c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch callable.descriptor(), ArrayVector(values)); 6958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 6959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 6960c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* values[] = {object, key, value, slot_value, vector_value}; 6961f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 6962f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Callable callable = CodeFactory::KeyedStoreICInOptimizedCode( 6963f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch isolate(), function_language_mode()); 6964f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HValue* stub = Add<HConstant>(callable.code()); 6965c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HCallWithDescriptor* result = 6966c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch New<HCallWithDescriptor>(Code::KEYED_STORE_IC, stub, 0, 6967c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch callable.descriptor(), ArrayVector(values)); 6968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result; 6969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) { 6974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Loads from a "stock" fast holey double arrays can elide the hole check. 6975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Loads from a "stock" fast holey array can convert the hole to undefined 6976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // with impunity. 6977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; 6978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool holey_double_elements = 6979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS); 6980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool holey_elements = 6981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *map == isolate()->get_initial_js_array_map(FAST_HOLEY_ELEMENTS); 6982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if ((holey_double_elements || holey_elements) && 6983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->IsFastArrayConstructorPrototypeChainIntact()) { 6984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch load_mode = 6985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch holey_double_elements ? ALLOW_RETURN_HOLE : CONVERT_HOLE_TO_UNDEFINED; 6986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); 6988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); 6989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckPrototypeMaps(prototype, object_prototype); 6990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->MarkDependsOnEmptyArrayProtoElements(); 6991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return load_mode; 6993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( 6997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object, 6998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key, 6999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* val, 7000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* dependency, 7001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map, 7002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyAccessType access_type, 7003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch KeyedAccessStoreMode store_mode) { 7004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCheckMaps* checked_object = Add<HCheckMaps>(object, map, dependency); 7005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == STORE && map->prototype()->IsJSObject()) { 7007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // monomorphic stores need a prototype chain check because shape 7008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // changes could allow callbacks on elements in the chain that 7009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // aren't compatible with monomorphic keyed stores. 7010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrototypeIterator iter(map); 7011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject* holder = NULL; 7012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!iter.IsAtEnd()) { 7013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // JSProxies can't occur here because we wouldn't have installed a 7014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // non-generic IC if there were any. 7015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch holder = *PrototypeIterator::GetCurrent<JSObject>(iter); 7016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iter.Advance(); 7017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(holder && holder->IsJSObject()); 7019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckPrototypeMaps(handle(JSObject::cast(map->prototype())), 7021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject>(holder)); 7022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); 7025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildUncheckedMonomorphicElementAccess( 7026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object, key, val, 7027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->instance_type() == JS_ARRAY_TYPE, 7028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->elements_kind(), access_type, 7029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch load_mode, store_mode); 7030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic bool CanInlineElementAccess(Handle<Map> map) { 7034109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return map->IsJSObjectMap() && 7035109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch (map->has_fast_elements() || map->has_fixed_typed_array_elements()) && 7036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !map->has_indexed_interceptor() && !map->is_access_check_needed(); 7037958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 7038958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 7039958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 7040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( 7041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object, 7042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key, 7043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* val, 7044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList* maps) { 7045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For polymorphic loads of similar elements kinds (i.e. all tagged or all 7046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // double), always use the "worst case" code without a transition. This is 7047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // much faster than transitioning the elements to the worst case, trading a 7048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // HTransitionElements for a HCheckMaps, and avoiding mutation of the array. 7049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_double_maps = false; 7050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_smi_or_object_maps = false; 7051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_js_array_access = false; 7052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_non_js_array_access = false; 7053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_seen_holey_elements = false; 7054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> most_general_consolidated_map; 7055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < maps->length(); ++i) { 7056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = maps->at(i); 7057958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!CanInlineElementAccess(map)) return NULL; 7058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Don't allow mixing of JSArrays with JSObjects. 7059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map->instance_type() == JS_ARRAY_TYPE) { 7060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (has_non_js_array_access) return NULL; 7061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch has_js_array_access = true; 7062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (has_js_array_access) { 7063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 7064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch has_non_js_array_access = true; 7066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Don't allow mixed, incompatible elements kinds. 7068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map->has_fast_double_elements()) { 7069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (has_smi_or_object_maps) return NULL; 7070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch has_double_maps = true; 7071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (map->has_fast_smi_or_object_elements()) { 7072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (has_double_maps) return NULL; 7073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch has_smi_or_object_maps = true; 7074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 7076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remember if we've ever seen holey elements. 7078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsHoleyElementsKind(map->elements_kind())) { 7079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch has_seen_holey_elements = true; 7080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remember the most general elements kind, the code for its load will 7082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // properly handle all of the more specific cases. 7083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((i == 0) || IsMoreGeneralElementsKindTransition( 7084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch most_general_consolidated_map->elements_kind(), 7085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->elements_kind())) { 7086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch most_general_consolidated_map = map; 7087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!has_double_maps && !has_smi_or_object_maps) return NULL; 7090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCheckMaps* checked_object = Add<HCheckMaps>(object, maps); 7092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // FAST_ELEMENTS is considered more general than FAST_HOLEY_SMI_ELEMENTS. 7093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we've seen both, the consolidated load must use FAST_HOLEY_ELEMENTS. 7094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind consolidated_elements_kind = has_seen_holey_elements 7095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? GetHoleyElementsKind(most_general_consolidated_map->elements_kind()) 7096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : most_general_consolidated_map->elements_kind(); 7097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; 7098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (has_seen_holey_elements) { 7099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Make sure that all of the maps we are handling have the initial array 7100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // prototype. 7101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool saw_non_array_prototype = false; 7102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < maps->length(); ++i) { 7103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> map = maps->at(i); 7104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->prototype() != *isolate()->initial_array_prototype()) { 7105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We can't guarantee that loading the hole is safe. The prototype may 7106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // have an element at this position. 7107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch saw_non_array_prototype = true; 7108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 7109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 7110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 7111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!saw_non_array_prototype) { 7113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> holey_map = handle( 7114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()->get_initial_js_array_map(consolidated_elements_kind)); 7115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch load_mode = BuildKeyedHoleMode(holey_map); 7116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (load_mode != NEVER_RETURN_HOLE) { 7117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < maps->length(); ++i) { 7118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> map = maps->at(i); 7119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The prototype check was already done for the holey map in 7120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // BuildKeyedHoleMode. 7121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!map.is_identical_to(holey_map)) { 7122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSObject> prototype(JSObject::cast(map->prototype()), 7123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()); 7124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSObject> object_prototype = 7125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()->initial_object_prototype(); 7126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildCheckPrototypeMaps(prototype, object_prototype); 7127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 7128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 7129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 7130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 7131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 7132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = BuildUncheckedMonomorphicElementAccess( 7133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object, key, val, 7134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, 7135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch consolidated_elements_kind, LOAD, load_mode, STANDARD_STORE); 7136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return instr; 7137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( 714062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Expression* expr, FeedbackSlot slot, HValue* object, HValue* key, 7141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* val, SmallMapList* maps, PropertyAccessType access_type, 7142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch KeyedAccessStoreMode store_mode, bool* has_side_effects) { 7143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *has_side_effects = false; 7144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(object); 7145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == LOAD) { 7147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* consolidated_load = 7148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TryBuildConsolidatedElementLoad(object, key, val, maps); 7149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (consolidated_load != NULL) { 7150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *has_side_effects |= consolidated_load->HasObservableSideEffects(); 7151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return consolidated_load; 7152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Elements_kind transition support. 7156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapHandleList transition_target(maps->length()); 7157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Collect possible transition targets. 7158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapHandleList possible_transitioned_maps(maps->length()); 7159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < maps->length(); ++i) { 7160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = maps->at(i); 7161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Loads from strings or loads with a mix of string and non-string maps 7162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // shouldn't be handled polymorphically. 7163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(access_type != LOAD || !map->IsStringMap()); 7164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind = map->elements_kind(); 7165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (CanInlineElementAccess(map) && IsFastElementsKind(elements_kind) && 7166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind != GetInitialFastElementsKind()) { 7167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch possible_transitioned_maps.Add(map); 7168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsSloppyArgumentsElements(elements_kind)) { 7170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* result = 7171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildKeyedGeneric(access_type, expr, slot, object, key, val); 7172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *has_side_effects = result->HasObservableSideEffects(); 7173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddInstruction(result); 7174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Get transition target for each map (NULL == no transition). 7177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < maps->length(); ++i) { 7178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = maps->at(i); 7179bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Map* transitioned_map = 7180bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch map->FindElementsKindTransitionedMap(&possible_transitioned_maps); 7181bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (transitioned_map != nullptr) { 7182bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch transition_target.Add(handle(transitioned_map)); 7183bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 7184bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch transition_target.Add(Handle<Map>()); 7185bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 7186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapHandleList untransitionable_maps(maps->length()); 7189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HTransitionElementsKind* transition = NULL; 7190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < maps->length(); ++i) { 7191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = maps->at(i); 7192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(map->IsMap()); 7193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!transition_target.at(i).is_null()) { 7194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Map::IsValidElementsTransition( 7195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->elements_kind(), 7196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch transition_target.at(i)->elements_kind())); 7197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch transition = Add<HTransitionElementsKind>(object, map, 7198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch transition_target.at(i)); 7199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch untransitionable_maps.Add(map); 7201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If only one map is left after transitioning, handle this case 7205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // monomorphically. 7206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(untransitionable_maps.length() >= 1); 7207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (untransitionable_maps.length() == 1) { 7208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> untransitionable_map = untransitionable_maps[0]; 7209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = NULL; 7210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!CanInlineElementAccess(untransitionable_map)) { 7211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr = AddInstruction( 7212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildKeyedGeneric(access_type, expr, slot, object, key, val)); 7213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = BuildMonomorphicElementAccess( 7215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object, key, val, transition, untransitionable_map, access_type, 7216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_mode); 7217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *has_side_effects |= instr->HasObservableSideEffects(); 7219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return access_type == STORE ? val : instr; 7220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = graph()->CreateBasicBlock(); 7223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < untransitionable_maps.length(); ++i) { 7225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = untransitionable_maps[i]; 7226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind = map->elements_kind(); 7227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* this_map = graph()->CreateBasicBlock(); 7228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* other_map = graph()->CreateBasicBlock(); 7229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCompareMap* mapcompare = 7230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HCompareMap>(object, map, this_map, other_map); 7231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(mapcompare); 7232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(this_map); 7234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* access = NULL; 7235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!CanInlineElementAccess(map)) { 7236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch access = AddInstruction( 7237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildKeyedGeneric(access_type, expr, slot, object, key, val)); 7238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsFastElementsKind(elements_kind) || 7240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsFixedTypedArrayElementsKind(elements_kind)); 7241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); 7242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Happily, mapcompare is a checked object. 7243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch access = BuildUncheckedMonomorphicElementAccess( 7244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mapcompare, key, val, 7245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->instance_type() == JS_ARRAY_TYPE, 7246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind, access_type, 7247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch load_mode, 7248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch store_mode); 7249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *has_side_effects |= access->HasObservableSideEffects(); 7251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The caller will use has_side_effects and add a correct Simulate. 7252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch access->SetFlag(HValue::kHasNoObservableSideEffects); 7253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == LOAD) { 7254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(access); 7255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope scope(this); 7257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GotoNoSimulate(join); 7258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(other_map); 7259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Ensure that we visited at least one map above that goes to join. This is 7262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // necessary because FinishExitWithHardDeoptimization does an AbnormalExit 7263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // rather than joining the join block. If this becomes an issue, insert a 7264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // generic access in the case length() == 0. 7265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(join->predecessors()->length() > 0); 7266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Deopt if none of the cases matched. 7267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope scope(this); 7268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FinishExitWithHardDeoptimization( 7269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason::kUnknownMapInPolymorphicElementAccess); 7270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(join); 7271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return access_type == STORE ? val : Pop(); 7272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( 727562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HValue* obj, HValue* key, HValue* val, Expression* expr, FeedbackSlot slot, 727662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BailoutId ast_id, BailoutId return_id, PropertyAccessType access_type, 727762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool* has_side_effects) { 7278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // A keyed name access with type feedback may contain the name. 727962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FeedbackVector> vector = handle(current_feedback_vector(), isolate()); 7280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* expected_key = key; 7281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!key->ActualValue()->IsConstant()) { 7282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Name* name = nullptr; 7283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (access_type == LOAD) { 7284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch KeyedLoadICNexus nexus(vector, slot); 7285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch name = nexus.FindFirstName(); 7286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 7287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch KeyedStoreICNexus nexus(vector, slot); 7288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch name = nexus.FindFirstName(); 7289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 7290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (name != nullptr) { 7291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> handle_name(name); 7292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch expected_key = Add<HConstant>(handle_name); 7293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We need a check against the key. 7294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool in_new_space = isolate()->heap()->InNewSpace(*handle_name); 7295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Unique<Name> unique_name = Unique<Name>::CreateUninitialized(handle_name); 7296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HCheckValue>(key, unique_name, in_new_space); 7297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 7298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 7299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (expected_key->ActualValue()->IsConstant()) { 7300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> constant = 7301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant::cast(expected_key->ActualValue())->handle(isolate()); 7302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t array_index; 7303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if ((constant->IsString() && 7304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !Handle<String>::cast(constant)->AsArrayIndex(&array_index)) || 7305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constant->IsSymbol()) { 7306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!constant->IsUniqueName()) { 7307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constant = isolate()->factory()->InternalizeString( 7308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String>::cast(constant)); 7309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* access = 7311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildNamedAccess(access_type, ast_id, return_id, expr, slot, obj, 7312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name>::cast(constant), val, false); 7313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (access == NULL || access->IsPhi() || 7314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction::cast(access)->IsLinked()) { 7315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *has_side_effects = false; 7316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* instr = HInstruction::cast(access); 7318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(instr); 7319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *has_side_effects = instr->HasObservableSideEffects(); 7320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return access; 7322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!expr->IsPropertyName()); 7326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = NULL; 7327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmallMapList* maps; 7329109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bool monomorphic = ComputeReceiverTypes(expr, obj, &maps, this); 7330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool force_generic = false; 7332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (expr->GetKeyType() == PROPERTY) { 7333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Non-Generic accesses assume that elements are being accessed, and will 7334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // deopt for non-index keys, which the IC knows will occur. 7335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(jkummerow): Consider adding proper support for property accesses. 7336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier force_generic = true; 7337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier monomorphic = false; 7338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (access_type == STORE && 7339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (monomorphic || (maps != NULL && !maps->is_empty()))) { 7340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Stores can't be mono/polymorphic if their prototype chain has dictionary 7341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // elements. However a receiver map that has dictionary elements itself 7342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // should be left to normal mono/poly behavior (the other maps may benefit 7343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // from highly optimized stores). 7344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < maps->length(); i++) { 7345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> current_map = maps->at(i); 7346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_map->DictionaryElementsInPrototypeChainOnly()) { 7347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch force_generic = true; 7348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch monomorphic = false; 7349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 7350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (access_type == LOAD && !monomorphic && 7353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (maps != NULL && !maps->is_empty())) { 7354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Polymorphic loads have to go generic if any of the maps are strings. 7355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If some, but not all of the maps are strings, we should go generic 7356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // because polymorphic access wants to key on ElementsKind and isn't 7357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // compatible with strings. 7358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < maps->length(); i++) { 7359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> current_map = maps->at(i); 7360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (current_map->IsStringMap()) { 7361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier force_generic = true; 7362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 7363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 7364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 7365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (monomorphic) { 7368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> map = maps->first(); 7369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!CanInlineElementAccess(map)) { 7370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr = AddInstruction( 7371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildKeyedGeneric(access_type, expr, slot, obj, key, val)); 7372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(obj); 7374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = BuildMonomorphicElementAccess( 7375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj, key, val, NULL, map, access_type, expr->GetStoreMode()); 7376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (!force_generic && (maps != NULL && !maps->is_empty())) { 7378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return HandlePolymorphicElementAccess(expr, slot, obj, key, val, maps, 7379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch access_type, expr->GetStoreMode(), 7380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch has_side_effects); 7381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (access_type == STORE) { 7383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->IsAssignment() && 7384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->AsAssignment()->HasNoTypeInformation()) { 7385f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Add<HDeoptimize>( 7386f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess, 7387f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Deoptimizer::SOFT); 7388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->AsProperty()->HasNoTypeInformation()) { 7391f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Add<HDeoptimize>( 7392f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess, 7393f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Deoptimizer::SOFT); 7394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr = AddInstruction( 7397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildKeyedGeneric(access_type, expr, slot, obj, key, val)); 7398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *has_side_effects = instr->HasObservableSideEffects(); 7400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return instr; 7401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { 7405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Outermost function already has arguments on the stack. 7406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function_state()->outer() == NULL) return; 7407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function_state()->arguments_pushed()) return; 7409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Push arguments when entering inlined function. 7411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnterInlined* entry = function_state()->entry(); 7412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry->set_arguments_pushed(); 7413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HArgumentsObject* arguments = entry->arguments_object(); 7415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ZoneList<HValue*>* arguments_values = arguments->arguments_values(); 7416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* insert_after = entry; 7418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < arguments_values->length(); i++) { 7419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* argument = arguments_values->at(i); 7420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* push_argument = New<HPushArguments>(argument); 7421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch push_argument->InsertAfter(insert_after); 7422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch insert_after = push_argument; 7423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HArgumentsElements* arguments_elements = New<HArgumentsElements>(true); 7426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_elements->ClearFlag(HValue::kUseGVN); 7427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_elements->InsertAfter(insert_after); 7428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state()->set_arguments_elements(arguments_elements); 7429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7431c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochbool HOptimizedGraphBuilder::IsAnyParameterContextAllocated() { 7432c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int count = current_info()->scope()->num_parameters(); 7433c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch for (int i = 0; i < count; ++i) { 7434c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (current_info()->scope()->parameter(i)->location() == 7435c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch VariableLocation::CONTEXT) { 7436c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return true; 7437c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 7438c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 7439c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return false; 7440c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 7441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { 7443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VariableProxy* proxy = expr->obj()->AsVariableProxy(); 7444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (proxy == NULL) return false; 7445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!proxy->var()->IsStackAllocated()) return false; 7446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { 7447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 7448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NULL; 7451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->key()->IsPropertyName()) { 7452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 7453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!String::Equals(name, isolate()->factory()->length_string())) { 7454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 7455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 745713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Make sure we visit the arguments object so that the liveness analysis 745813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // still records the access. 745913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch CHECK_ALIVE_OR_RETURN(VisitForValue(expr->obj(), ARGUMENTS_ALLOWED), true); 746013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Drop(1); 746113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 7462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function_state()->outer() == NULL) { 7463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* elements = Add<HArgumentsElements>(false); 7464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = New<HArgumentsLength>(elements); 7465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Number of arguments without receiver. 7467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = environment()-> 7468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_environment()->parameter_count() - 1; 7469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = New<HConstant>(argument_count); 7470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7472c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // We need to take into account the KEYED_LOAD_IC feedback to guard the 7473c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // HBoundsCheck instructions below. 7474c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!expr->IsMonomorphic() && !expr->IsUninitialized()) return false; 7475c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (IsAnyParameterContextAllocated()) return false; 7476109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CHECK_ALIVE_OR_RETURN(VisitForValue(expr->obj(), ARGUMENTS_ALLOWED), true); 7477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE_OR_RETURN(VisitForValue(expr->key()), true); 7478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = Pop(); 7479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Arguments object. 7480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function_state()->outer() == NULL) { 7481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* elements = Add<HArgumentsElements>(false); 7482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* length = Add<HArgumentsLength>(elements); 7483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* checked_key = Add<HBoundsCheck>(key, length); 7484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = New<HAccessArgumentsAt>(elements, length, checked_key); 7485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnsureArgumentsArePushedForAccess(); 7487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Number of arguments without receiver. 7489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* elements = function_state()->arguments_elements(); 7490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = environment()-> 7491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_environment()->parameter_count() - 1; 7492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* length = Add<HConstant>(argument_count); 7493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* checked_key = Add<HBoundsCheck>(key, length); 7494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = New<HAccessArgumentsAt>(elements, length, checked_key); 7495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(result, expr->id()); 7498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 7499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHValue* HOptimizedGraphBuilder::BuildNamedAccess( 7502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAccessType access, BailoutId ast_id, BailoutId return_id, 750362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Expression* expr, FeedbackSlot slot, HValue* object, Handle<Name> name, 750462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HValue* value, bool is_uninitialized) { 7505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmallMapList* maps; 7506109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ComputeReceiverTypes(expr, object, &maps, this); 7507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(maps != NULL); 7508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7509c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Check for special case: Access via a single map to the global proxy 7510c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // can also be handled monomorphically. 7511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (maps->length() > 0) { 7512c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Object> map_constructor = 7513c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch handle(maps->first()->GetConstructor(), isolate()); 7514c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (map_constructor->IsJSFunction()) { 7515c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Context> map_context = 7516c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch handle(Handle<JSFunction>::cast(map_constructor)->context()); 7517c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Context> current_context(current_info()->context()); 7518c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch bool is_same_context_global_proxy_access = 7519c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch maps->length() == 1 && // >1 map => fallback to polymorphic 7520c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch maps->first()->IsJSGlobalProxyMap() && 7521c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch (*map_context == *current_context); 7522c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (is_same_context_global_proxy_access) { 7523c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<JSGlobalObject> global_object(current_info()->global_object()); 7524c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch LookupIterator it(global_object, name, LookupIterator::OWN); 7525c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (CanInlineGlobalPropertyAccess(&it, access)) { 7526c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch BuildCheckHeapObject(object); 7527c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Add<HCheckMaps>(object, maps); 7528c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (access == LOAD) { 7529c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InlineGlobalPropertyLoad(&it, expr->id()); 7530c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return nullptr; 7531c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 7532c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return InlineGlobalPropertyStore(&it, value, expr->id()); 7533c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 7534c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 7535c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 7536c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 7537c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 7538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAccessInfo info(this, access, maps->first(), name); 7539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!info.CanAccessAsMonomorphic(maps)) { 7540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandlePolymorphicNamedFieldAccess(access, expr, slot, ast_id, return_id, 7541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object, value, maps, name); 7542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 7543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_object; 7546f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // AstType::Number() is only supported by polymorphic load/call handling. 7547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!info.IsNumberType()); 7548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(object); 7549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (AreStringTypes(maps)) { 7550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object = 7551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); 7552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch checked_object = Add<HCheckMaps>(object, maps); 7554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildMonomorphicAccess( 7556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &info, object, checked_object, value, ast_id, return_id); 7557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return BuildNamedGeneric(access, expr, slot, object, name, value, 7560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch is_uninitialized); 7561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::PushLoad(Property* expr, 7565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object, 7566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key) { 7567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); 7568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(object); 7569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (key != NULL) Push(key); 7570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildLoad(expr, expr->LoadId()); 7571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildLoad(Property* expr, 7575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id) { 7576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = NULL; 7577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (expr->IsStringAccess() && expr->GetKeyType() == ELEMENT) { 7578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = Pop(); 7579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* string = Pop(); 7580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* char_code = BuildStringCharCodeAt(string, index); 7581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(char_code); 758262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (char_code->IsConstant()) { 758362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HConstant* c_code = HConstant::cast(char_code); 758462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (c_code->HasNumberValue() && std::isnan(c_code->DoubleValue())) { 758562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Add<HDeoptimize>(DeoptimizeReason::kOutOfBounds, Deoptimizer::EAGER); 758662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 758762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 7588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = NewUncasted<HStringCharFromCode>(char_code); 7589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (expr->key()->IsPropertyName()) { 7591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 7592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object = Pop(); 7593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* value = BuildNamedAccess(LOAD, ast_id, expr->LoadId(), expr, 7595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch expr->PropertyFeedbackSlot(), object, name, 7596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NULL, expr->IsUninitialized()); 7597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (value == NULL) return; 7598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (value->IsPhi()) return ast_context()->ReturnValue(value); 7599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr = HInstruction::cast(value); 7600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->IsLinked()) return ast_context()->ReturnValue(instr); 7601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 76028b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else { 7603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = Pop(); 7604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* obj = Pop(); 7605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_side_effects = false; 7607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* load = HandleKeyedElementAccess( 7608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch obj, key, NULL, expr, expr->PropertyFeedbackSlot(), ast_id, 7609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch expr->LoadId(), LOAD, &has_side_effects); 7610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (has_side_effects) { 7611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ast_context()->IsEffect()) { 7612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 7613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(load); 7615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 7616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 7617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (load == NULL) return; 7620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(load); 7621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, ast_id); 7623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitProperty(Property* expr) { 7627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 7628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 7629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 7630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryArgumentsAccess(expr)) return; 7632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->obj())); 7634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!expr->key()->IsPropertyName() || expr->IsStringAccess()) { 7635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->key())); 7636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildLoad(expr, expr->id()); 7639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 764162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochHInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant, 764262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool ensure_no_elements) { 7643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HCheckMaps* check = Add<HCheckMaps>( 7644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(constant), handle(constant->map())); 7645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch check->ClearDependsOnFlag(kElementsKind); 764662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (ensure_no_elements) { 764762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(ishell): remove this once we support NO_ELEMENTS elements kind. 764862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HValue* elements = AddLoadElements(check, nullptr); 764962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch HValue* empty_elements = 765062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Add<HConstant>(isolate()->factory()->empty_fixed_array()); 765162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch IfBuilder if_empty(this); 765262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if_empty.IfNot<HCompareObjectEqAndBranch>(elements, empty_elements); 765362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if_empty.ThenDeopt(DeoptimizeReason::kWrongMap); 765462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if_empty.End(); 765562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 7656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return check; 7657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype, 766062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSObject> holder, 766162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool ensure_no_elements) { 766213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrototypeIterator iter(isolate(), prototype, kStartAtReceiver); 7663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (holder.is_null() || 7664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !PrototypeIterator::GetCurrent(iter).is_identical_to(holder)) { 766562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BuildConstantMapCheck(PrototypeIterator::GetCurrent<JSObject>(iter), 766662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ensure_no_elements); 7667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iter.Advance(); 7668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (iter.IsAtEnd()) { 7669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 7670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 767262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return BuildConstantMapCheck(holder); 7673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, 7677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> receiver_map) { 7678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!holder.is_null()) { 7679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); 7680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckPrototypeMaps(prototype, holder); 7681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 76843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid HOptimizedGraphBuilder::BuildEnsureCallable(HValue* object) { 76853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch NoObservableSideEffectsScope scope(this); 76863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch const Runtime::Function* throw_called_non_callable = 76873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Runtime::FunctionForId(Runtime::kThrowCalledNonCallable); 76883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 76893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch IfBuilder is_not_function(this); 76903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HValue* smi_check = is_not_function.If<HIsSmiAndBranch>(object); 76913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch is_not_function.Or(); 76923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HValue* map = AddLoadMap(object, smi_check); 76933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HValue* bit_field = 76943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField()); 76953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HValue* bit_field_masked = AddUncasted<HBitwise>( 76963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Token::BIT_AND, bit_field, Add<HConstant>(1 << Map::kIsCallable)); 76973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch is_not_function.IfNot<HCompareNumericAndBranch>( 76983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bit_field_masked, Add<HConstant>(1 << Map::kIsCallable), Token::EQ); 76993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch is_not_function.Then(); 77003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch { 77013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Add<HPushArguments>(object); 77023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Add<HCallRuntime>(throw_called_non_callable, 1); 77033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 77043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch is_not_function.End(); 7705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 77073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochHInstruction* HOptimizedGraphBuilder::NewCallFunction( 77083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HValue* function, int argument_count, TailCallMode syntactic_tail_call_mode, 77093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ConvertReceiverMode convert_mode, TailCallMode tail_call_mode) { 77103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (syntactic_tail_call_mode == TailCallMode::kAllow) { 77113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch BuildEnsureCallable(function); 77123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 77133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(TailCallMode::kDisallow, tail_call_mode); 77143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 7715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* arity = Add<HConstant>(argument_count - 1); 7716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7717c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* op_vals[] = {function, arity}; 7718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 77193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Callable callable = 77203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CodeFactory::Call(isolate(), convert_mode, tail_call_mode); 7721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant* stub = Add<HConstant>(callable.code()); 7722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), 7724bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ArrayVector(op_vals), 77253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch syntactic_tail_call_mode); 7726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 77283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochHInstruction* HOptimizedGraphBuilder::NewCallFunctionViaIC( 77293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HValue* function, int argument_count, TailCallMode syntactic_tail_call_mode, 77303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ConvertReceiverMode convert_mode, TailCallMode tail_call_mode, 773162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FeedbackSlot slot) { 77323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (syntactic_tail_call_mode == TailCallMode::kAllow) { 77333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch BuildEnsureCallable(function); 7734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 77353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(TailCallMode::kDisallow, tail_call_mode); 7736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 77373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int arity = argument_count - 1; 773862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FeedbackVector> vector(current_feedback_vector(), isolate()); 7739c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* arity_val = Add<HConstant>(arity); 77403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HValue* index_val = Add<HConstant>(vector->GetIndex(slot)); 77413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HValue* vector_val = Add<HConstant>(vector); 77423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 7743c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* op_vals[] = {function, arity_val, index_val, vector_val}; 774462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Callable callable = 774562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CodeFactory::CallIC(isolate(), convert_mode, tail_call_mode); 77463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HConstant* stub = Add<HConstant>(callable.code()); 77473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 77483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), 7749bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ArrayVector(op_vals), 77503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch syntactic_tail_call_mode); 77513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 77523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 77533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochHInstruction* HOptimizedGraphBuilder::NewCallConstantFunction( 77543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<JSFunction> function, int argument_count, 77553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode syntactic_tail_call_mode, TailCallMode tail_call_mode) { 77563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HValue* target = Add<HConstant>(function); 77573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return New<HInvokeFunction>(target, function, argument_count, 77583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch syntactic_tail_call_mode, tail_call_mode); 7759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass FunctionSorter { 7763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 7764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit FunctionSorter(int index = 0, int ticks = 0, int size = 0) 7765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : index_(index), ticks_(ticks), size_(size) {} 7766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index() const { return index_; } 7768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int ticks() const { return ticks_; } 7769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size() const { return size_; } 7770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 7772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index_; 7773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int ticks_; 7774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size_; 7775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 7776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline bool operator<(const FunctionSorter& lhs, const FunctionSorter& rhs) { 7779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int diff = lhs.ticks() - rhs.ticks(); 7780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (diff != 0) return diff > 0; 7781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return lhs.size() < rhs.size(); 7782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::HandlePolymorphicCallNamed(Call* expr, 7786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* receiver, 7787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmallMapList* maps, 7788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<String> name) { 7789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = expr->arguments()->length() + 1; // Includes receiver. 7790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FunctionSorter order[kMaxCallPolymorphism]; 7791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool handle_smi = false; 7793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool handled_string = false; 7794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int ordered_functions = 0; 7795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 77963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode syntactic_tail_call_mode = expr->tail_call_mode(); 77973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode tail_call_mode = 77983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch function_state()->ComputeTailCallMode(syntactic_tail_call_mode); 77993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 7800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int i; 7801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (i = 0; i < maps->length() && ordered_functions < kMaxCallPolymorphism; 7802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++i) { 7803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAccessInfo info(this, LOAD, maps->at(i), name); 7804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info.CanAccessMonomorphic() && info.IsDataConstant() && 7805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info.constant()->IsJSFunction()) { 7806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info.IsStringType()) { 7807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (handled_string) continue; 7808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handled_string = true; 7809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant()); 7811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info.IsNumberType()) { 7812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle_smi = true; 7813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->set_target(target); 7815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch order[ordered_functions++] = FunctionSorter( 7816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i, target->shared()->profiler_ticks(), InliningAstSize(target)); 7817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch std::sort(order, order + ordered_functions); 7821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (i < maps->length()) { 7823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch maps->Clear(); 7824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ordered_functions = -1; 7825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* number_block = NULL; 7828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* join = NULL; 7829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handled_string = false; 7830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int count = 0; 7831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int fn = 0; fn < ordered_functions; ++fn) { 7833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int i = order[fn].index(); 7834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAccessInfo info(this, LOAD, maps->at(i), name); 7835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info.IsStringType()) { 7836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (handled_string) continue; 7837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handled_string = true; 7838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Reloads the target. 7840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info.CanAccessMonomorphic(); 7841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant()); 7842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->set_target(target); 7844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (count == 0) { 7845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Only needed once. 7846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch join = graph()->CreateBasicBlock(); 7847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (handle_smi) { 7848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); 7849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); 7850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_block = graph()->CreateBasicBlock(); 7851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(New<HIsSmiAndBranch>( 7852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver, empty_smi_block, not_smi_block)); 7853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GotoNoSimulate(empty_smi_block, number_block); 7854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(not_smi_block); 7855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(receiver); 7857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++count; 7860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_true = graph()->CreateBasicBlock(); 7861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_false = graph()->CreateBasicBlock(); 7862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HUnaryControlInstruction* compare; 7863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = info.map(); 7865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info.IsNumberType()) { 7866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); 7867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare = New<HCompareMap>(receiver, heap_number_map, if_true, if_false); 7868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (info.IsStringType()) { 7869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare = New<HIsStringAndBranch>(receiver, if_true, if_false); 7870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare = New<HCompareMap>(receiver, map, if_true, if_false); 7872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(compare); 7874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info.IsNumberType()) { 7876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GotoNoSimulate(if_true, number_block); 7877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_true = number_block; 7878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(if_true); 7881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddCheckPrototypeMaps(info.holder(), map); 7883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = Add<HConstant>(expr->target()); 7885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(0, function); 7886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(receiver); 7887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 7888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool needs_wrapping = info.NeedsWrappingFor(target); 7889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool try_inline = FLAG_polymorphic_inlining && !needs_wrapping; 7890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_inlining && try_inline) { 7891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> caller = current_info()->closure(); 7892f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::unique_ptr<char[]> caller_name = 7893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch caller->shared()->DebugName()->ToCString(); 7894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Trying to inline the polymorphic call to %s from %s\n", 7895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch name->ToCString().get(), 7896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch caller_name.get()); 7897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (try_inline && TryInlineCall(expr)) { 7899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Trying to inline will signal that we should bailout from the 7900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // entire compilation by setting stack overflow on the visitor. 7901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasStackOverflow()) return; 7902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Since HWrapReceiver currently cannot actually wrap numbers and strings, 79043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // use the regular call builtin for method calls to wrap the receiver. 7905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(verwaest): Support creation of value wrappers directly in 7906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // HWrapReceiver. 7907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* call = 79083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch needs_wrapping 79093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ? NewCallFunction( 79103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch function, argument_count, syntactic_tail_call_mode, 79113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode) 79123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch : NewCallConstantFunction(target, argument_count, 79133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch syntactic_tail_call_mode, 79143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch tail_call_mode); 7915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argument_count); 7916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(call); 7917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Drop the function. 7918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(call); 7919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_block() != NULL) Goto(join); 7922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(if_false); 7923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Finish up. Unconditionally deoptimize if we've handled all the maps we 7926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // know about and do not want to handle ones we've never seen. Otherwise 7927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // use a generic IC. 7928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) { 7929f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FinishExitWithHardDeoptimization( 7930f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason::kUnknownMapInPolymorphicCall); 7931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Property* prop = expr->expression()->AsProperty(); 7933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* function = 7934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver, 7935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch name, NULL, prop->IsUninitialized()); 7936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(function); 7937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(function); 7938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 7939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(1, function); 7941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(0, receiver); 7942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 7943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 79443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HInstruction* call = NewCallFunction( 79453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch function, argument_count, syntactic_tail_call_mode, 79463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode); 7947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argument_count); 7949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Function. 7951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (join != NULL) { 7953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(call); 7954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(call); 7955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(join); 7956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(call, expr->id()); 7958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We assume that control flow is always live after an expression. So 7962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // even without predecessors to the join block, we set it as the exit 7963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // block and continue by adding instructions there. 7964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(join != NULL); 7965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (join->HasPredecessor()) { 7966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(join); 7967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch join->SetJoinId(expr->id()); 7968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); 7969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 7971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::TraceInline(Handle<JSFunction> target, 7975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> caller, 79763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch const char* reason, 79773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode tail_call_mode) { 7978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_inlining) { 7979f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::unique_ptr<char[]> target_name = 7980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target->shared()->DebugName()->ToCString(); 7981f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::unique_ptr<char[]> caller_name = 7982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch caller->shared()->DebugName()->ToCString(); 7983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reason == NULL) { 79843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch const char* call_mode = 79853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch tail_call_mode == TailCallMode::kAllow ? "tail called" : "called"; 79863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch PrintF("Inlined %s %s from %s.\n", target_name.get(), call_mode, 7987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch caller_name.get()); 7988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 7989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Did not inline %s called from %s (%s).\n", 7990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target_name.get(), caller_name.get(), reason); 7991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kNotInlinable = 1000000000; 7997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint HOptimizedGraphBuilder::InliningAstSize(Handle<JSFunction> target) { 8000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_use_inlining) return kNotInlinable; 8001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Precondition: call is monomorphic and we have found a target with the 8003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // appropriate arity. 8004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> caller = current_info()->closure(); 8005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<SharedFunctionInfo> target_shared(target->shared()); 8006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Always inline functions that force inlining. 8008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (target_shared->force_inline()) { 8009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 0; 8010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 801162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!target->shared()->IsUserJavaScript()) { 8012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return kNotInlinable; 8013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (target_shared->IsApiFunction()) { 8016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target is api function"); 8017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kNotInlinable; 8018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Do a quick check on source code length to avoid parsing large 8021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inlining candidates. 8022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (target_shared->SourceSize() > 8023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Min(FLAG_max_inlined_source_size, kUnlimitedMaxInlinedSourceSize)) { 8024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target text too big"); 8025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kNotInlinable; 8026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Target must be inlineable. 8029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BailoutReason noopt_reason = target_shared->disable_optimization_reason(); 8030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!target_shared->IsInlineable() && noopt_reason != kHydrogenFilter) { 8031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target not inlineable"); 8032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kNotInlinable; 8033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (noopt_reason != kNoReason && noopt_reason != kHydrogenFilter) { 8035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target contains unsupported syntax [early]"); 8036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kNotInlinable; 8037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int nodes_added = target_shared->ast_node_count(); 8040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return nodes_added; 8041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 8042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target, 8044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int arguments_count, 8045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* implicit_return_value, 8046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BailoutId ast_id, BailoutId return_id, 80473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch InliningKind inlining_kind, 80483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode syntactic_tail_call_mode) { 8049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (target->context()->native_context() != 8050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch top_info()->closure()->context()->native_context()) { 8051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 8052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 8053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int nodes_added = InliningAstSize(target); 8054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (nodes_added == kNotInlinable) return false; 8055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> caller = current_info()->closure(); 8057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { 8058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target AST is too large [early]"); 8059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 8060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Don't inline deeper than the maximum number of inlining levels. 8063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* env = environment(); 8064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int current_level = 1; 8065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (env->outer() != NULL) { 8066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_level == FLAG_max_inlining_levels) { 8067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "inline depth limit reached"); 8068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 8069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (env->outer()->frame_type() == JS_FUNCTION) { 8071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_level++; 8072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env = env->outer(); 8074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Don't inline recursive functions. 8077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (FunctionState* state = function_state(); 8078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch state != NULL; 8079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch state = state->outer()) { 8080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (*state->compilation_info()->closure() == *target) { 8081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target is recursive"); 8082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 8083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We don't want to add more than a certain number of nodes from inlining. 8087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Always inline small methods (<= 10 nodes). 8088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (inlined_count_ > Min(FLAG_max_inlined_nodes_cumulative, 8089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kUnlimitedMaxInlinedNodesCumulative)) { 8090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "cumulative AST node limit reached"); 8091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 8092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Parse and allocate variables. 8095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Use the same AstValueFactory for creating strings in the sub-compilation 8096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // step, but don't transfer ownership to target_info. 8097c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<SharedFunctionInfo> target_shared(target->shared()); 809862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ParseInfo parse_info(target_shared, top_info()->parse_info()->zone_shared()); 8099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parse_info.set_ast_value_factory( 8100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch top_info()->parse_info()->ast_value_factory()); 8101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parse_info.set_ast_value_factory_owned(false); 8102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 810362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CompilationInfo target_info(parse_info.zone(), &parse_info, target); 8104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 8105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (inlining_kind != CONSTRUCT_CALL_RETURN && 8106109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch IsClassConstructor(target_shared->kind())) { 8107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TraceInline(target, caller, "target is classConstructor"); 8108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 8109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 8110109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 8111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (target_shared->HasDebugInfo()) { 8112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TraceInline(target, caller, "target is being debugged"); 8113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 8114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 8115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!Compiler::ParseAndAnalyze(target_info.parse_info())) { 8116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (target_info.isolate()->has_pending_exception()) { 8117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Parse or scope error, never optimize this function. 8118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetStackOverflow(); 8119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target_shared->DisableOptimization(kParseScopeError); 8120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "parse failure"); 8122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 8123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 812462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (target_shared->must_use_ignition_turbo()) { 8125bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch TraceInline(target, caller, "ParseAndAnalyze found incompatibility"); 8126bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return false; 8127bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 8128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8129f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (target_info.scope()->NeedsContext()) { 8130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target has context-allocated variables"); 8131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 8132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 8134f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (target_info.scope()->rest_parameter() != nullptr) { 8135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TraceInline(target, caller, "target uses rest parameters"); 8136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 8137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 8138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 8139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FunctionLiteral* function = target_info.literal(); 8140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The following conditions must be checked again after re-parsing, because 8142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // earlier the information might not have been complete due to lazy parsing. 8143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch nodes_added = function->ast_node_count(); 8144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { 8145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target AST is too large [late]"); 8146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 8147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function->dont_optimize()) { 8149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target contains unsupported syntax [late]"); 8150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 8151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the function uses the arguments object check that inlining of functions 8154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // with arguments object is enabled and the arguments-variable is 8155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // stack allocated. 8156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function->scope()->arguments() != NULL) { 8157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_inline_arguments) { 8158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target uses arguments object"); 8159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 8160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unsupported variable references present. 8164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (function->scope()->this_function_var() != nullptr || 8165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch function->scope()->new_target_var() != nullptr) { 8166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TraceInline(target, caller, "target uses new target or this function"); 8167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 8168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 8169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 8170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // All declarations must be inlineable. 8171c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Declaration::List* decls = target_info.scope()->declarations(); 8172c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch for (Declaration* decl : *decls) { 8173c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (decl->IsFunctionDeclaration() || 8174c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch !decl->proxy()->var()->IsStackAllocated()) { 8175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "target has non-trivial declaration"); 8176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 8177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 81788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 8179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generate the deoptimization data for the unoptimized version of 8181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the target function if we don't already have it. 8182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!Compiler::EnsureDeoptimizationSupport(&target_info)) { 8183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "could not generate deoptimization info"); 8184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 8185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 818613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 8187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Remember that we inlined this function. This needs to be called right 8188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // after the EnsureDeoptimizationSupport call so that the code flusher 8189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // does not remove the code with the deoptimization support. 8190c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int inlining_id = top_info()->AddInlinedFunction(target_info.shared_info(), 8191c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch source_position()); 8192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ---------------------------------------------------------------- 8194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // After this point, we've made a decision to inline this function (so 8195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TryInline should always return true). 8196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 819713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // If target was lazily compiled, it's literals array may not yet be set up. 819813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch JSFunction::EnsureLiterals(target); 819913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 8200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Type-check the inlined function. 8201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(target_shared->has_deoptimization_support()); 8202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AstTyper(target_info.isolate(), target_info.zone(), target_info.closure(), 8203bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch target_info.scope(), target_info.osr_ast_id(), target_info.literal(), 8204bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch &bounds_) 8205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch .Run(); 8206b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Save the pending call context. Set up new one for the inlined function. 8208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The function state is new-allocated because we need to delete it 8209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in two different places. 82103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FunctionState* target_state = new FunctionState( 82113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch this, &target_info, inlining_kind, inlining_id, 82123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch function_state()->ComputeTailCallMode(syntactic_tail_call_mode)); 8213b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* undefined = graph()->GetConstantUndefined(); 8215589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 82163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HEnvironment* inner_env = environment()->CopyForInlining( 82173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch target, arguments_count, function, undefined, 82183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch function_state()->inlining_kind(), syntactic_tail_call_mode); 8219589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 8220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* context = Add<HConstant>(Handle<Context>(target->context())); 8221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inner_env->BindContext(context); 8222589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 8223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create a dematerialized arguments object for the function, also copy the 8224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // current arguments values to use them for materialization. 8225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* arguments_env = inner_env->arguments_environment(); 8226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int parameter_count = arguments_env->parameter_count(); 8227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HArgumentsObject* arguments_object = Add<HArgumentsObject>(parameter_count); 8228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < parameter_count; i++) { 8229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments_object->AddArgument(arguments_env->Lookup(i), zone()); 8230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 82313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the function uses arguments object then bind bind one. 8233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function->scope()->arguments() != NULL) { 8234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(function->scope()->arguments()->IsStackAllocated()); 8235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inner_env->Bind(function->scope()->arguments(), arguments_object); 8236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 82373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Capture the state before invoking the inlined function for deopt in the 8239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inlined function. This simulate has no bailout-id since it's not directly 8240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // reachable for deopt, and is only used to capture the state. If the simulate 8241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // becomes reachable by merging, the ast id of the simulate merged into it is 8242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // adopted. 8243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(BailoutId::None()); 82443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_block()->UpdateEnvironment(inner_env); 8246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* saved_scope = scope(); 8247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_scope(target_info.scope()); 82483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HEnterInlined* enter_inlined = Add<HEnterInlined>( 82493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return_id, target, context, arguments_count, function, 82503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch function_state()->inlining_kind(), function->scope()->arguments(), 82513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch arguments_object, syntactic_tail_call_mode); 8252f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (is_tracking_positions()) { 8253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enter_inlined->set_inlining_id(inlining_id); 8254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 8255c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 8256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state()->set_entry(enter_inlined); 8257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitDeclarations(target_info.scope()->declarations()); 8259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitStatements(function->body()); 8260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_scope(saved_scope); 8261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasStackOverflow()) { 8262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bail out if the inline function did, as we cannot residualize a call 8263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instead, but do not disable optimization for the outer function. 8264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceInline(target, caller, "inline graph construction failed"); 8265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target_shared->DisableOptimization(kInliningBailedOut); 8266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_info()->RetryOptimization(kInliningBailedOut); 8267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete target_state; 8268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update inlined nodes count. 8272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inlined_count_ += nodes_added; 8273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> unoptimized_code(target_shared->code()); 8275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(unoptimized_code->kind() == Code::FUNCTION); 8276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<TypeFeedbackInfo> type_info( 8277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); 8278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->update_type_change_checksum(type_info->own_type_change_checksum()); 8279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 82803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TraceInline(target, caller, NULL, syntactic_tail_call_mode); 8281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_block() != NULL) { 8283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FunctionState* state = function_state(); 8284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { 8285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Falling off the end of an inlined construct call. In a test context the 8286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // return value will always evaluate to true, in a value context the 8287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // return value is the newly allocated receiver. 8288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (call_context()->IsTest()) { 8289109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inlined_test_context()->ReturnValue(graph()->GetConstantTrue()); 8290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (call_context()->IsEffect()) { 8291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(function_return(), state); 8292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 8293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call_context()->IsValue()); 8294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddLeaveInlined(implicit_return_value, state); 8295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (state->inlining_kind() == SETTER_CALL_RETURN) { 8297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Falling off the end of an inlined setter call. The returned value is 8298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // never used, the value of an assignment is always the value of the RHS 8299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of the assignment. 8300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (call_context()->IsTest()) { 8301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inlined_test_context()->ReturnValue(implicit_return_value); 8302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (call_context()->IsEffect()) { 8303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(function_return(), state); 8304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 8305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call_context()->IsValue()); 8306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddLeaveInlined(implicit_return_value, state); 8307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 8308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 8309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Falling off the end of a normal inlined function. This basically means 8310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // returning undefined. 8311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (call_context()->IsTest()) { 8312109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inlined_test_context()->ReturnValue(graph()->GetConstantFalse()); 8313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (call_context()->IsEffect()) { 8314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(function_return(), state); 8315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 8316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call_context()->IsValue()); 8317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddLeaveInlined(undefined, state); 8318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fix up the function exits. 8323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (inlined_test_context() != NULL) { 8324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_true = inlined_test_context()->if_true(); 8325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* if_false = inlined_test_context()->if_false(); 8326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnterInlined* entry = function_state()->entry(); 8328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pop the return test context from the expression context stack. 8330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(ast_context() == inlined_test_context()); 8331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearInlinedTestContext(); 8332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete target_state; 8333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Forward to the real test context. 8335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (if_true->HasPredecessor()) { 8336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry->RegisterReturnTarget(if_true, zone()); 8337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_true->SetJoinId(ast_id); 8338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* true_target = TestContext::cast(ast_context())->if_true(); 8339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(if_true, true_target, function_state()); 8340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (if_false->HasPredecessor()) { 8342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry->RegisterReturnTarget(if_false, zone()); 8343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_false->SetJoinId(ast_id); 8344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBasicBlock* false_target = TestContext::cast(ast_context())->if_false(); 8345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Goto(if_false, false_target, function_state()); 8346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 8347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 8348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (function_return()->HasPredecessor()) { 8351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state()->entry()->RegisterReturnTarget(function_return(), zone()); 8352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_return()->SetJoinId(ast_id); 8353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(function_return()); 8354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 8355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_current_block(NULL); 8356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 8357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete target_state; 8358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 8360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineCall(Call* expr) { 8363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return TryInline(expr->target(), expr->arguments()->length(), NULL, 83643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch expr->id(), expr->ReturnId(), NORMAL_RETURN, 83653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch expr->tail_call_mode()); 8366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 8367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, 8370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* implicit_return_value) { 8371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return TryInline(expr->target(), expr->arguments()->length(), 8372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch implicit_return_value, expr->id(), expr->ReturnId(), 83733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CONSTRUCT_CALL_RETURN, TailCallMode::kDisallow); 8374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 83753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8376109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool HOptimizedGraphBuilder::TryInlineGetter(Handle<Object> getter, 8377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> receiver_map, 8378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id, 8379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId return_id) { 8380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true; 838113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (getter->IsJSFunction()) { 838213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Handle<JSFunction> getter_function = Handle<JSFunction>::cast(getter); 838313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return TryInlineBuiltinGetterCall(getter_function, receiver_map, ast_id) || 838413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch TryInline(getter_function, 0, NULL, ast_id, return_id, 838513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch GETTER_CALL_RETURN, TailCallMode::kDisallow); 838613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 838713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return false; 8388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 83893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8390109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool HOptimizedGraphBuilder::TryInlineSetter(Handle<Object> setter, 8391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> receiver_map, 8392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId id, 8393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId assignment_id, 8394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* implicit_return_value) { 8395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineApiSetter(setter, receiver_map, id)) return true; 8396109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return setter->IsJSFunction() && 8397109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch TryInline(Handle<JSFunction>::cast(setter), 1, implicit_return_value, 83983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch id, assignment_id, SETTER_CALL_RETURN, 83993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode::kDisallow); 8400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 8401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool HOptimizedGraphBuilder::TryInlineIndirectCall(Handle<JSFunction> function, 8404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Call* expr, 8405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int arguments_count) { 8406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return TryInline(function, arguments_count, NULL, expr->id(), 84073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch expr->ReturnId(), NORMAL_RETURN, expr->tail_call_mode()); 8408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 8409589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 8410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr) { 8412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; 8413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); 84143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // We intentionally ignore expr->tail_call_mode() here because builtins 84153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // we inline here do not observe if they were tail called or not. 8416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (id) { 841713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kMathCos: 8418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathExp: 8419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathRound: 8420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathFround: 8421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathFloor: 8422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathAbs: 842313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kMathSin: 8424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathSqrt: 8425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathLog: 8426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathClz32: 8427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->arguments()->length() == 1) { 8428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* argument = Pop(); 8429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(2); // Receiver and function. 8430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id); 8431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(op, expr->id()); 8432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathImul: 8436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->arguments()->length() == 2) { 8437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right = Pop(); 8438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left = Pop(); 8439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(2); // Receiver and function. 8440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* op = 8441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HMul::NewImul(isolate(), zone(), context(), left, right); 8442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(op, expr->id()); 8443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8444589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 8445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 8447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Not supported for inlining yet. 8448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 8451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 84523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 84531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 8454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static 8455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool HOptimizedGraphBuilder::IsReadOnlyLengthDescriptor( 8456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> jsarray_map) { 8457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!jsarray_map->is_dictionary_map()); 8458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate = jsarray_map->GetIsolate(); 8459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> length_string = isolate->factory()->length_string(); 8460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DescriptorArray* descriptors = jsarray_map->instance_descriptors(); 8461109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int number = 8462109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch descriptors->SearchWithCache(isolate, *length_string, *jsarray_map); 8463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(DescriptorArray::kNotFound, number); 8464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return descriptors->GetDetails(number).IsReadOnly(); 8465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 8466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 8467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 8468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static 8469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool HOptimizedGraphBuilder::CanInlineArrayResizeOperation( 8470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> receiver_map) { 8471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return !receiver_map.is_null() && receiver_map->prototype()->IsJSObject() && 8472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver_map->instance_type() == JS_ARRAY_TYPE && 8473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsFastElementsKind(receiver_map->elements_kind()) && 8474bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch !receiver_map->is_dictionary_map() && receiver_map->is_extensible() && 8475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (!receiver_map->is_prototype_map() || receiver_map->is_stable()) && 8476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !IsReadOnlyLengthDescriptor(receiver_map); 8477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 8478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 847913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochbool HOptimizedGraphBuilder::TryInlineBuiltinGetterCall( 848013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Handle<JSFunction> function, Handle<Map> receiver_map, BailoutId ast_id) { 848113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!function->shared()->HasBuiltinFunctionId()) return false; 848213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch BuiltinFunctionId id = function->shared()->builtin_function_id(); 848313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 848413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Try to inline getter calls like DataView.prototype.byteLength/byteOffset 848513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // as operations in the calling function. 848613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch switch (id) { 848713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kDataViewBuffer: { 848813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!receiver_map->IsJSDataViewMap()) return false; 848913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HObjectAccess access = HObjectAccess::ForMapAndOffset( 849013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch receiver_map, JSDataView::kBufferOffset); 849113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HValue* object = Pop(); // receiver 849213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HInstruction* result = New<HLoadNamedField>(object, object, access); 849313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ast_context()->ReturnInstruction(result, ast_id); 849413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return true; 849513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 849613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kDataViewByteLength: 849713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kDataViewByteOffset: { 849813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!receiver_map->IsJSDataViewMap()) return false; 849913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch int offset = (id == kDataViewByteLength) ? JSDataView::kByteLengthOffset 850013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch : JSDataView::kByteOffsetOffset; 850113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HObjectAccess access = 850213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HObjectAccess::ForMapAndOffset(receiver_map, offset); 850313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HValue* object = Pop(); // receiver 850413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HValue* checked_object = Add<HCheckArrayBufferNotNeutered>(object); 850513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HInstruction* result = 850613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch New<HLoadNamedField>(object, checked_object, access); 850713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ast_context()->ReturnInstruction(result, ast_id); 850813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return true; 850913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 851013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kTypedArrayByteLength: 851113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kTypedArrayByteOffset: 851213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kTypedArrayLength: { 851313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!receiver_map->IsJSTypedArrayMap()) return false; 851413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch int offset = (id == kTypedArrayLength) 851513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ? JSTypedArray::kLengthOffset 851613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch : (id == kTypedArrayByteLength) 851713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ? JSTypedArray::kByteLengthOffset 851813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch : JSTypedArray::kByteOffsetOffset; 851913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HObjectAccess access = 852013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HObjectAccess::ForMapAndOffset(receiver_map, offset); 852113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HValue* object = Pop(); // receiver 852213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HValue* checked_object = Add<HCheckArrayBufferNotNeutered>(object); 852313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HInstruction* result = 852413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch New<HLoadNamedField>(object, checked_object, access); 852513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ast_context()->ReturnInstruction(result, ast_id); 852613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return true; 852713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 852813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch default: 852913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return false; 853013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 853113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 8532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 853362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// static 853462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool HOptimizedGraphBuilder::NoElementsInPrototypeChain( 853562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Map> receiver_map) { 853662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(ishell): remove this once we support NO_ELEMENTS elements kind. 853762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PrototypeIterator iter(receiver_map); 853862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> empty_fixed_array = 853962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch iter.isolate()->factory()->empty_fixed_array(); 854062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch while (true) { 854162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter); 854262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (current->elements() != *empty_fixed_array) return false; 854362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch iter.Advance(); 854462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (iter.IsAtEnd()) { 854562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return true; 854662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 854762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 854862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 854962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 8550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( 855113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Handle<JSFunction> function, Handle<Map> receiver_map, BailoutId ast_id, 8552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int args_count_no_receiver) { 8553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!function->shared()->HasBuiltinFunctionId()) return false; 8554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BuiltinFunctionId id = function->shared()->builtin_function_id(); 8555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int argument_count = args_count_no_receiver + 1; // Plus receiver. 8556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 8557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (receiver_map.is_null()) { 8558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* receiver = environment()->ExpressionStackAt(args_count_no_receiver); 8559958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (receiver->IsConstant() && 8560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HConstant::cast(receiver)->handle(isolate())->IsHeapObject()) { 8561958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier receiver_map = 8562958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier handle(Handle<HeapObject>::cast( 8563958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HConstant::cast(receiver)->handle(isolate()))->map()); 8564958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 8565958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 8566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Try to inline calls like Math.* as operations in the calling function. 8567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (id) { 85683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kObjectHasOwnProperty: { 85693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // It's not safe to look through the phi for elements if we're compiling 85703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // for osr. 85713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (top_info()->is_osr()) return false; 85723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (argument_count != 2) return false; 85733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HValue* key = Top(); 85743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (!key->IsLoadKeyed()) return false; 85753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HValue* elements = HLoadKeyed::cast(key)->elements(); 85763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (!elements->IsPhi() || elements->OperandCount() != 1) return false; 85773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (!elements->OperandAt(0)->IsForInCacheArray()) return false; 85783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HForInCacheArray* cache = HForInCacheArray::cast(elements->OperandAt(0)); 85793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HValue* receiver = environment()->ExpressionStackAt(1); 85803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (!receiver->IsPhi() || receiver->OperandCount() != 1) return false; 85813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (cache->enumerable() != receiver->OperandAt(0)) return false; 85823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Drop(3); // key, receiver, function 85833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Add<HCheckMapValue>(receiver, cache->map()); 85843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ast_context()->ReturnValue(graph()->GetConstantTrue()); 85853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return true; 85863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 8587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kStringCharCodeAt: 8588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kStringCharAt: 8589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument_count == 2) { 8590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = Pop(); 8591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* string = Pop(); 8592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Function. 8593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* char_code = 8594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildStringCharCodeAt(string, index); 8595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (id == kStringCharCodeAt) { 859613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ast_context()->ReturnInstruction(char_code, ast_id); 8597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInstruction(char_code); 8600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NewUncasted<HStringCharFromCode>(char_code); 860113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ast_context()->ReturnInstruction(result, ast_id); 8602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kStringFromCharCode: 8606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument_count == 2) { 8607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* argument = Pop(); 8608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(2); // Receiver and function. 86093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch argument = AddUncasted<HForceRepresentation>( 86103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch argument, Representation::Integer32()); 86113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch argument->SetFlag(HValue::kTruncatingToInt32); 8612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NewUncasted<HStringCharFromCode>(argument); 861313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ast_context()->ReturnInstruction(result, ast_id); 8614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 861713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kMathCos: 8618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathExp: 8619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathRound: 8620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathFround: 8621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathFloor: 8622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathAbs: 862313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kMathSin: 8624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathSqrt: 8625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathLog: 8626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathClz32: 8627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument_count == 2) { 8628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* argument = Pop(); 8629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(2); // Receiver and function. 8630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id); 863113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ast_context()->ReturnInstruction(op, ast_id); 8632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathPow: 8636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument_count == 3) { 8637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right = Pop(); 8638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left = Pop(); 8639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(2); // Receiver and function. 8640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NULL; 8641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Use sqrt() if exponent is 0.5 or -0.5. 8642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { 8643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double exponent = HConstant::cast(right)->DoubleValue(); 8644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (exponent == 0.5) { 8645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = NewUncasted<HUnaryMathOperation>(left, kMathPowHalf); 8646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (exponent == -0.5) { 8647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* one = graph()->GetConstant1(); 8648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* sqrt = AddUncasted<HUnaryMathOperation>( 8649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left, kMathPowHalf); 8650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // MathPowHalf doesn't have side effects so there's no need for 8651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // an environment simulation here. 8652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!sqrt->HasObservableSideEffects()); 8653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = NewUncasted<HDiv>(one, sqrt); 8654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (exponent == 2.0) { 8655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = NewUncasted<HMul>(left, left); 86563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 86573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 86583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (result == NULL) { 8660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = NewUncasted<HPower>(left, right); 86613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 866213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ast_context()->ReturnInstruction(result, ast_id); 8663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8664589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 8665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathMax: 8667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathMin: 8668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument_count == 3) { 8669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right = Pop(); 8670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left = Pop(); 8671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(2); // Receiver and function. 8672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin 8673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : HMathMinMax::kMathMax; 8674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = NewUncasted<HMathMinMax>(left, right, op); 867513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ast_context()->ReturnInstruction(result, ast_id); 8676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kMathImul: 8680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument_count == 3) { 8681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right = Pop(); 8682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left = Pop(); 8683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(2); // Receiver and function. 8684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* result = 8685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HMul::NewImul(isolate(), zone(), context(), left, right); 868613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ast_context()->ReturnInstruction(result, ast_id); 8687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 8690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArrayPop: { 8691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!CanInlineArrayResizeOperation(receiver_map)) return false; 8692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind = receiver_map->elements_kind(); 8693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Drop(args_count_no_receiver); 8695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result; 8696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* reduced_length; 8697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver = Pop(); 86981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 8699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_object = AddCheckMap(receiver, receiver_map); 8700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* length = 8701958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HLoadNamedField>(checked_object, nullptr, 8702958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HObjectAccess::ForArrayLength(elements_kind)); 8703b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Function. 8705b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { NoObservableSideEffectsScope scope(this); 8707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder length_checker(this); 8708b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* bounds_check = length_checker.If<HCompareNumericAndBranch>( 8710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length, graph()->GetConstant0(), Token::EQ); 8711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.Then(); 8712b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(graph()->GetConstantUndefined()); 8714b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.Else(); 8716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements = AddLoadElements(checked_object); 8717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Ensure that we aren't popping from a copy-on-write array. 8718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFastSmiOrObjectElementsKind(elements_kind)) { 8719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements = BuildCopyElementsOnWrite(checked_object, elements, 8720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind, length); 8721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reduced_length = AddUncasted<HSub>(length, graph()->GetConstant1()); 8723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch result = AddElementAccess(elements, reduced_length, nullptr, 8724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bounds_check, nullptr, elements_kind, LOAD); 8725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) 8726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? graph()->GetConstantHole() 8727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Add<HConstant>(HConstant::kHoleNaN); 8728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFastSmiOrObjectElementsKind(elements_kind)) { 8729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements_kind = FAST_HOLEY_ELEMENTS; 8730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddElementAccess(elements, reduced_length, hole, bounds_check, nullptr, 8732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements_kind, STORE); 8733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 8734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checked_object, HObjectAccess::ForArrayLength(elements_kind), 8735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reduced_length, STORE_TO_INITIALIZED_ENTRY); 8736b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(result); 8738b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length_checker.End(); 8740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); 874213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 8743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Drop(1); 8744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnValue(result); 8746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArrayPush: { 8749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!CanInlineArrayResizeOperation(receiver_map)) return false; 8750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind = receiver_map->elements_kind(); 8751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there may be elements accessors in the prototype chain, the fast 8753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inlined version can't be used. 8754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; 8755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there currently can be no elements accessors on the prototype chain, 8756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // it doesn't mean that there won't be any later. Install a full prototype 8757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chain check to trap element accessors being installed on the prototype 8758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chain, which would cause elements to go to dictionary mode and result 8759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in a map change. 8760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); 8761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckPrototypeMaps(prototype, Handle<JSObject>()); 8762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Protect against adding elements to the Array prototype, which needs to 8764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // route through appropriate bottlenecks. 8765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (isolate()->IsFastArrayConstructorPrototypeChainIntact() && 8766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !prototype->IsJSArray()) { 8767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 8768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 8769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 8770958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const int argc = args_count_no_receiver; 8771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argc != 1) return false; 8772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value_to_push = Pop(); 8774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* array = Pop(); 8775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Drop function. 8776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* new_size = NULL; 8778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length = NULL; 8779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope scope(this); 8782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8783958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier length = Add<HLoadNamedField>( 8784958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier array, nullptr, HObjectAccess::ForArrayLength(elements_kind)); 8785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_size = AddUncasted<HAdd>(length, graph()->GetConstant1()); 8787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 8789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* checked_array = Add<HCheckMaps>(array, receiver_map); 8790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildUncheckedMonomorphicElementAccess( 8791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch checked_array, length, value_to_push, is_array, elements_kind, 8792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STORE, NEVER_RETURN_HOLE, STORE_AND_GROW_NO_TRANSITION); 8793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(new_size); 879513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 8796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Drop(1); 8797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8798b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnValue(new_size); 8800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArrayShift: { 8803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!CanInlineArrayResizeOperation(receiver_map)) return false; 880462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!NoElementsInPrototypeChain(receiver_map)) return false; 8805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind = receiver_map->elements_kind(); 8806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there may be elements accessors in the prototype chain, the fast 8808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inlined version can't be used. 8809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; 8810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there currently can be no elements accessors on the prototype chain, 8812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // it doesn't mean that there won't be any later. Install a full prototype 8813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chain check to trap element accessors being installed on the prototype 8814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chain, which would cause elements to go to dictionary mode and result 8815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in a map change. 8816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckPrototypeMaps( 8817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle(JSObject::cast(receiver_map->prototype()), isolate()), 881862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSObject>::null(), true); 8819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Threshold for fast inlined Array.shift(). 8821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* inline_threshold = Add<HConstant>(static_cast<int32_t>(16)); 8822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Drop(args_count_no_receiver); 8824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result; 8825f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HValue* receiver = Pop(); 8826f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HValue* checked_object = AddCheckMap(receiver, receiver_map); 8827f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HValue* length = Add<HLoadNamedField>( 8828f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch receiver, checked_object, HObjectAccess::ForArrayLength(kind)); 8829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8830f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Drop(1); // Function. 8831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope scope(this); 8833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_lengthiszero(this); 8835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* lengthiszero = if_lengthiszero.If<HCompareNumericAndBranch>( 8836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length, graph()->GetConstant0(), Token::EQ); 8837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_lengthiszero.Then(); 8838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(graph()->GetConstantUndefined()); 8840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_lengthiszero.Else(); 8842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements = AddLoadElements(receiver); 8844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if we can use the fast inlined Array.shift(). 8846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_inline(this); 8847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_inline.If<HCompareNumericAndBranch>( 8848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length, inline_threshold, Token::LTE); 8849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFastSmiOrObjectElementsKind(kind)) { 8850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We cannot handle copy-on-write backing stores here. 8851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_inline.AndIf<HCompareMap>( 8852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements, isolate()->factory()->fixed_array_map()); 8853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_inline.Then(); 8855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remember the result. 8857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) { 8858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(AddElementAccess(elements, graph()->GetConstant0(), nullptr, 8859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lengthiszero, nullptr, kind, LOAD)); 8860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8861b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the new length. 8863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_length = AddUncasted<HSub>( 8864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length, graph()->GetConstant1()); 8865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_length->ClearFlag(HValue::kCanOverflow); 8866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy the remaining elements. 8868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); 8869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* new_key = loop.BeginBody( 8871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0(), new_length, Token::LT); 8872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = AddUncasted<HAdd>(new_key, graph()->GetConstant1()); 8873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key->ClearFlag(HValue::kCanOverflow); 8874958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ElementsKind copy_kind = 8875958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier kind == FAST_HOLEY_SMI_ELEMENTS ? FAST_HOLEY_ELEMENTS : kind; 8876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* element = 8877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddUncasted<HLoadKeyed>(elements, key, lengthiszero, nullptr, 8878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch copy_kind, ALLOW_RETURN_HOLE); 8879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HStoreKeyed* store = Add<HStoreKeyed>(elements, new_key, element, 8880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch nullptr, copy_kind); 8881c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch store->SetFlag(HValue::kTruncatingToNumber); 8882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.EndBody(); 8884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Put a hole at the end. 8886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* hole = IsFastSmiOrObjectElementsKind(kind) 8887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? graph()->GetConstantHole() 8888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Add<HConstant>(HConstant::kHoleNaN); 8889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFastSmiOrObjectElementsKind(kind)) kind = FAST_HOLEY_ELEMENTS; 8890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreKeyed>(elements, new_length, hole, nullptr, kind, 8891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch INITIALIZING_STORE); 8892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remember new length. 8894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 8895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver, HObjectAccess::ForArrayLength(kind), 8896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_length, STORE_TO_INITIALIZED_ENTRY); 8897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_inline.Else(); 8899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 8900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(receiver); 89013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch result = AddInstruction(NewCallConstantFunction( 89023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch function, 1, TailCallMode::kDisallow, TailCallMode::kDisallow)); 8903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(result); 8904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_inline.End(); 89063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_lengthiszero.End(); 89083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 8909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); 891013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 8911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Drop(1); 8912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnValue(result); 8913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 8914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArrayIndexOf: 8916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArrayLastIndexOf: { 8917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map.is_null()) return false; 8918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; 8919109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!receiver_map->prototype()->IsJSObject()) return false; 8920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind = receiver_map->elements_kind(); 8921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsFastElementsKind(kind)) return false; 8922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (argument_count != 2) return false; 8923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!receiver_map->is_extensible()) return false; 8924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there may be elements accessors in the prototype chain, the fast 8926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inlined version can't be used. 8927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; 8928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If there currently can be no elements accessors on the prototype chain, 8930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // it doesn't mean that there won't be any later. Install a full prototype 8931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chain check to trap element accessors being installed on the prototype 8932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chain, which would cause elements to go to dictionary mode and result 8933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in a map change. 8934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckPrototypeMaps( 8935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle(JSObject::cast(receiver_map->prototype()), isolate()), 8936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject>::null()); 8937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* search_element = Pop(); 8939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver = Pop(); 8940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Drop function. 89413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArrayIndexOfMode mode = (id == kArrayIndexOf) 8943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? kFirstIndexOf : kLastIndexOf; 8944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = BuildArrayIndexOf(receiver, search_element, kind, mode); 89453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Push(index); 894713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 8948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ast_context()->IsEffect()) Drop(1); 8949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnValue(index); 8950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 89513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 8953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Not yet supported for inlining. 8954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 89553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 89573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 89583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 89593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineApiFunctionCall(Call* expr, 8961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver) { 8962c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (V8_UNLIKELY(FLAG_runtime_stats)) return false; 8963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> function = expr->target(); 8964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argc = expr->arguments()->length(); 8965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList receiver_maps; 89663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return TryInlineApiCall(function, receiver, &receiver_maps, argc, expr->id(), 89673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch kCallApiFunction, expr->tail_call_mode()); 8968b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 8969b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8970b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOptimizedGraphBuilder::TryInlineApiMethodCall( 8972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Call* expr, 8973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver, 8974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList* receiver_maps) { 8975c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (V8_UNLIKELY(FLAG_runtime_stats)) return false; 8976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> function = expr->target(); 8977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argc = expr->arguments()->length(); 89783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return TryInlineApiCall(function, receiver, receiver_maps, argc, expr->id(), 89793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch kCallApiMethod, expr->tail_call_mode()); 8980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 89813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8982109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool HOptimizedGraphBuilder::TryInlineApiGetter(Handle<Object> function, 8983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> receiver_map, 8984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id) { 8985c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (V8_UNLIKELY(FLAG_runtime_stats)) return false; 8986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList receiver_maps(1, zone()); 8987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver_maps.Add(receiver_map, zone()); 8988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return TryInlineApiCall(function, 8989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL, // Receiver is on expression stack. 89903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch &receiver_maps, 0, ast_id, kCallApiGetter, 89913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode::kDisallow); 8992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 89933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8994109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool HOptimizedGraphBuilder::TryInlineApiSetter(Handle<Object> function, 8995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> receiver_map, 8996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId ast_id) { 8997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmallMapList receiver_maps(1, zone()); 8998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver_maps.Add(receiver_map, zone()); 8999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return TryInlineApiCall(function, 9000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL, // Receiver is on expression stack. 90013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch &receiver_maps, 1, ast_id, kCallApiSetter, 90023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode::kDisallow); 9003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 90043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 90053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochbool HOptimizedGraphBuilder::TryInlineApiCall( 90063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<Object> function, HValue* receiver, SmallMapList* receiver_maps, 90073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int argc, BailoutId ast_id, ApiCallType call_type, 90083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode syntactic_tail_call_mode) { 9009c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (V8_UNLIKELY(FLAG_runtime_stats)) return false; 9010109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (function->IsJSFunction() && 9011109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<JSFunction>::cast(function)->context()->native_context() != 9012109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch top_info()->closure()->context()->native_context()) { 9013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 9014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 90153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (argc > CallApiCallbackStub::kArgMax) { 90163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return false; 90173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 90183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 9019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallOptimization optimization(function); 9020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!optimization.is_simple_api_call()) return false; 9021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> holder_map; 9022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < receiver_maps->length(); ++i) { 9023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto map = receiver_maps->at(i); 9024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Don't inline calls to receivers requiring accesschecks. 9025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->is_access_check_needed()) return false; 9026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 9027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (call_type == kCallApiFunction) { 9028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Cannot embed a direct reference to the global proxy map 9029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // as it maybe dropped on deserialization. 9030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!isolate()->serializer_enabled()); 9031109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(function->IsJSFunction()); 9032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(0, receiver_maps->length()); 9033109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch receiver_maps->Add( 9034109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch handle(Handle<JSFunction>::cast(function)->global_proxy()->map()), 9035109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch zone()); 9036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallOptimization::HolderLookup holder_lookup = 9038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallOptimization::kHolderNotFound; 9039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType( 9040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver_maps->first(), &holder_lookup); 9041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (holder_lookup == CallOptimization::kHolderNotFound) return false; 90423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_inlining) { 9044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Inlining api function "); 9045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function->ShortPrint(); 9046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("\n"); 9047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_function = false; 9050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_store = false; 9051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (call_type) { 9052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kCallApiFunction: 9053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kCallApiMethod: 9054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Need to check that none of the receiver maps could have changed. 9055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckMaps>(receiver, receiver_maps); 9056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Need to ensure the chain between receiver and api_holder is intact. 9057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (holder_lookup == CallOptimization::kHolderFound) { 9058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddCheckPrototypeMaps(api_holder, receiver_maps->first()); 9059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 9060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(holder_lookup, CallOptimization::kHolderIsReceiver); 90613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 9062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Includes receiver. 9063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argc + 1); 9064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch is_function = true; 9065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 9066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kCallApiGetter: 9067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Receiver and prototype chain cannot have changed. 9068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(0, argc); 9069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NULL(receiver); 9070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Receiver is on expression stack. 9071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver = Pop(); 9072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(receiver); 9073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 9074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kCallApiSetter: 9075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 9076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_store = true; 9077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Receiver and prototype chain cannot have changed. 9078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(1, argc); 9079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NULL(receiver); 9080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Receiver and value are on expression stack. 9081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 9082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver = Pop(); 9083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HPushArguments>(receiver, value); 9084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 9085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 90863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 90873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 9088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* holder = NULL; 9089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (holder_lookup) { 9090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CallOptimization::kHolderFound: 9091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch holder = Add<HConstant>(api_holder); 9092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 9093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CallOptimization::kHolderIsReceiver: 9094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch holder = receiver; 9095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 9096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CallOptimization::kHolderNotFound: 9097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 9098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 90998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 9100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 9101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> call_data_obj(api_call_info->data(), isolate()); 910213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch bool call_data_undefined = call_data_obj->IsUndefined(isolate()); 9103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* call_data = Add<HConstant>(call_data_obj); 9104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ApiFunction fun(v8::ToCData<Address>(api_call_info->callback())); 9105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference ref = ExternalReference(&fun, 9106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::DIRECT_API_CALL, 9107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()); 9108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* api_function_address = Add<HConstant>(ExternalReference(ref)); 9109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9110c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* op_vals[] = {Add<HConstant>(function), call_data, holder, 9111f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch api_function_address}; 9112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 9113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* call = nullptr; 91143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CHECK(argc <= CallApiCallbackStub::kArgMax); 9115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!is_function) { 91163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CallApiCallbackStub stub(isolate(), is_store, call_data_undefined, 9117109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch !optimization.is_constant_call()); 9118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> code = stub.GetCode(); 9119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant* code_value = Add<HConstant>(code); 9120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch call = New<HCallWithDescriptor>( 91213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch code_value, argc + 1, stub.GetCallInterfaceDescriptor(), 9122f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Vector<HValue*>(op_vals, arraysize(op_vals)), syntactic_tail_call_mode); 9123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 9124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallApiCallbackStub stub(isolate(), argc, call_data_undefined, false); 9125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> code = stub.GetCode(); 9126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant* code_value = Add<HConstant>(code); 91273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch call = New<HCallWithDescriptor>( 91283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch code_value, argc + 1, stub.GetCallInterfaceDescriptor(), 9129f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Vector<HValue*>(op_vals, arraysize(op_vals)), syntactic_tail_call_mode); 9130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Drop(1); // Drop function. 9131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 9132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(call, ast_id); 9134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 91358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch} 91368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 91378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 9138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid HOptimizedGraphBuilder::HandleIndirectCall(Call* expr, HValue* function, 9139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int arguments_count) { 9140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSFunction> known_function; 9141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int args_count_no_receiver = arguments_count - 1; 9142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (function->IsConstant() && 9143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HConstant::cast(function)->handle(isolate())->IsJSFunction()) { 9144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier known_function = 9145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSFunction>::cast(HConstant::cast(function)->handle(isolate())); 914613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (TryInlineBuiltinMethodCall(known_function, Handle<Map>(), expr->id(), 9147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier args_count_no_receiver)) { 9148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_inlining) { 9149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Inlining builtin "); 9150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier known_function->ShortPrint(); 9151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("\n"); 9152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 9153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 9154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 9155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 9156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (TryInlineIndirectCall(known_function, expr, args_count_no_receiver)) { 9157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 9158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 9159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 9160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 91613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode syntactic_tail_call_mode = expr->tail_call_mode(); 91623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode tail_call_mode = 91633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch function_state()->ComputeTailCallMode(syntactic_tail_call_mode); 91643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 9165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PushArgumentsFromEnvironment(arguments_count); 9166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HInvokeFunction* call = 91673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch New<HInvokeFunction>(function, known_function, arguments_count, 91683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch syntactic_tail_call_mode, tail_call_mode); 9169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Drop(1); // Function 9170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ast_context()->ReturnInstruction(call, expr->id()); 9171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 9172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 9173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 9174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool HOptimizedGraphBuilder::TryIndirectCall(Call* expr) { 9175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->expression()->IsProperty()); 9176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!expr->IsMonomorphic()) { 9178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return false; 9179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 9180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> function_map = expr->GetReceiverTypes()->first(); 9181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function_map->instance_type() != JS_FUNCTION_TYPE || 9182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier !expr->target()->shared()->HasBuiltinFunctionId()) { 9183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 9184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 9185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (expr->target()->shared()->builtin_function_id()) { 9187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kFunctionCall: { 9188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (expr->arguments()->length() == 0) return false; 9189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BuildFunctionCall(expr); 9190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return true; 9191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 9192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kFunctionApply: { 9193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // For .apply, only the pattern f.apply(receiver, arguments) 9194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // is supported. 9195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!CanBeFunctionApplyArguments(expr)) return false; 91961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 9197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BuildFunctionApply(expr); 9198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return true; 9199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 9200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: { return false; } 9201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 9202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 9203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 9204b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 9206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// f.apply(...) 9207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid HOptimizedGraphBuilder::BuildFunctionApply(Call* expr) { 9208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ZoneList<Expression*>* args = expr->arguments(); 9209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(args->at(0))); 9210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver = Pop(); // receiver 9211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = Pop(); // f 9212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // apply 9213b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9214f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Make sure the arguments object is live. 9215f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch VariableProxy* arg_two = args->at(1)->AsVariableProxy(); 9216f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch LookupAndMakeLive(arg_two->var()); 9217f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 9218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Map> function_map = expr->GetReceiverTypes()->first(); 9219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* checked_function = AddCheckMap(function, function_map); 9220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function_state()->outer() == NULL) { 92223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode syntactic_tail_call_mode = expr->tail_call_mode(); 92233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode tail_call_mode = 92243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch function_state()->ComputeTailCallMode(syntactic_tail_call_mode); 92253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 9226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* elements = Add<HArgumentsElements>(false); 9227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* length = Add<HArgumentsLength>(elements); 9228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* wrapped_receiver = BuildWrapReceiver(receiver, checked_function); 92293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HInstruction* result = New<HApplyArguments>( 92303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch function, wrapped_receiver, length, elements, tail_call_mode); 9231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnInstruction(result, expr->id()); 9232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 9233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We are inside inlined function and we know exactly what is inside 9234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // arguments object. But we need to be able to materialize at deopt. 9235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(environment()->arguments_environment()->parameter_count(), 9236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state()->entry()->arguments_object()->arguments_count()); 9237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HArgumentsObject* args = function_state()->entry()->arguments_object(); 9238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ZoneList<HValue*>* arguments_values = args->arguments_values(); 9239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int arguments_count = arguments_values->length(); 9240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(function); 9241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(BuildWrapReceiver(receiver, checked_function)); 9242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 1; i < arguments_count; i++) { 9243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(arguments_values->at(i)); 9244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleIndirectCall(expr, function, arguments_count); 9246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 9247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 9248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// f.call(...) 9251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid HOptimizedGraphBuilder::BuildFunctionCall(Call* expr) { 9252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* function = Top(); // f 9253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Map> function_map = expr->GetReceiverTypes()->first(); 9254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* checked_function = AddCheckMap(function, function_map); 9255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 9256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // f and call are on the stack in the unoptimized code 9257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // during evaluation of the arguments. 9258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitExpressions(expr->arguments())); 9259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 9260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int args_length = expr->arguments()->length(); 9261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int receiver_index = args_length - 1; 9262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Patch the receiver. 9263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* receiver = BuildWrapReceiver( 9264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier environment()->ExpressionStackAt(receiver_index), checked_function); 9265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier environment()->SetExpressionStackAt(receiver_index, receiver); 9266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 9267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Call must not be on the stack from now on. 9268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int call_index = args_length + 1; 9269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier environment()->RemoveExpressionStackAt(call_index); 9270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 9271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleIndirectCall(expr, function, args_length); 9272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 9273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 92743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 9275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function, 9276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> target) { 9277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedFunctionInfo* shared = target->shared(); 9278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_sloppy(shared->language_mode()) && !shared->native()) { 9279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Cannot embed a direct reference to the global proxy 9280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // as is it dropped on deserialization. 9281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!isolate()->serializer_enabled()); 9282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> global_proxy(target->context()->global_proxy()); 9283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Add<HConstant>(global_proxy); 9284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 9285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return graph()->GetConstantUndefined(); 9286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 9287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HOptimizedGraphBuilder::BuildArrayIndexOf(HValue* receiver, 9290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* search_element, 9291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 9292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArrayIndexOfMode mode) { 9293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsFastElementsKind(kind)); 929444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 9296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements = AddLoadElements(receiver); 9298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* length = AddLoadArrayLength(receiver, kind); 9299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* initial; 9301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* terminating; 9302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::Value token; 9303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder::Direction direction; 9304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode == kFirstIndexOf) { 9305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch initial = graph()->GetConstant0(); 9306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch terminating = length; 9307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch token = Token::LT; 9308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch direction = LoopBuilder::kPostIncrement; 9309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 9310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(kLastIndexOf, mode); 9311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch initial = length; 9312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch terminating = graph()->GetConstant0(); 9313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch token = Token::GT; 9314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch direction = LoopBuilder::kPreDecrement; 9315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(graph()->GetConstantMinus1()); 9318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFastDoubleElementsKind(kind) || IsFastSmiElementsKind(kind)) { 9319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure that we can actually compare numbers correctly below, see 9320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // https://code.google.com/p/chromium/issues/detail?id=407946 for details. 9321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch search_element = AddUncasted<HForceRepresentation>( 9322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch search_element, IsFastSmiElementsKind(kind) ? Representation::Smi() 9323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Representation::Double()); 9324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder loop(this, context(), direction); 9326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 9327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = loop.BeginBody(initial, terminating, token); 9328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* element = AddUncasted<HLoadKeyed>( 9329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements, index, nullptr, nullptr, kind, ALLOW_RETURN_HOLE); 9330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_issame(this); 9331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.If<HCompareNumericAndBranch>(element, search_element, 9332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::EQ_STRICT); 9333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.Then(); 9334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 9335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 9336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(index); 9337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.Break(); 9338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.End(); 93409fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block } 9341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.EndBody(); 9342257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 9343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_isstring(this); 9344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isstring.If<HIsStringAndBranch>(search_element); 9345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isstring.Then(); 9346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 9347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder loop(this, context(), direction); 9348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 9349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = loop.BeginBody(initial, terminating, token); 9350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* element = AddUncasted<HLoadKeyed>( 9351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements, index, nullptr, nullptr, kind, ALLOW_RETURN_HOLE); 9352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_issame(this); 9353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.If<HIsStringAndBranch>(element); 9354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.AndIf<HStringCompareAndBranch>( 9355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch element, search_element, Token::EQ_STRICT); 9356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.Then(); 9357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 9358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 9359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(index); 9360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.Break(); 9361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.End(); 9363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.EndBody(); 9365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isstring.Else(); 9367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 9368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_isnumber(this); 9369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isnumber.If<HIsSmiAndBranch>(search_element); 9370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isnumber.OrIf<HCompareMap>( 9371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch search_element, isolate()->factory()->heap_number_map()); 9372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isnumber.Then(); 9373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 9374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* search_number = 9375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HForceRepresentation>(search_element, 9376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation::Double()); 9377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder loop(this, context(), direction); 9378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 9379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = loop.BeginBody(initial, terminating, token); 9380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* element = AddUncasted<HLoadKeyed>( 9381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements, index, nullptr, nullptr, kind, ALLOW_RETURN_HOLE); 9382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_element_isnumber(this); 9384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_element_isnumber.If<HIsSmiAndBranch>(element); 9385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_element_isnumber.OrIf<HCompareMap>( 9386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch element, isolate()->factory()->heap_number_map()); 9387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_element_isnumber.Then(); 9388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 9389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* number = 9390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HForceRepresentation>(element, 9391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation::Double()); 9392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_issame(this); 9393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.If<HCompareNumericAndBranch>( 9394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number, search_number, Token::EQ_STRICT); 9395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.Then(); 9396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 9397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 9398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(index); 9399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.Break(); 9400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.End(); 9402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_element_isnumber.End(); 9404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.EndBody(); 9406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isnumber.Else(); 9408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 9409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder loop(this, context(), direction); 9410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 9411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index = loop.BeginBody(initial, terminating, token); 9412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* element = AddUncasted<HLoadKeyed>( 9413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements, index, nullptr, nullptr, kind, ALLOW_RETURN_HOLE); 9414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_issame(this); 9415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.If<HCompareObjectEqAndBranch>( 9416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch element, search_element); 9417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.Then(); 9418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 9419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 9420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(index); 9421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.Break(); 9422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_issame.End(); 9424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop.EndBody(); 9426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isnumber.End(); 9428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_isstring.End(); 943044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 9431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Pop(); 9433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 9434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9435f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <class T> 9436f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool HOptimizedGraphBuilder::TryHandleArrayCall(T* expr, HValue* function) { 9437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!array_function().is_identical_to(expr->target())) { 9438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 9439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 9440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> site = expr->allocation_site(); 9442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (site.is_null()) return false; 9443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9444f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Add<HCheckValue>(function, array_function()); 9445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9446f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int arguments_count = expr->arguments()->length(); 9447f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (TryInlineArrayCall(expr, arguments_count, site)) return true; 9448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9449f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HInstruction* call = PreProcessCall(New<HCallNewArray>( 9450f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch function, arguments_count + 1, site->GetElementsKind(), site)); 9451f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (expr->IsCall()) Drop(1); 9452f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ReturnInstruction(call, expr->id()); 9453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 9454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 9455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 9456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 94573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool HOptimizedGraphBuilder::CanBeFunctionApplyArguments(Call* expr) { 9459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ZoneList<Expression*>* args = expr->arguments(); 9460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (args->length() != 2) return false; 9461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VariableProxy* arg_two = args->at(1)->AsVariableProxy(); 9462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; 9463f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HValue* arg_two_value = environment()->Lookup(arg_two->var()); 9464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; 9465f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK_NOT_NULL(current_info()->scope()->arguments()); 9466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return true; 9467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 9468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 9469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 9470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitCall(Call* expr) { 9471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 9472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 9473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 9474f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!is_tracking_positions()) SetSourcePosition(expr->position()); 9475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* callee = expr->expression(); 9476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = expr->arguments()->length() + 1; // Plus receiver. 9477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* call = NULL; 94783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 94793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode syntactic_tail_call_mode = expr->tail_call_mode(); 94803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode tail_call_mode = 94813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch function_state()->ComputeTailCallMode(syntactic_tail_call_mode); 94823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 9483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Property* prop = callee->AsProperty(); 9484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (prop != NULL) { 9485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(prop->obj())); 9486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver = Top(); 9487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmallMapList* maps; 9489109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ComputeReceiverTypes(expr, receiver, &maps, this); 9490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (prop->key()->IsPropertyName() && maps->length() > 0) { 9492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 9493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAccessInfo info(this, LOAD, maps->first(), name); 9494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!info.CanAccessAsMonomorphic(maps)) { 9495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandlePolymorphicCallNamed(expr, receiver, maps, name); 9496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 9497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 94983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = NULL; 9500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!prop->key()->IsPropertyName()) { 9501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(prop->key())); 9502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key = Pop(); 95033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9504b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(PushLoad(prop, receiver, key)); 9506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = Pop(); 9507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function->IsConstant() && 9509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(function)->handle(isolate())->IsJSFunction()) { 9510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Push the function under the receiver. 9511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier environment()->SetExpressionStackAt(0, function); 9512958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Push(receiver); 9513958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 9514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> known_function = Handle<JSFunction>::cast( 9515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(function)->handle(isolate())); 9516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->set_target(known_function); 95173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9518958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (TryIndirectCall(expr)) return; 9519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 95203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> map = maps->length() == 1 ? maps->first() : Handle<Map>(); 952213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (TryInlineBuiltinMethodCall(known_function, map, expr->id(), 9523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier expr->arguments()->length())) { 9524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_inlining) { 9525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Inlining builtin "); 9526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch known_function->ShortPrint(); 9527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("\n"); 9528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 9530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (TryInlineApiMethodCall(expr, receiver, maps)) return; 9532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Wrap the receiver if necessary. 9534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (NeedsWrapping(maps->first(), known_function)) { 9535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Since HWrapReceiver currently cannot actually wrap numbers and 95363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // strings, use the regular call builtin for method calls to wrap 9537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the receiver. 9538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(verwaest): Support creation of value wrappers directly in 9539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // HWrapReceiver. 95403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch call = NewCallFunction( 95413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch function, argument_count, syntactic_tail_call_mode, 95423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode); 9543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (TryInlineCall(expr)) { 9544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 9545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 95463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch call = 95473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch NewCallConstantFunction(known_function, argument_count, 95483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch syntactic_tail_call_mode, tail_call_mode); 9549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 9552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; 9553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { 9554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // We have to use EAGER deoptimization here because Deoptimizer::SOFT 9555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // gets ignored by the always-opt flag, which leads to incorrect code. 9556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HDeoptimize>( 9557f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason::kInsufficientTypeFeedbackForCallWithArguments, 9558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Deoptimizer::EAGER); 9559958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier arguments_flag = ARGUMENTS_FAKED; 9560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 9561958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 9562958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Push the function under the receiver. 9563958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier environment()->SetExpressionStackAt(0, function); 9564958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Push(receiver); 9565958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 9566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); 95673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch call = NewCallFunction(function, argument_count, syntactic_tail_call_mode, 95683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ConvertReceiverMode::kNotNullOrUndefined, 95693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch tail_call_mode); 9570e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 9571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argument_count); 9572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 9574f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (expr->is_possibly_eval()) { 9575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kPossibleDirectCallToEval); 95763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 9577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The function is on the stack in the unoptimized code during 9579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // evaluation of the arguments. 9580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->expression())); 9581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = Top(); 9582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (function->IsConstant() && 9583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant::cast(function)->handle(isolate())->IsJSFunction()) { 9584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> constant = HConstant::cast(function)->handle(isolate()); 9585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction> target = Handle<JSFunction>::cast(constant); 9586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch expr->SetKnownGlobalTarget(target); 9587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 9588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Placeholder for the receiver. 9590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(graph()->GetConstantUndefined()); 9591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 9592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (expr->IsMonomorphic() && 9594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !IsClassConstructor(expr->target()->shared()->kind())) { 9595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckValue>(function, expr->target()); 9596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Patch the global object on the stack by the expected receiver. 9598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* receiver = ImplicitReceiverFor(function, expr->target()); 9599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int receiver_index = argument_count - 1; 9600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(receiver_index, receiver); 9601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineBuiltinFunctionCall(expr)) { 9603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_inlining) { 9604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("Inlining builtin "); 9605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->target()->ShortPrint(); 9606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("\n"); 9607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 9609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineApiFunctionCall(expr, receiver)) return; 9611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (TryHandleArrayCall(expr, function)) return; 9612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineCall(expr)) return; 9613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushArgumentsFromEnvironment(argument_count); 96153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch call = NewCallConstantFunction(expr->target(), argument_count, 96163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch syntactic_tail_call_mode, tail_call_mode); 9617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 9618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(argument_count); 9619c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (expr->is_uninitialized()) { 9620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We've never seen this call before, so let's have Crankshaft learn 9621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // through the type vector. 96223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch call = NewCallFunctionViaIC(function, argument_count, 96233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch syntactic_tail_call_mode, 96243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ConvertReceiverMode::kNullOrUndefined, 96253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch tail_call_mode, expr->CallFeedbackICSlot()); 96263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 96273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch call = NewCallFunction( 96283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch function, argument_count, syntactic_tail_call_mode, 96293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ConvertReceiverMode::kNullOrUndefined, tail_call_mode); 9630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 9631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 96323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); // Drop the function. 9635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(call, expr->id()); 9636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 9637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9638f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool HOptimizedGraphBuilder::TryInlineArrayCall(Expression* expression, 9639f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int argument_count, 9640f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<AllocationSite> site) { 9641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSFunction> caller = current_info()->closure(); 9642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSFunction> target = array_function(); 9643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!site->CanInlineCall()) { 9645f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TraceInline(target, caller, "AllocationSite requested no inlining."); 9646f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 9647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 9648f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 9649f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (argument_count > 1) { 9650f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TraceInline(target, caller, "Too many arguments to inline."); 9651f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 9652f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 9653f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 9654f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int array_length = 0; 9655f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Do not inline if the constant length argument is not a smi or outside the 9656f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // valid range for unrolled loop initialization. 9657f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (argument_count == 1) { 9658f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HValue* argument = Top(); 9659f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!argument->IsConstant()) { 9660f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TraceInline(target, caller, 9661f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "Dont inline [new] Array(n) where n isn't constant."); 9662f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 9663f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 9664f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 9665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HConstant* constant_argument = HConstant::cast(argument); 9666f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!constant_argument->HasSmiValue()) { 9667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TraceInline(target, caller, 9668f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "Constant length outside of valid inlining range."); 9669f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 9670f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 9671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch array_length = constant_argument->Integer32Value(); 9672f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (array_length < 0 || array_length > kElementLoopUnrollThreshold) { 9673f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TraceInline(target, caller, 9674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch "Constant length outside of valid inlining range."); 9675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 9676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 9677f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 9678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 9679f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TraceInline(target, caller, NULL); 9680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9681f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NoObservableSideEffectsScope no_effects(this); 9682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Register on the site for deoptimization if the transition feedback changes. 9684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch top_info()->dependencies()->AssumeTransitionStable(site); 9685f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 9686f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Build the array. 9687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind = site->GetElementsKind(); 9688f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HValue* capacity; 9689f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HValue* length; 9690f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (array_length == 0) { 9691f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch STATIC_ASSERT(0 < JSArray::kPreallocatedArrayElements); 9692f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const int initial_capacity = JSArray::kPreallocatedArrayElements; 9693f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch capacity = Add<HConstant>(initial_capacity); 9694f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length = graph()->GetConstant0(); 9695f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 9696f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length = Top(); 9697f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch capacity = length; 9698f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch kind = GetHoleyElementsKind(kind); 9699b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 9700b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9701f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // These HForceRepresentations are because we store these as fields in the 9702f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // objects we construct, and an int32-to-smi HChange could deopt. Accept 9703f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // the deopt possibility now, before allocation occurs. 9704f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length = AddUncasted<HForceRepresentation>(length, Representation::Smi()); 9705f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi()); 9706f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 9707f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Generate size calculation code here in order to make it dominate 9708f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // the JSArray allocation. 9709f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HValue* elements_size = BuildCalculateElementsSize(kind, capacity); 9710f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 9711f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Bail out for large objects. 9712f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HValue* max_size = Add<HConstant>(kMaxRegularHeapObjectSize); 9713f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Add<HBoundsCheck>(elements_size, max_size); 9714f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 9715f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Allocate (dealing with failure appropriately). 9716f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AllocationSiteMode mode = DONT_TRACK_ALLOCATION_SITE; 9717f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HAllocate* new_object = AllocateJSArrayObject(mode); 9718f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 9719f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Fill in the fields: map, properties, length. 9720f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Map> map_constant(isolate()->get_initial_js_array_map(kind)); 9721f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HValue* map = Add<HConstant>(map_constant); 9722f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 9723f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BuildJSArrayHeader(new_object, map, 9724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch nullptr, // set elements to empty fixed array 9725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch mode, kind, nullptr, length); 9726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 9727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Allocate and initialize the elements. 9728f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HAllocate* elements = BuildAllocateElements(kind, elements_size); 9729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BuildInitializeElementsHeader(elements, kind, capacity); 9730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BuildFillElementsWithHole(elements, kind, graph()->GetConstant0(), capacity); 9731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 9732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Set the elements. 9733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Add<HStoreNamedField>(new_object, HObjectAccess::ForElementsPointer(), 9734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch elements); 9735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int args_to_drop = argument_count + (expression->IsCall() ? 2 : 1); 9737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(args_to_drop); 9738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->ReturnValue(new_object); 9739f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 9740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 9741b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Checks whether allocation using the given constructor can be inlined. 9744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool IsAllocationInlineable(Handle<JSFunction> constructor) { 9745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return constructor->has_initial_map() && 974662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch !IsDerivedConstructor(constructor->shared()->kind()) && 9747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && 9748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constructor->initial_map()->instance_size() < 9749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HAllocate::kMaxInlineSize; 9750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 9751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { 9753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 9754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 9755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 9756f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!is_tracking_positions()) SetSourcePosition(expr->position()); 9757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = expr->arguments()->length() + 1; // Plus constructor. 9758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate()->factory(); 9759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The constructor function is on the stack in the unoptimized code 9761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // during evaluation of the arguments. 9762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->expression())); 9763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* function = Top(); 9764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 9765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (function->IsConstant() && 9767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant::cast(function)->handle(isolate())->IsJSFunction()) { 9768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> constant = HConstant::cast(function)->handle(isolate()); 9769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch expr->SetKnownGlobalTarget(Handle<JSFunction>::cast(constant)); 9770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 9771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 9772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_inline_construct && 9773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->IsMonomorphic() && 9774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsAllocationInlineable(expr->target())) { 9775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> constructor = expr->target(); 9776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK( 9777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constructor->shared()->construct_stub() == 9778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()->builtins()->builtin(Builtins::kJSConstructStubGeneric) || 9779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constructor->shared()->construct_stub() == 9780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()->builtins()->builtin(Builtins::kJSConstructStubApi)); 9781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* check = Add<HCheckValue>(function, constructor); 9782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Force completion of inobject slack tracking before generating 9784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // allocation code to finalize instance size. 9785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constructor->CompleteInobjectSlackTrackingIfActive(); 9786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calculate instance size from initial map of constructor. 9788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(constructor->has_initial_map()); 9789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> initial_map(constructor->initial_map()); 9790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int instance_size = initial_map->instance_size(); 9791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate an instance of the implicit receiver object. 9793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* size_in_bytes = Add<HConstant>(instance_size); 9794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocationMode allocation_mode; 9795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocate* receiver = BuildAllocate( 9796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode); 9797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver->set_known_initial_map(initial_map); 9798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize map and fields of the newly allocated object. 9800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { NoObservableSideEffectsScope no_effects(this); 9801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(initial_map->instance_type() == JS_OBJECT_TYPE); 9802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(receiver, 9803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMapAndOffset(initial_map, JSObject::kMapOffset), 9804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(initial_map)); 9805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array()); 9806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(receiver, 9807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMapAndOffset(initial_map, 9808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::kPropertiesOffset), 9809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch empty_fixed_array); 9810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(receiver, 9811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMapAndOffset(initial_map, 9812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::kElementsOffset), 9813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch empty_fixed_array); 9814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildInitializeInobjectProperties(receiver, initial_map); 9815257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 9816b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Replace the constructor function with a newly allocated receiver using 9818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the index of the receiver from the top of the expression stack. 9819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int receiver_index = argument_count - 1; 9820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(environment()->ExpressionStackAt(receiver_index) == function); 9821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(receiver_index, receiver); 9822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryInlineConstruct(expr, receiver)) { 9824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Inlining worked, add a dependency on the initial map to make sure that 9825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this code is deoptimized whenever the initial map of the constructor 9826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // changes. 9827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch top_info()->dependencies()->AssumeInitialMapCantChange(initial_map); 9828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 9829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(mstarzinger): For now we remove the previous HAllocate and all 9832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // corresponding instructions and instead add HPushArguments for the 9833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // arguments in case inlining failed. What we actually should do is for 9834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inlining to try to build a subgraph without mutating the parent graph. 9835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = current_block()->last(); 9836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch do { 9837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* prev_instr = instr->previous(); 9838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->DeleteAndReplaceWith(NULL); 9839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr = prev_instr; 9840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } while (instr != check); 9841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(receiver_index, function); 9842257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 9843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The constructor function is both an operand to the instruction and an 9844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // argument to the construct call. 9845f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (TryHandleArrayCall(expr, function)) return; 9846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 9847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 9848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* arity = Add<HConstant>(argument_count - 1); 9849c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* op_vals[] = {function, function, arity}; 9850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Callable callable = CodeFactory::Construct(isolate()); 9851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant* stub = Add<HConstant>(callable.code()); 9852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushArgumentsFromEnvironment(argument_count); 9853bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HInstruction* construct = New<HCallWithDescriptor>( 9854bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch stub, argument_count, callable.descriptor(), ArrayVector(op_vals)); 9855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ast_context()->ReturnInstruction(construct, expr->id()); 9856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 9857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 9858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::BuildInitializeInobjectProperties( 9860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* receiver, Handle<Map> initial_map) { 9861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (initial_map->GetInObjectProperties() != 0) { 9862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant* undefined = graph()->GetConstantUndefined(); 9863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < initial_map->GetInObjectProperties(); i++) { 9864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int property_offset = initial_map->GetInObjectPropertyOffset(i); 9865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(receiver, HObjectAccess::ForMapAndOffset( 9866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch initial_map, property_offset), 9867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch undefined); 9868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 9869b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 98705d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch} 98715d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 98725d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 9873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHValue* HGraphBuilder::BuildAllocateEmptyArrayBuffer(HValue* byte_length) { 9874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We HForceRepresentation here to avoid allocations during an *-to-tagged 9875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // HChange that could cause GC while the array buffer object is not fully 9876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // initialized. 9877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess byte_length_access(HObjectAccess::ForJSArrayBufferByteLength()); 9878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch byte_length = AddUncasted<HForceRepresentation>( 9879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch byte_length, byte_length_access.representation()); 9880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HAllocate* result = 9881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildAllocate(Add<HConstant>(JSArrayBuffer::kSizeWithInternalFields), 9882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HType::JSObject(), JS_ARRAY_BUFFER_TYPE, HAllocationMode()); 98833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* native_context = BuildGetNativeContext(); 9885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>( 9886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch result, HObjectAccess::ForMap(), 9887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HLoadNamedField>( 9888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch native_context, nullptr, 9889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess::ForContextSlot(Context::ARRAY_BUFFER_MAP_INDEX))); 98903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant* empty_fixed_array = 9892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HConstant>(isolate()->factory()->empty_fixed_array()); 9893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>( 9894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch result, HObjectAccess::ForJSArrayOffset(JSArray::kPropertiesOffset), 9895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch empty_fixed_array); 9896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>( 9897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset), 9898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch empty_fixed_array); 9899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>( 9900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch result, HObjectAccess::ForJSArrayBufferBackingStore().WithRepresentation( 9901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Representation::Smi()), 9902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->GetConstant0()); 9903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(result, byte_length_access, byte_length); 9904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(result, HObjectAccess::ForJSArrayBufferBitFieldSlot(), 9905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->GetConstant0()); 9906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>( 9907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch result, HObjectAccess::ForJSArrayBufferBitField(), 9908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HConstant>((1 << JSArrayBuffer::IsExternal::kShift) | 9909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (1 << JSArrayBuffer::IsNeuterable::kShift))); 9910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 9911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int field = 0; field < v8::ArrayBuffer::kInternalFieldCount; ++field) { 9912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>( 9913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch result, 9914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess::ForObservableJSObjectOffset( 9915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSArrayBuffer::kSize + field * kPointerSize, Representation::Smi()), 9916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->GetConstant0()); 9917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 9918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 9919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result; 9920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 99213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 99223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <class ViewClass> 9924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HGraphBuilder::BuildArrayBufferViewInitialization( 9925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* obj, 9926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* buffer, 9927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* byte_offset, 9928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* byte_length) { 9929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int offset = ViewClass::kSize; 9931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset < ViewClass::kSizeWithInternalFields; 9932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset += kPointerSize) { 9933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(obj, 9934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForObservableJSObjectOffset(offset), 9935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->GetConstant0()); 9936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 9939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj, 9940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSArrayBufferViewByteOffset(), 9941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_offset); 9942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 9943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj, 9944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSArrayBufferViewByteLength(), 9945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_length); 9946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(obj, HObjectAccess::ForJSArrayBufferViewBuffer(), 9947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer); 99483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 99493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 99503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HOptimizedGraphBuilder::BuildAllocateExternalElements( 9952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalArrayType array_type, 9953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_zero_byte_offset, 9954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* buffer, HValue* byte_offset, HValue* length) { 9955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> external_array_map( 9956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()->heap()->MapForFixedTypedArray(array_type)); 9957b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The HForceRepresentation is to prevent possible deopt on int-smi 9959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // conversion after allocation but before the new object fields are set. 9960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length = AddUncasted<HForceRepresentation>(length, Representation::Smi()); 9961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* elements = Add<HAllocate>( 9962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HConstant>(FixedTypedArrayBase::kHeaderSize), HType::HeapObject(), 9963bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NOT_TENURED, external_array_map->instance_type(), 9964bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch graph()->GetConstant0()); 9965b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddStoreMapConstant(elements, external_array_map); 9967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(elements, 9968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForFixedArrayLength(), length); 9969257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* backing_store = Add<HLoadNamedField>( 9971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier buffer, nullptr, HObjectAccess::ForJSArrayBufferBackingStore()); 99723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* typed_array_start; 9974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_zero_byte_offset) { 9975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typed_array_start = backing_store; 99763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 9977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* external_pointer = 9978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddUncasted<HAdd>(backing_store, byte_offset); 9979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Arguments are checked prior to call to TypedArrayInitialize, 9980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // including byte_offset. 9981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch external_pointer->ClearFlag(HValue::kCanOverflow); 9982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typed_array_start = external_pointer; 9983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 99843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(elements, 9986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess::ForFixedTypedArrayBaseBasePointer(), 9987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->GetConstant0()); 9988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(elements, 9989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess::ForFixedTypedArrayBaseExternalPointer(), 9990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch typed_array_start); 99913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return elements; 9993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 99943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 99953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HOptimizedGraphBuilder::BuildAllocateFixedTypedArray( 9997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalArrayType array_type, size_t element_size, 9998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKind fixed_elements_kind, HValue* byte_length, HValue* length, 9999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool initialize) { 10000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT( 10001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (FixedTypedArrayBase::kHeaderSize & kObjectAlignmentMask) == 0); 10002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* total_size; 10003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // if fixed array's elements are not aligned to object's alignment, 10005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // we need to align the whole array to object alignment. 10006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (element_size % kObjectAlignment != 0) { 10007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total_size = BuildObjectSizeAlignment( 10008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_length, FixedTypedArrayBase::kHeaderSize); 10009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total_size = AddUncasted<HAdd>(byte_length, 10011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(FixedTypedArrayBase::kHeaderSize)); 10012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total_size->ClearFlag(HValue::kCanOverflow); 100133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10014b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The HForceRepresentation is to prevent possible deopt on int-smi 10016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // conversion after allocation but before the new object fields are set. 10017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length = AddUncasted<HForceRepresentation>(length, Representation::Smi()); 10018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> fixed_typed_array_map( 10019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->heap()->MapForFixedTypedArray(array_type)); 10020bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HAllocate* elements = Add<HAllocate>( 10021bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch total_size, HType::HeapObject(), NOT_TENURED, 10022bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch fixed_typed_array_map->instance_type(), graph()->GetConstant0()); 10023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_HOST_ARCH_64_BIT 10025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (array_type == kExternalFloat64Array) { 10026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements->MakeDoubleAligned(); 10027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 10028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 10029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddStoreMapConstant(elements, fixed_typed_array_map); 10031b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(elements, 10033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForFixedArrayLength(), 10034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length); 10035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>( 10036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements, HObjectAccess::ForFixedTypedArrayBaseBasePointer(), elements); 10037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>( 10039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements, HObjectAccess::ForFixedTypedArrayBaseExternalPointer(), 10040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HConstant>(ExternalReference::fixed_typed_array_base_data_offset())); 10041b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* filler = Add<HConstant>(static_cast<int32_t>(0)); 10043b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (initialize) { 10045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement); 10046b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* backing_store = AddUncasted<HAdd>( 10048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HConstant>(ExternalReference::fixed_typed_array_base_data_offset()), 10049109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch elements, AddOfExternalAndTagged); 10050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = builder.BeginBody( 10052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>(0)), 10053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length, Token::LT); 10054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreKeyed>(backing_store, key, filler, elements, fixed_elements_kind); 10055b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder.EndBody(); 10057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return elements; 10059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10060b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10061b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateTypedArrayInitialize( 10063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* expr) { 10064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Expression*>* arguments = expr->arguments(); 10065b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kObjectArg = 0; 10067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kArrayIdArg = 1; 10068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kBufferArg = 2; 10069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kByteOffsetArg = 3; 10070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kByteLengthArg = 4; 10071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kInitializeArg = 5; 10072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kArgsLength = 6; 10073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(arguments->length() == kArgsLength); 10074b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10075b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(arguments->at(kObjectArg))); 10077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* obj = Pop(); 10078b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!arguments->at(kArrayIdArg)->IsLiteral()) { 10080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This should never happen in real use, but can happen when fuzzing. 10081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Just bail out. 10082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bailout(kNeedSmiLiteral); 10083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 10084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> value = 10086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<Literal*>(arguments->at(kArrayIdArg))->value(); 10087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!value->IsSmi()) { 10088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This should never happen in real use, but can happen when fuzzing. 10089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Just bail out. 10090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bailout(kNeedSmiLiteral); 10091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 10092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int array_id = Smi::cast(*value)->value(); 10094b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* buffer; 10096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!arguments->at(kBufferArg)->IsNullLiteral()) { 10097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(arguments->at(kBufferArg))); 10098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer = Pop(); 10099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer = NULL; 10101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 101021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 10103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* byte_offset; 10104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_zero_byte_offset; 10105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10106c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (arguments->at(kByteOffsetArg)->IsLiteral() && 10107c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Smi::kZero == 10108c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch *static_cast<Literal*>(arguments->at(kByteOffsetArg))->value()) { 10109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_offset = Add<HConstant>(static_cast<int32_t>(0)); 10110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_zero_byte_offset = true; 10111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(arguments->at(kByteOffsetArg))); 10113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_offset = Pop(); 10114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_zero_byte_offset = false; 10115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(buffer != NULL); 10116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(arguments->at(kByteLengthArg))); 10119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* byte_length = Pop(); 10120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(arguments->at(kInitializeArg)->IsLiteral()); 10122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool initialize = static_cast<Literal*>(arguments->at(kInitializeArg)) 10123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ->value() 10124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ->BooleanValue(); 10125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope scope(this); 10127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder byte_offset_smi(this); 101283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!is_zero_byte_offset) { 10130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_offset_smi.If<HIsSmiAndBranch>(byte_offset); 10131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_offset_smi.Then(); 10132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalArrayType array_type = 10135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kExternalInt8Array; // Bogus initialization. 10136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t element_size = 1; // Bogus initialization. 10137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind fixed_elements_kind = // Bogus initialization. 10138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch INT8_ELEMENTS; 10139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Runtime::ArrayIdToTypeAndSize(array_id, 10140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &array_type, 10141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &fixed_elements_kind, 10142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &element_size); 10143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { // byte_offset is Smi. 10146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* allocated_buffer = buffer; 10147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (buffer == NULL) { 10148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch allocated_buffer = BuildAllocateEmptyArrayBuffer(byte_length); 10149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 10150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildArrayBufferViewInitialization<JSTypedArray>(obj, allocated_buffer, 10151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch byte_offset, byte_length); 10152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 101533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* length = AddUncasted<HDiv>(byte_length, 10155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(static_cast<int32_t>(element_size))); 10156f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Callers (in typedarray.js) ensure that length <= %_MaxSmi(). 10157f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch length = AddUncasted<HForceRepresentation>(length, Representation::Smi()); 101583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(obj, 10160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSTypedArrayLength(), 10161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length); 101623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* elements; 10164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (buffer != NULL) { 10165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements = BuildAllocateExternalElements( 10166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array_type, is_zero_byte_offset, buffer, byte_offset, length); 10167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 10168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_zero_byte_offset); 10169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements = BuildAllocateFixedTypedArray(array_type, element_size, 10170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch fixed_elements_kind, byte_length, 10171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch length, initialize); 10172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 10174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj, HObjectAccess::ForElementsPointer(), elements); 10175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!is_zero_byte_offset) { 10178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_offset_smi.Else(); 10179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { // byte_offset is not Smi. 10180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(obj); 10181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(arguments->at(kArrayIdArg))); 10182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(buffer); 10183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(byte_offset); 10184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(byte_length); 10185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_ALIVE(VisitForValue(arguments->at(kInitializeArg))); 10186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushArgumentsFromEnvironment(kArgsLength); 10187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HCallRuntime>(expr->function(), kArgsLength); 10188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte_offset_smi.End(); 10191b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 10192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateMaxSmi(CallRuntime* expr) { 10195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->arguments()->length() == 0); 10196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue)); 10197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(max_smi, expr->id()); 101983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 101993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 102003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateTypedArrayMaxSizeInHeap( 10202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* expr) { 10203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->arguments()->length() == 0); 10204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* result = New<HConstant>(static_cast<int32_t>( 10205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FLAG_typed_array_max_size_in_heap)); 10206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(result, expr->id()); 10207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 102083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 102093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateArrayBufferGetByteLength( 10211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* expr) { 10212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->arguments()->length() == 1); 10213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 10214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* buffer = Pop(); 10215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = New<HLoadNamedField>( 10216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier buffer, nullptr, HObjectAccess::ForJSArrayBufferByteLength()); 10217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(result, expr->id()); 10218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 102193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 102203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteLength( 10222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* expr) { 10223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NoObservableSideEffectsScope scope(this); 10224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->arguments()->length() == 1); 10225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 10226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* view = Pop(); 10227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ast_context()->ReturnValue(BuildArrayBufferViewFieldAccessor( 10229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch view, nullptr, 10230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FieldIndex::ForInObjectOffset(JSArrayBufferView::kByteLengthOffset))); 10231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 10232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteOffset( 10235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* expr) { 10236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NoObservableSideEffectsScope scope(this); 10237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->arguments()->length() == 1); 10238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 10239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* view = Pop(); 10240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ast_context()->ReturnValue(BuildArrayBufferViewFieldAccessor( 10242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch view, nullptr, 10243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FieldIndex::ForInObjectOffset(JSArrayBufferView::kByteOffsetOffset))); 10244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateTypedArrayGetLength( 10248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* expr) { 10249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NoObservableSideEffectsScope scope(this); 10250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->arguments()->length() == 1); 10251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 10252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* view = Pop(); 10253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ast_context()->ReturnValue(BuildArrayBufferViewFieldAccessor( 10255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch view, nullptr, 10256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FieldIndex::ForInObjectOffset(JSTypedArray::kLengthOffset))); 10257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { 10261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 10262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 10263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 10264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (expr->is_jsruntime()) { 102653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Crankshaft always specializes to the native context, so we can just grab 102663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // the constant function from the current native context and embed that into 102673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // the code object. 102683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<JSFunction> known_function( 102693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch JSFunction::cast( 102703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch current_info()->native_context()->get(expr->context_index())), 102713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch isolate()); 102723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 102733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // The callee and the receiver both have to be pushed onto the operand stack 102743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // before arguments are being evaluated. 102753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HConstant* function = Add<HConstant>(known_function); 102763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HValue* receiver = ImplicitReceiverFor(function, known_function); 102773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Push(function); 102783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Push(receiver); 102793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 102803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int argument_count = expr->arguments()->length() + 1; // Count receiver. 102813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 102823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch PushArgumentsFromEnvironment(argument_count); 102833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HInstruction* call = NewCallConstantFunction(known_function, argument_count, 102843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode::kDisallow, 102853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode::kDisallow); 102863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Drop(1); // Function 102873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return ast_context()->ReturnInstruction(call, expr->id()); 10288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1029044f0eee88ff00398ff7f715fab053374d808c90dSteve Block const Runtime::Function* function = expr->function(); 10291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(function != NULL); 10292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (function->function_id) { 10293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CALL_INTRINSIC_GENERATOR(Name) \ 10294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Runtime::kInline##Name: \ 10295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Generate##Name(expr); 10296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FOR_EACH_HYDROGEN_INTRINSIC(CALL_INTRINSIC_GENERATOR) 10298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef CALL_INTRINSIC_GENERATOR 10299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: { 10300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int argument_count = expr->arguments()->length(); 10301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_ALIVE(VisitExpressions(expr->arguments())); 10302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushArgumentsFromEnvironment(argument_count); 10303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HCallRuntime* call = New<HCallRuntime>(function, argument_count); 10304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ast_context()->ReturnInstruction(call, expr->id()); 10305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 10306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 10308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { 10311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 10312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 10313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 10314257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch switch (expr->op()) { 10315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case Token::DELETE: return VisitDelete(expr); 10316257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case Token::VOID: return VisitVoid(expr); 10317257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case Token::TYPEOF: return VisitTypeof(expr); 10318257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case Token::NOT: return VisitNot(expr); 10319257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch default: UNREACHABLE(); 10320257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 10321257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 10322257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { 10325257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Property* prop = expr->expression()->AsProperty(); 10326589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch VariableProxy* proxy = expr->expression()->AsVariableProxy(); 10327589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (prop != NULL) { 1032869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_ALIVE(VisitForValue(prop->obj())); 1032969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_ALIVE(VisitForValue(prop->key())); 1033069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch HValue* key = Pop(); 1033169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch HValue* obj = Pop(); 10332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HPushArguments>(obj, key); 10333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* instr = New<HCallRuntime>( 10334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Runtime::FunctionForId(is_strict(function_language_mode()) 10335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? Runtime::kDeleteProperty_Strict 10336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Runtime::kDeleteProperty_Sloppy), 10337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2); 1033869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 10339589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } else if (proxy != NULL) { 10340589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Variable* var = proxy->var(); 10341f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (var->IsUnallocated()) { 10342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bailout(kDeleteWithGlobalVariable); 10343589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } else if (var->IsStackAllocated() || var->IsContextSlot()) { 10344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Result of deleting non-global variables is false. 'this' is not really 10345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // a variable, though we implement it as one. The subexpression does not 10346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // have side effects. 10347f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HValue* value = var->is_this() ? graph()->GetConstantTrue() 10348f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : graph()->GetConstantFalse(); 10349589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return ast_context()->ReturnValue(value); 10350589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } else { 10351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bailout(kDeleteWithNonGlobalVariable); 10352589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 10353257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 10354589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Result of deleting non-property, non-variable reference is true. 10355589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Evaluate the subexpression for side effects. 10356589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch CHECK_ALIVE(VisitForEffect(expr->expression())); 10357589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return ast_context()->ReturnValue(graph()->GetConstantTrue()); 10358257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 10359257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 10360e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1036144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 10362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitVoid(UnaryOperation* expr) { 10363257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForEffect(expr->expression())); 103643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 10365257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 10366257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10367257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) { 10369257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForTypeOf(expr->expression())); 10370257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HValue* value = Pop(); 10371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = New<HTypeof>(value); 103723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 10373257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 10374257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10375257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { 10377257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (ast_context()->IsTest()) { 10378257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch TestContext* context = TestContext::cast(ast_context()); 10379257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch VisitForControl(expr->expression(), 10380257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch context->if_false(), 10381257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch context->if_true()); 10382257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return; 10383257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 10384257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10385257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (ast_context()->IsEffect()) { 10386257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch VisitForEffect(expr->expression()); 10387257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return; 10388257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 10389257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(ast_context()->IsValue()); 10391257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* materialize_false = graph()->CreateBasicBlock(); 10392257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* materialize_true = graph()->CreateBasicBlock(); 10393257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_BAILOUT(VisitForControl(expr->expression(), 10394257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch materialize_false, 10395257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch materialize_true)); 10396257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10397257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (materialize_false->HasPredecessor()) { 103983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch materialize_false->SetJoinId(expr->MaterializeFalseId()); 10399257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch set_current_block(materialize_false); 10400257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Push(graph()->GetConstantFalse()); 1040144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { 10402257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch materialize_false = NULL; 10403257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 10404257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10405257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (materialize_true->HasPredecessor()) { 104063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch materialize_true->SetJoinId(expr->MaterializeTrueId()); 10407257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch set_current_block(materialize_true); 10408257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Push(graph()->GetConstantTrue()); 10409257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 10410257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch materialize_true = NULL; 10411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10412257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10413257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* join = 10414257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CreateJoin(materialize_false, materialize_true, expr->id()); 10415257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch set_current_block(join); 104163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (join != NULL) return ast_context()->ReturnValue(Pop()); 10417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 10418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10419f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic Representation RepresentationFor(AstType* type) { 10420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DisallowHeapAllocation no_allocation; 10421f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (type->Is(AstType::None())) return Representation::None(); 10422f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (type->Is(AstType::SignedSmall())) return Representation::Smi(); 10423f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (type->Is(AstType::Signed32())) return Representation::Integer32(); 10424f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (type->Is(AstType::Number())) return Representation::Double(); 10425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Representation::Tagged(); 10426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 10427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10428c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochHInstruction* HOptimizedGraphBuilder::BuildIncrement(CountOperation* expr) { 10429257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // The input to the count operation is on top of the expression stack. 10430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Representation rep = RepresentationFor(expr->type()); 10431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (rep.IsNone() || rep.IsTagged()) { 10432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rep = Representation::Smi(); 10433257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 10434257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10435c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // We need an explicit HValue representing ToNumber(input). The 10436c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // actual HChange instruction we need is (sometimes) added in a later 10437c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // phase, so it is not available now to be used as an input to HAdd and 10438c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // as the return value. 10439c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HInstruction* number_input = AddUncasted<HForceRepresentation>(Pop(), rep); 10440c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!rep.IsDouble()) { 10441c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch number_input->SetFlag(HInstruction::kFlexibleRepresentation); 10442c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch number_input->SetFlag(HInstruction::kCannotBeTagged); 10443257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 10444c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Push(number_input); 10445257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10446257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // The addition has no side effects, so we do not need 10447257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // to simulate the expression stack after this instruction. 10448257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Any later failures deopt to the load of the input or earlier. 10449257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HConstant* delta = (expr->op() == Token::INC) 10450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? graph()->GetConstant1() 10451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : graph()->GetConstantMinus1(); 10452109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HInstruction* instr = AddUncasted<HAdd>(Top(), delta); 10453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->IsAdd()) { 10454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAdd* add = HAdd::cast(instr); 10455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch add->set_observed_input_representation(1, rep); 10456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch add->set_observed_input_representation(2, Representation::Smi()); 10457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 104583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr->ClearAllSideEffects(); 10459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetFlag(HInstruction::kCannotBeTagged); 10460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return instr; 10461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 10462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::BuildStoreForEffect( 1046462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Expression* expr, Property* prop, FeedbackSlot slot, BailoutId ast_id, 10465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BailoutId return_id, HValue* object, HValue* key, HValue* value) { 10466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EffectContext for_effect(this); 10467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(object); 10468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (key != NULL) Push(key); 10469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(value); 10470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildStore(expr, prop, slot, ast_id, return_id); 10471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { 10475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 10476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 10477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 10478f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!is_tracking_positions()) SetSourcePosition(expr->position()); 104798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Expression* target = expr->expression(); 10480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch VariableProxy* proxy = target->AsVariableProxy(); 10481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Property* prop = target->AsProperty(); 10482589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (proxy == NULL && prop == NULL) { 10483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kInvalidLhsInCountOperation); 10484257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 10485257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10486257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Match the full code generator stack by simulating an extra stack 10487257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // element for postfix operations in a non-effect context. The return 10488257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // value is ToNumber(input). 10489257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool returns_original_input = 10490257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch expr->is_postfix() && !ast_context()->IsEffect(); 10491257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HValue* input = NULL; // ToNumber(original_input). 10492257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HValue* after = NULL; // The result after incrementing or decrementing. 10493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10494589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (proxy != NULL) { 10495589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Variable* var = proxy->var(); 10496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (var->mode() == CONST) { 10497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Bailout(kNonInitializerAssignmentToConst); 10498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 10499257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Argument of the count operation is a variable, not a property. 10500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(prop == NULL); 10501257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(target)); 10502257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10503c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch after = BuildIncrement(expr); 10504257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch input = returns_original_input ? Top() : Pop(); 10505b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Push(after); 10506b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10507589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch switch (var->location()) { 10508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::UNALLOCATED: 10509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleGlobalVariableAssignment(var, after, expr->CountSlot(), 10510589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch expr->AssignmentId()); 10511589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch break; 10512589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 10513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::PARAMETER: 10514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOCAL: 10515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BindIfLive(var, after); 10516589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch break; 10517589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 10518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::CONTEXT: { 10519589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch HValue* context = BuildContextChainWalk(var); 10520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) 105213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; 10522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), 10523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode, after); 105243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->HasObservableSideEffects()) { 10525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 105263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10527589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch break; 105283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 105293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 10530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOOKUP: 10531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kLookupVariableInCountOperation); 10532f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 10533f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case VariableLocation::MODULE: 10534f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 10535b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(returns_original_input ? 2 : 1); 10538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(expr->is_postfix() ? input : after); 10539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Argument of the count operation is a property. 10542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(prop != NULL); 10543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (returns_original_input) Push(graph()->GetConstantUndefined()); 10544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(prop->obj())); 10546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object = Top(); 10547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key = NULL; 10549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!prop->key()->IsPropertyName() || prop->IsStringAccess()) { 10550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(prop->key())); 10551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key = Top(); 10552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(PushLoad(prop, object, key)); 10555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10556c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch after = BuildIncrement(expr); 10557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (returns_original_input) { 10559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch input = Pop(); 10560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Drop object and key to push it again in the effect context below. 10561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(key == NULL ? 1 : 2); 10562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(0, input); 10563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_ALIVE(BuildStoreForEffect(expr, prop, expr->CountSlot(), expr->id(), 10564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch expr->AssignmentId(), object, key, after)); 10565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 10566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->SetExpressionStackAt(0, after); 10569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return BuildStore(expr, prop, expr->CountSlot(), expr->id(), 10570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch expr->AssignmentId()); 10571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( 10575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* string, 10576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* index) { 10577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (string->IsConstant() && index->IsConstant()) { 10578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* c_string = HConstant::cast(string); 10579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* c_index = HConstant::cast(index); 10580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (c_string->HasStringValue() && c_index->HasNumberValue()) { 10581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t i = c_index->NumberValueAsInteger32(); 10582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> s = c_string->StringValue(); 10583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i < 0 || i >= s->length()) { 10584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return New<HConstant>(std::numeric_limits<double>::quiet_NaN()); 10585b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HConstant>(s->Get(i)); 10587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch string = BuildCheckString(string); 10590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch index = Add<HBoundsCheck>(index, AddLoadStringLength(string)); 10591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HStringCharCodeAt>(string, index); 10592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Checks if the given shift amounts have following forms: 10596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (N1) and (N2) with N1 + N2 = 32; (sa) and (32 - sa). 10597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool ShiftAmountsAllowReplaceByRotate(HValue* sa, 10598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* const32_minus_sa) { 10599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (sa->IsConstant() && const32_minus_sa->IsConstant()) { 10600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const HConstant* c1 = HConstant::cast(sa); 10601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const HConstant* c2 = HConstant::cast(const32_minus_sa); 10602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return c1->HasInteger32Value() && c2->HasInteger32Value() && 10603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (c1->Integer32Value() + c2->Integer32Value() == 32); 10604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!const32_minus_sa->IsSub()) return false; 10606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HSub* sub = HSub::cast(const32_minus_sa); 10607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return sub->left()->EqualsInteger32Constant(32) && sub->right() == sa; 10608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Checks if the left and the right are shift instructions with the oposite 10612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// directions that can be replaced by one rotate right instruction or not. 10613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Returns the operand and the shift amount for the rotate instruction in the 10614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// former case. 10615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HGraphBuilder::MatchRotateRight(HValue* left, 10616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right, 10617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue** operand, 10618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue** shift_amount) { 10619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HShl* shl; 10620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HShr* shr; 10621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (left->IsShl() && right->IsShr()) { 10622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shl = HShl::cast(left); 10623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shr = HShr::cast(right); 10624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (left->IsShr() && right->IsShl()) { 10625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shl = HShl::cast(right); 10626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shr = HShr::cast(left); 10627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 10629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shl->left() != shr->left()) return false; 10631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!ShiftAmountsAllowReplaceByRotate(shl->right(), shr->right()) && 10633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !ShiftAmountsAllowReplaceByRotate(shr->right(), shl->right())) { 10634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 10635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *operand = shr->left(); 10637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *shift_amount = shr->right(); 10638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 10639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10641b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool CanBeZero(HValue* right) { 10643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (right->IsConstant()) { 10644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* right_const = HConstant::cast(right); 10645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (right_const->HasInteger32Value() && 10646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (right_const->Integer32Value() & 0x1f) != 0) { 10647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 10648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 10651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10652b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10653f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHValue* HGraphBuilder::EnforceNumberType(HValue* number, AstType* expected) { 10654f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (expected->Is(AstType::SignedSmall())) { 10655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddUncasted<HForceRepresentation>(number, Representation::Smi()); 10656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10657f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (expected->Is(AstType::Signed32())) { 10658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddUncasted<HForceRepresentation>(number, 10659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation::Integer32()); 10660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return number; 10662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 10663b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10664f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHValue* HGraphBuilder::TruncateToNumber(HValue* value, AstType** expected) { 10665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value->IsConstant()) { 10666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* constant = HConstant::cast(value); 10667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Maybe<HConstant*> number = 10668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constant->CopyToTruncatedNumber(isolate(), zone()); 10669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (number.IsJust()) { 10670f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch *expected = AstType::Number(); 10671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return AddInstruction(number.FromJust()); 10672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10674257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We put temporary values on the stack, which don't correspond to anything 10676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in baseline code. Since nothing is observable we avoid recording those 10677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pushes with a NoObservableSideEffectsScope. 10678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 10679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10680f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AstType* expected_type = *expected; 10681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Separate the number type from the rest. 10683f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AstType* expected_obj = 10684f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AstType::Intersect(expected_type, AstType::NonNumber(), zone()); 10685f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AstType* expected_number = 10686f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AstType::Intersect(expected_type, AstType::Number(), zone()); 10687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We expect to get a number. 10689f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // (We need to check first, since AstType::None->Is(AstType::Any()) == true. 10690f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (expected_obj->Is(AstType::None())) { 10691f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(!expected_number->Is(AstType::None())); 10692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return value; 10693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10695f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (expected_obj->Is(AstType::Undefined())) { 10696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This is already done by HChange. 10697f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch *expected = AstType::Union(expected_number, AstType::Number(), zone()); 10698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return value; 10699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return value; 10702b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 10703b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10704b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHValue* HOptimizedGraphBuilder::BuildBinaryOperation( 10706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BinaryOperation* expr, 10707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left, 10708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* right, 10709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushBeforeSimulateBehavior push_sim_result) { 10710f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AstType* left_type = bounds_.get(expr->left()).lower; 10711f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AstType* right_type = bounds_.get(expr->right()).lower; 10712f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AstType* result_type = bounds_.get(expr).lower; 10713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Maybe<int> fixed_right_arg = expr->fixed_right_arg(); 10714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> allocation_site = expr->allocation_site(); 10715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HAllocationMode allocation_mode; 10717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) { 10718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_mode = HAllocationMode(allocation_site); 10719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result = HGraphBuilder::BuildBinaryOperation( 10721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->op(), left, right, left_type, right_type, result_type, 10722109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch fixed_right_arg, allocation_mode, expr->id()); 10723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Add a simulate after instructions with observable side effects, and 10724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // after phis, which are the result of BuildBinaryOperation when we 10725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inlined some complex subgraph. 10726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (result->HasObservableSideEffects() || result->IsPhi()) { 10727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (push_sim_result == PUSH_BEFORE_SIMULATE) { 10728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(result); 10729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 10730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 10731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 10733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 107361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 107371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 10738f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHValue* HGraphBuilder::BuildBinaryOperation( 10739f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Token::Value op, HValue* left, HValue* right, AstType* left_type, 10740f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AstType* right_type, AstType* result_type, Maybe<int> fixed_right_arg, 10741f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HAllocationMode allocation_mode, BailoutId opt_id) { 10742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool maybe_string_add = false; 10743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (op == Token::ADD) { 10744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If we are adding constant string with something for which we don't have 10745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // a feedback yet, assume that it's also going to be a string and don't 10746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // generate deopt instructions. 10747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!left_type->IsInhabited() && right->IsConstant() && 10748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant::cast(right)->HasStringValue()) { 10749f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch left_type = AstType::String(); 10750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 10751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!right_type->IsInhabited() && left->IsConstant() && 10753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant::cast(left)->HasStringValue()) { 10754f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch right_type = AstType::String(); 10755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 10756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10757f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch maybe_string_add = (left_type->Maybe(AstType::String()) || 10758f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch left_type->Maybe(AstType::Receiver()) || 10759f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch right_type->Maybe(AstType::String()) || 10760f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch right_type->Maybe(AstType::Receiver())); 10761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 10762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Representation left_rep = RepresentationFor(left_type); 10764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Representation right_rep = RepresentationFor(right_type); 10765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!left_type->IsInhabited()) { 10767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HDeoptimize>( 10768f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason::kInsufficientTypeFeedbackForLHSOfBinaryOperation, 10769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Deoptimizer::SOFT); 10770f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch left_type = AstType::Any(); 10771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left_rep = RepresentationFor(left_type); 10772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch maybe_string_add = op == Token::ADD; 10773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!right_type->IsInhabited()) { 10776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HDeoptimize>( 10777f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason::kInsufficientTypeFeedbackForRHSOfBinaryOperation, 10778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Deoptimizer::SOFT); 10779f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch right_type = AstType::Any(); 10780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch right_rep = RepresentationFor(right_type); 10781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch maybe_string_add = op == Token::ADD; 10782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 10783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10784109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!maybe_string_add) { 10785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left = TruncateToNumber(left, &left_type); 10786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch right = TruncateToNumber(right, &right_type); 10787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Special case for string addition here. 10790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (op == Token::ADD && 10791f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch (left_type->Is(AstType::String()) || right_type->Is(AstType::String()))) { 10792109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Validate type feedback for left argument. 10793f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (left_type->Is(AstType::String())) { 10794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left = BuildCheckString(left); 10795109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 10796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10797109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Validate type feedback for right argument. 10798f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (right_type->Is(AstType::String())) { 10799109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch right = BuildCheckString(right); 10800109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 10801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10802109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Convert left argument as necessary. 10803f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (left_type->Is(AstType::Number())) { 10804f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(right_type->Is(AstType::String())); 10805109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch left = BuildNumberToString(left, left_type); 10806f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else if (!left_type->Is(AstType::String())) { 10807f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(right_type->Is(AstType::String())); 10808109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return AddUncasted<HStringAdd>( 10809109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch left, right, allocation_mode.GetPretenureMode(), 10810109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch STRING_ADD_CONVERT_LEFT, allocation_mode.feedback_site()); 10811109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 10812f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch 10813109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Convert right argument as necessary. 10814f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (right_type->Is(AstType::Number())) { 10815f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(left_type->Is(AstType::String())); 10816109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch right = BuildNumberToString(right, right_type); 10817f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else if (!right_type->Is(AstType::String())) { 10818f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(left_type->Is(AstType::String())); 10819109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return AddUncasted<HStringAdd>( 10820109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch left, right, allocation_mode.GetPretenureMode(), 10821109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch STRING_ADD_CONVERT_RIGHT, allocation_mode.feedback_site()); 10822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 10823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Fast paths for empty constant strings. 10825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<String> left_string = 10826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left->IsConstant() && HConstant::cast(left)->HasStringValue() 10827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? HConstant::cast(left)->StringValue() 10828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Handle<String>(); 10829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<String> right_string = 10830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch right->IsConstant() && HConstant::cast(right)->HasStringValue() 10831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? HConstant::cast(right)->StringValue() 10832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Handle<String>(); 10833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!left_string.is_null() && left_string->length() == 0) return right; 10834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!right_string.is_null() && right_string->length() == 0) return left; 10835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!left_string.is_null() && !right_string.is_null()) { 10836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return AddUncasted<HStringAdd>( 10837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left, right, allocation_mode.GetPretenureMode(), 10838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); 10839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Register the dependent code with the allocation site. 10842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!allocation_mode.feedback_site().is_null()) { 10843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!graph()->info()->IsStub()); 10844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> site(allocation_mode.feedback_site()); 10845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch top_info()->dependencies()->AssumeTenuringDecision(site); 10846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Inline the string addition into the stub when creating allocation 10849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // mementos to gather allocation site feedback, or if we can statically 10850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // infer that we're going to create a cons string. 10851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((graph()->info()->IsStub() && 10852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_mode.CreateAllocationMementos()) || 10853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (left->IsConstant() && 10854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(left)->HasStringValue() && 10855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(left)->StringValue()->length() + 1 >= 10856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConsString::kMinLength) || 10857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (right->IsConstant() && 10858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(right)->HasStringValue() && 10859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(right)->StringValue()->length() + 1 >= 10860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConsString::kMinLength)) { 10861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return BuildStringAdd(left, right, allocation_mode); 10862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fallback to using the string add stub. 10865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return AddUncasted<HStringAdd>( 10866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left, right, allocation_mode.GetPretenureMode(), STRING_ADD_CHECK_NONE, 10867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch allocation_mode.feedback_site()); 10868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10870109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Special case for +x here. 10871109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (op == Token::MUL) { 10872109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (left->EqualsInteger32Constant(1)) { 10873109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return BuildToNumber(right); 10874109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 10875109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (right->EqualsInteger32Constant(1)) { 10876109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return BuildToNumber(left); 10877109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 10878109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 10879109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 10880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (graph()->info()->IsStub()) { 10881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left = EnforceNumberType(left, left_type); 10882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right = EnforceNumberType(right, right_type); 108833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 10884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Representation result_rep = RepresentationFor(result_type); 10886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || 10888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (right_rep.IsTagged() && !right_rep.IsSmi()); 10889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 108903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HInstruction* instr = NULL; 10891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Only the stub is allowed to call into the runtime, since otherwise we would 10892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inline several instructions (including the two pushes) for every tagged 10893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // operation in optimized code, which is more expensive, than a stub call. 10894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (graph()->info()->IsStub() && is_non_primitive) { 10895c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* values[] = {left, right}; 10896bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define GET_STUB(Name) \ 10897bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch do { \ 10898bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Callable callable = CodeFactory::Name(isolate()); \ 10899bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HValue* stub = Add<HConstant>(callable.code()); \ 10900bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch instr = AddUncasted<HCallWithDescriptor>(stub, 0, callable.descriptor(), \ 10901bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ArrayVector(values)); \ 10902bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } while (false) 10903bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 10904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (op) { 10905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 10906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 10907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Token::ADD: 10908bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GET_STUB(Add); 10909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 10910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Token::SUB: 10911bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GET_STUB(Subtract); 10912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 10913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Token::MUL: 10914bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GET_STUB(Multiply); 10915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 10916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Token::DIV: 10917bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GET_STUB(Divide); 10918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 10919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Token::MOD: 10920bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GET_STUB(Modulus); 10921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 10922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Token::BIT_OR: 10923bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GET_STUB(BitwiseOr); 10924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 10925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Token::BIT_AND: 10926bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GET_STUB(BitwiseAnd); 10927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 10928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Token::BIT_XOR: 10929bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GET_STUB(BitwiseXor); 10930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 10931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Token::SAR: 10932bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GET_STUB(ShiftRight); 10933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 10934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Token::SHR: 10935bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GET_STUB(ShiftRightLogical); 10936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 10937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Token::SHL: 10938bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GET_STUB(ShiftLeft); 10939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 10940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 10941bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#undef GET_STUB 10942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (op) { 10944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::ADD: 10945109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch instr = AddUncasted<HAdd>(left, right); 10946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::SUB: 10948109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch instr = AddUncasted<HSub>(left, right); 10949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::MUL: 10951109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch instr = AddUncasted<HMul>(left, right); 10952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::MOD: { 10954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (fixed_right_arg.IsJust() && 10955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !right->EqualsInteger32Constant(fixed_right_arg.FromJust())) { 10956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant* fixed_right = 10957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HConstant>(static_cast<int>(fixed_right_arg.FromJust())); 10958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder if_same(this); 10959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ); 10960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if_same.Then(); 10961f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if_same.ElseDeopt(DeoptimizeReason::kUnexpectedRHSOfBinaryOperation); 10962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right = fixed_right; 10963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10964109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch instr = AddUncasted<HMod>(left, right); 10965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 109663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 10967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::DIV: 10968109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch instr = AddUncasted<HDiv>(left, right); 10969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::BIT_XOR: 10971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::BIT_AND: 10972109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch instr = AddUncasted<HBitwise>(op, left, right); 10973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::BIT_OR: { 10975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue *operand, *shift_amount; 10976f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (left_type->Is(AstType::Signed32()) && 10977f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch right_type->Is(AstType::Signed32()) && 10978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MatchRotateRight(left, right, &operand, &shift_amount)) { 10979109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch instr = AddUncasted<HRor>(operand, shift_amount); 10980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 10981109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch instr = AddUncasted<HBitwise>(op, left, right); 10982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::SAR: 10986109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch instr = AddUncasted<HSar>(left, right); 10987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::SHR: 10989109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch instr = AddUncasted<HShr>(left, right); 10990958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->IsShr() && CanBeZero(right)) { 10991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph()->RecordUint32Instruction(instr); 10992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 10993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::SHL: 10995109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch instr = AddUncasted<HShl>(left, right); 10996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 10998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 10999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 110003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 110013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->IsBinaryOperation()) { 11003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBinaryOperation* binop = HBinaryOperation::cast(instr); 11004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch binop->set_observed_input_representation(1, left_rep); 11005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch binop->set_observed_input_representation(2, right_rep); 11006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch binop->initialize_output_representation(result_rep); 11007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (graph()->info()->IsStub()) { 11008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Stub should not call into stub. 11009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->SetFlag(HValue::kCannotBeTagged); 11010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // And should truncate on HForceRepresentation already. 11011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (left->IsForceRepresentation()) { 11012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left->CopyFlag(HValue::kTruncatingToSmi, instr); 11013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch left->CopyFlag(HValue::kTruncatingToInt32, instr); 11014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (right->IsForceRepresentation()) { 11016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right->CopyFlag(HValue::kTruncatingToSmi, instr); 11017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right->CopyFlag(HValue::kTruncatingToInt32, instr); 11018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 110201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 11021b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return instr; 11022b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11023b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11024b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11025b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Check for the form (%_ClassOf(foo) === 'BarClass'). 11026b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic bool IsClassOfTest(CompareOperation* expr) { 11027b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (expr->op() != Token::EQ_STRICT) return false; 11028b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CallRuntime* call = expr->left()->AsCallRuntime(); 11029b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (call == NULL) return false; 11030b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Literal* literal = expr->right()->AsLiteral(); 11031b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (literal == NULL) return false; 11032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!literal->value()->IsString()) return false; 1103362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (call->is_jsruntime()) return false; 1103462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (call->function()->function_id != Runtime::kInlineClassOf) return false; 1103562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(call->arguments()->length(), 1); 11036b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return true; 11037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11038b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { 11040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 11041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 11042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 11043257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch switch (expr->op()) { 110443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case Token::COMMA: 110453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return VisitComma(expr); 110463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case Token::OR: 110473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case Token::AND: 110483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return VisitLogicalExpression(expr); 110493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch default: 110503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return VisitArithmeticExpression(expr); 11051257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 11052257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 11053b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11054b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitComma(BinaryOperation* expr) { 11056257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForEffect(expr->left())); 11057257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Visit the right subexpression in the same AST context as the entire 11058257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // expression. 11059257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Visit(expr->right()); 11060257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 11061e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 11062e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 11063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) { 110643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool is_logical_and = expr->op() == Token::AND; 11065257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (ast_context()->IsTest()) { 11066257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch TestContext* context = TestContext::cast(ast_context()); 11067257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Translate left subexpression. 11068257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* eval_right = graph()->CreateBasicBlock(); 11069257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (is_logical_and) { 11070257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_BAILOUT(VisitForControl(expr->left(), 11071257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch eval_right, 11072257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch context->if_false())); 11073257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 11074257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_BAILOUT(VisitForControl(expr->left(), 11075257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch context->if_true(), 11076257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch eval_right)); 11077257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 11078257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 11079257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Translate right subexpression by visiting it in the same AST 11080257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // context as the entire expression. 110813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CHECK(eval_right->HasPredecessor()); 110823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch eval_right->SetJoinId(expr->RightId()); 110833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch set_current_block(eval_right); 110843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Visit(expr->right()); 11085257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else if (ast_context()->IsValue()) { 11086257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(expr->left())); 11087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 11088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* left_value = Top(); 11089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Short-circuit left values that always evaluate to the same boolean value. 11091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->left()->ToBooleanIsTrue() || expr->left()->ToBooleanIsFalse()) { 11092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // l (evals true) && r -> r 11093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // l (evals true) || r -> l 11094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // l (evals false) && r -> l 11095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // l (evals false) || r -> r 11096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_logical_and == expr->left()->ToBooleanIsTrue()) { 11097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 11098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(expr->right())); 11099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(Pop()); 11101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11102257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 11103257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // We need an extra block to maintain edge-split form. 11104257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* empty_block = graph()->CreateBasicBlock(); 11105257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* eval_right = graph()->CreateBasicBlock(); 11106c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ToBooleanHints expected(expr->left()->to_boolean_types()); 111073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HBranch* test = is_logical_and 11108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? New<HBranch>(left_value, expected, eval_right, empty_block) 11109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : New<HBranch>(left_value, expected, empty_block, eval_right); 11110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FinishCurrentBlock(test); 11111257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 11112257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch set_current_block(eval_right); 11113257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Drop(1); // Value of the left subexpression. 11114257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_BAILOUT(VisitForValue(expr->right())); 11115257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 11116257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* join_block = 11117257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CreateJoin(empty_block, current_block(), expr->id()); 11118257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch set_current_block(join_block); 111193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnValue(Pop()); 11120e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 11121257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 11122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(ast_context()->IsEffect()); 11123257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // In an effect context, we don't need the value of the left subexpression, 11124257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // only its control flow and side effects. We need an extra block to 11125257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // maintain edge-split form. 11126257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* empty_block = graph()->CreateBasicBlock(); 11127257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* right_block = graph()->CreateBasicBlock(); 11128257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (is_logical_and) { 11129257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_BAILOUT(VisitForControl(expr->left(), right_block, empty_block)); 11130e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 11131257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_BAILOUT(VisitForControl(expr->left(), empty_block, right_block)); 11132257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 11133257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 11134257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // TODO(kmillikin): Find a way to fix this. It's ugly that there are 11135257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // actually two empty blocks (one here and one inserted by 11136257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // TestContext::BuildBranch, and that they both have an HSimulate though the 11137257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // second one is not a merge node, and that we really have no good AST ID to 11138257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // put on that first HSimulate. 11139257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 111403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Technically, we should be able to handle the case when one side of 111413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // the test is not connected, but this can trip up liveness analysis 111423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // if we did not fully connect the test context based on some optimistic 111433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // assumption. If such an assumption was violated, we would end up with 111443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // an environment with optimized-out values. So we should always 111453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // conservatively connect the test context. 11146257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 111473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CHECK(right_block->HasPredecessor()); 111483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CHECK(empty_block->HasPredecessor()); 111493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 111503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch empty_block->SetJoinId(expr->id()); 111513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 111523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch right_block->SetJoinId(expr->RightId()); 111533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch set_current_block(right_block); 111543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CHECK_BAILOUT(VisitForEffect(expr->right())); 111553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch right_block = current_block(); 11156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11157257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HBasicBlock* join_block = 11158257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CreateJoin(empty_block, right_block, expr->id()); 11159257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch set_current_block(join_block); 11160257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // We did not materialize any value in the predecessor environments, 11161257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // so there is no need to handle it here. 11162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 11163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11165b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { 11167257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(expr->left())); 11168257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(expr->right())); 11169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetSourcePosition(expr->position()); 11170257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HValue* right = Pop(); 11171257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HValue* left = Pop(); 11172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* result = 11173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildBinaryOperation(expr, left, right, 11174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE 11175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : PUSH_BEFORE_SIMULATE); 11176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(result); 111773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 111783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 111793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, 11181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* sub_expr, 11182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> check) { 11183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForTypeOf(sub_expr)); 11184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetSourcePosition(expr->position()); 11185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 11186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HTypeofIsAndBranch* instr = New<HTypeofIsAndBranch>(value, check); 11187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnControl(instr, expr->id()); 111883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 111893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1119013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochnamespace { 111913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1119213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochbool IsLiteralCompareStrict(Isolate* isolate, HValue* left, Token::Value op, 1119313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HValue* right) { 111943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return op == Token::EQ_STRICT && 1119513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ((left->IsConstant() && 1119613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch !HConstant::cast(left)->handle(isolate)->IsNumber() && 1119713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch !HConstant::cast(left)->handle(isolate)->IsString()) || 1119813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch (right->IsConstant() && 1119913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch !HConstant::cast(right)->handle(isolate)->IsNumber() && 1120013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch !HConstant::cast(right)->handle(isolate)->IsString())); 11201c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch} 11202c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 1120313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} // namespace 11204c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 11205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 11206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 11207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 11208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 11209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11210f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!is_tracking_positions()) SetSourcePosition(expr->position()); 11211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check for a few fast cases. The AST visiting behavior must be in sync 11213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // with the full codegen: We don't push both left and right values onto 11214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the expression stack when one side is a special-case literal. 11215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* sub_expr = NULL; 11216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> check; 11217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { 11218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return HandleLiteralCompareTypeof(expr, sub_expr, check); 11219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 112203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (expr->IsLiteralCompareUndefined(&sub_expr)) { 11221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue); 11222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->IsLiteralCompareNull(&sub_expr)) { 11224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return HandleLiteralCompareNil(expr, sub_expr, kNullValue); 11225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (IsClassOfTest(expr)) { 11228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CallRuntime* call = expr->left()->AsCallRuntime(); 11229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 11230257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* value = Pop(); 11232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Literal* literal = expr->right()->AsLiteral(); 11233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> rhs = Handle<String>::cast(literal->value()); 11234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HClassOfTestAndBranch* instr = New<HClassOfTestAndBranch>(value, rhs); 112353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnControl(instr, expr->id()); 112363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 112373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11238f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AstType* left_type = bounds_.get(expr->left()).lower; 11239f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AstType* right_type = bounds_.get(expr->right()).lower; 11240f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AstType* combined_type = expr->combined_type(); 112413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11242257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(expr->left())); 11243257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(expr->right())); 11244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* right = Pop(); 11246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* left = Pop(); 11247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Token::Value op = expr->op(); 11248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1124913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (IsLiteralCompareStrict(isolate(), left, op, right)) { 112503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HCompareObjectEqAndBranch* result = 11251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HCompareObjectEqAndBranch>(left, right); 112523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ast_context()->ReturnControl(result, expr->id()); 112533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 112543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (op == Token::INSTANCEOF) { 11256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check to see if the rhs of the instanceof is a known function. 11257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (right->IsConstant() && 11258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HConstant::cast(right)->handle(isolate())->IsJSFunction()) { 11259bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Handle<JSFunction> function = 11260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction>::cast(HConstant::cast(right)->handle(isolate())); 11261f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Make sure that the {function} already has a meaningful initial map 11262f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // (i.e. we constructed at least one instance using the constructor 1126362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // {function}), and has an instance as .prototype. 1126462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (function->has_initial_map() && 1126562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch !function->map()->has_non_instance_prototype()) { 11266f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Lookup @@hasInstance on the {function}. 11267f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<Map> function_map(function->map(), isolate()); 11268f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch PropertyAccessInfo has_instance( 11269f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch this, LOAD, function_map, 11270f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch isolate()->factory()->has_instance_symbol()); 11271f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if we are using the Function.prototype[@@hasInstance]. 11272f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (has_instance.CanAccessMonomorphic() && 11273f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch has_instance.IsDataConstant() && 11274f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch has_instance.constant().is_identical_to( 11275f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch isolate()->function_has_instance())) { 11276f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Add appropriate receiver map check and prototype chain 11277f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // checks to guard the @@hasInstance lookup chain. 11278f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AddCheckMap(right, function_map); 11279f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (has_instance.has_holder()) { 11280f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<JSObject> prototype( 11281f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch JSObject::cast(has_instance.map()->prototype()), isolate()); 11282f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch BuildCheckPrototypeMaps(prototype, has_instance.holder()); 11283f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 11284f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Perform the prototype chain walk. 11285f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<Map> initial_map(function->initial_map(), isolate()); 11286f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch top_info()->dependencies()->AssumeInitialMapCantChange(initial_map); 11287f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HInstruction* prototype = 11288f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Add<HConstant>(handle(initial_map->prototype(), isolate())); 11289f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HHasInPrototypeChainAndBranch* result = 11290f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch New<HHasInPrototypeChainAndBranch>(left, prototype); 11291f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return ast_context()->ReturnControl(result, expr->id()); 11292f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 11293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 11294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 11295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 11296bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Callable callable = CodeFactory::InstanceOf(isolate()); 11297bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HValue* stub = Add<HConstant>(callable.code()); 11298c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* values[] = {left, right}; 11299bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HCallWithDescriptor* result = New<HCallWithDescriptor>( 11300bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch stub, 0, callable.descriptor(), ArrayVector(values)); 11301bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch result->set_type(HType::Boolean()); 11302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ast_context()->ReturnInstruction(result, expr->id()); 11303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else if (op == Token::IN) { 11305bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Callable callable = CodeFactory::HasProperty(isolate()); 11306bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HValue* stub = Add<HConstant>(callable.code()); 11307c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* values[] = {left, right}; 11308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* result = 11309bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch New<HCallWithDescriptor>(stub, 0, callable.descriptor(), 11310bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Vector<HValue*>(values, arraysize(values))); 113113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, expr->id()); 11312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushBeforeSimulateBehavior push_behavior = 11315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE 11316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : PUSH_BEFORE_SIMULATE; 11317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HControlInstruction* compare = BuildCompareInstruction( 11318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch op, left, right, left_type, right_type, combined_type, 11319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScriptPositionToSourcePosition(expr->left()->position()), 11320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScriptPositionToSourcePosition(expr->right()->position()), 11321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch push_behavior, expr->id()); 11322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (compare == NULL) return; // Bailed out. 11323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnControl(compare, expr->id()); 11324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( 11327f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Token::Value op, HValue* left, HValue* right, AstType* left_type, 11328f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AstType* right_type, AstType* combined_type, SourcePosition left_position, 11329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SourcePosition right_position, PushBeforeSimulateBehavior push_sim_result, 11330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId bailout_id) { 11331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Cases handled below depend on collected type feedback. They should 11332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // soft deoptimize when there is no type feedback. 11333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!combined_type->IsInhabited()) { 11334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HDeoptimize>( 11335f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason:: 11336f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch kInsufficientTypeFeedbackForCombinedTypeOfBinaryOperation, 11337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Deoptimizer::SOFT); 11338f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch combined_type = left_type = right_type = AstType::Any(); 11339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Representation left_rep = RepresentationFor(left_type); 11342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Representation right_rep = RepresentationFor(right_type); 11343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Representation combined_rep = RepresentationFor(combined_type); 11344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11345f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (combined_type->Is(AstType::Receiver())) { 11346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (Token::IsEqualityOp(op)) { 11347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // HCompareObjectEqAndBranch can only deal with object, so 11348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // exclude numbers. 11349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((left->IsConstant() && 11350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(left)->HasNumberValue()) || 11351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (right->IsConstant() && 11352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant::cast(right)->HasNumberValue())) { 11353f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Add<HDeoptimize>( 11354f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason::kTypeMismatchBetweenFeedbackAndConstant, 11355f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Deoptimizer::SOFT); 11356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The caller expects a branch instruction, so make it happy. 11357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HBranch>(graph()->GetConstantTrue()); 11358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11359c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (op == Token::EQ) { 11360c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // For abstract equality we need to check both sides are receivers. 11361c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (combined_type->IsClass()) { 11362c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Map> map = combined_type->AsClass()->Map(); 11363c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AddCheckMap(left, map); 11364c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AddCheckMap(right, map); 11365c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 11366c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch BuildCheckHeapObject(left); 11367c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Add<HCheckInstanceType>(left, HCheckInstanceType::IS_JS_RECEIVER); 11368c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch BuildCheckHeapObject(right); 11369c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Add<HCheckInstanceType>(right, HCheckInstanceType::IS_JS_RECEIVER); 113703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 11372c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // For strict equality we only need to check one side. 11373c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* operand_to_check = 11374c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch left->block()->block_id() < right->block()->block_id() ? left 11375c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch : right; 11376c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (combined_type->IsClass()) { 11377c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Map> map = combined_type->AsClass()->Map(); 11378c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AddCheckMap(operand_to_check, map); 11379c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 11380c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch BuildCheckHeapObject(operand_to_check); 11381c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Add<HCheckInstanceType>(operand_to_check, 11382c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HCheckInstanceType::IS_JS_RECEIVER); 11383c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 11384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 11385c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HCompareObjectEqAndBranch* result = 11386c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch New<HCompareObjectEqAndBranch>(left, right); 11387c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return result; 11388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 11389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (combined_type->IsClass()) { 11390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(bmeurer): This is an optimized version of an x < y, x > y, 11391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // x <= y or x >= y, where both x and y are spec objects with the 11392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // same map. The CompareIC collects this map for us. So if we know 11393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // that there's no @@toPrimitive on the map (including the prototype 11394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // chain), and both valueOf and toString are the default initial 11395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // implementations (on the %ObjectPrototype%), then we can reduce 11396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the comparison to map checks on x and y, because the comparison 11397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // will turn into a comparison of "[object CLASS]" to itself (the 11398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // default outcome of toString, since valueOf returns a spec object). 11399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This is pretty much adhoc, so in TurboFan we could do a lot better 11400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // and inline the interesting parts of ToPrimitive (actually we could 11401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // even do that in Crankshaft but we don't want to waste too much 11402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // time on this now). 11403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(Token::IsOrderedRelationalCompareOp(op)); 11404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> map = combined_type->AsClass()->Map(); 11405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAccessInfo value_of(this, LOAD, map, 11406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()->factory()->valueOf_string()); 11407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAccessInfo to_primitive( 11408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch this, LOAD, map, isolate()->factory()->to_primitive_symbol()); 11409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAccessInfo to_string(this, LOAD, map, 11410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()->factory()->toString_string()); 11411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAccessInfo to_string_tag( 11412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch this, LOAD, map, isolate()->factory()->to_string_tag_symbol()); 11413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (to_primitive.CanAccessMonomorphic() && !to_primitive.IsFound() && 11414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch to_string_tag.CanAccessMonomorphic() && 11415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (!to_string_tag.IsFound() || to_string_tag.IsData() || 11416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch to_string_tag.IsDataConstant()) && 11417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value_of.CanAccessMonomorphic() && value_of.IsDataConstant() && 11418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value_of.constant().is_identical_to(isolate()->object_value_of()) && 11419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch to_string.CanAccessMonomorphic() && to_string.IsDataConstant() && 11420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch to_string.constant().is_identical_to( 11421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()->object_to_string())) { 11422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We depend on the prototype chain to stay the same, because we 11423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // also need to deoptimize when someone installs @@toPrimitive 11424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // or @@toStringTag somewhere in the prototype chain. 11425c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Object> prototype(map->prototype(), isolate()); 11426c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (prototype->IsJSObject()) { 11427c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch BuildCheckPrototypeMaps(Handle<JSObject>::cast(prototype), 11428c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<JSObject>::null()); 11429c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 11430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddCheckMap(left, map); 11431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddCheckMap(right, map); 11432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The caller expects a branch instruction, so make it happy. 11433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return New<HBranch>( 11434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->GetConstantBool(op == Token::LTE || op == Token::GTE)); 11435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 11436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 11437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Bailout(kUnsupportedNonPrimitiveCompare); 11438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 11439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11440f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else if (combined_type->Is(AstType::InternalizedString()) && 11441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Token::IsEqualityOp(op)) { 11442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we have a constant argument, it should be consistent with the type 11443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // feedback (otherwise we fail assertions in HCompareObjectEqAndBranch). 11444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((left->IsConstant() && 11445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !HConstant::cast(left)->HasInternalizedStringValue()) || 11446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (right->IsConstant() && 11447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !HConstant::cast(right)->HasInternalizedStringValue())) { 11448f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Add<HDeoptimize>( 11449f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason::kTypeMismatchBetweenFeedbackAndConstant, 11450f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Deoptimizer::SOFT); 11451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The caller expects a branch instruction, so make it happy. 11452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HBranch>(graph()->GetConstantTrue()); 11453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(left); 11455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckInstanceType>(left, HCheckInstanceType::IS_INTERNALIZED_STRING); 11456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(right); 11457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckInstanceType>(right, HCheckInstanceType::IS_INTERNALIZED_STRING); 114583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HCompareObjectEqAndBranch* result = 11459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HCompareObjectEqAndBranch>(left, right); 11460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 11461f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else if (combined_type->Is(AstType::String())) { 11462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(left); 11463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckInstanceType>(left, HCheckInstanceType::IS_STRING); 11464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildCheckHeapObject(right); 11465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HCheckInstanceType>(right, HCheckInstanceType::IS_STRING); 11466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStringCompareAndBranch* result = 11467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HStringCompareAndBranch>(left, right, op); 11468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 11469f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else if (combined_type->Is(AstType::Boolean())) { 11470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddCheckMap(left, isolate()->factory()->boolean_map()); 11471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddCheckMap(right, isolate()->factory()->boolean_map()); 11472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (Token::IsEqualityOp(op)) { 11473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HCompareObjectEqAndBranch* result = 11474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch New<HCompareObjectEqAndBranch>(left, right); 11475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result; 11476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 11477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left = Add<HLoadNamedField>( 11478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left, nullptr, 11479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess::ForOddballToNumber(Representation::Smi())); 11480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch right = Add<HLoadNamedField>( 11481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch right, nullptr, 11482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HObjectAccess::ForOddballToNumber(Representation::Smi())); 11483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HCompareNumericAndBranch* result = 11484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch New<HCompareNumericAndBranch>(left, right, op); 11485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result; 11486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 114873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (op == Token::EQ) { 114883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (left->IsConstant() && 114893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HConstant::cast(left)->GetInstanceType() == ODDBALL_TYPE && 114903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HConstant::cast(left)->IsUndetectable()) { 114913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return New<HIsUndetectableAndBranch>(right); 114923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 114933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 114943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (right->IsConstant() && 114953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HConstant::cast(right)->GetInstanceType() == ODDBALL_TYPE && 114963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HConstant::cast(right)->IsUndetectable()) { 114973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return New<HIsUndetectableAndBranch>(left); 114983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 114993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 115003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 11501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (combined_rep.IsTagged() || combined_rep.IsNone()) { 11502109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HCompareGeneric* result = Add<HCompareGeneric>(left, right, op); 11503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_observed_input_representation(1, left_rep); 11504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_observed_input_representation(2, right_rep); 11505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (result->HasObservableSideEffects()) { 11506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (push_sim_result == PUSH_BEFORE_SIMULATE) { 11507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(result); 11508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSimulate(bailout_id, REMOVABLE_SIMULATE); 11509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Drop(1); 11510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 11511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSimulate(bailout_id, REMOVABLE_SIMULATE); 11512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(jkummerow): Can we make this more efficient? 11515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HBranch* branch = New<HBranch>(result); 11516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return branch; 115173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 11518109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HCompareNumericAndBranch* result = 11519109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch New<HCompareNumericAndBranch>(left, right, op); 11520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->set_observed_input_representation(left_rep, right_rep); 11521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 115223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 11523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 11524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, 11528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* sub_expr, 11529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NilValue nil) { 11530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 11531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 11532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 11533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); 11534f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!is_tracking_positions()) SetSourcePosition(expr->position()); 11535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(sub_expr)); 11536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 115373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HControlInstruction* instr; 11538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->op() == Token::EQ_STRICT) { 11539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* nil_constant = nil == kNullValue 11540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? graph()->GetConstantNull() 11541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : graph()->GetConstantUndefined(); 115423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr = New<HCompareObjectEqAndBranch>(value, nil_constant); 11543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 11544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(Token::EQ, expr->op()); 115453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch instr = New<HIsUndetectableAndBranch>(value); 11546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 115473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return ast_context()->ReturnControl(instr, expr->id()); 11548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::VisitSpread(Spread* expr) { UNREACHABLE(); } 11552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 11553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 11554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::VisitEmptyParentheses(EmptyParentheses* expr) { 11555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 11556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 11557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1155862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid HOptimizedGraphBuilder::VisitGetIterator(GetIterator* expr) { 1155962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 1156062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 11561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 11562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHValue* HOptimizedGraphBuilder::AddThisFunction() { 11563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return AddInstruction(BuildThisFunction()); 11564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 11565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 11566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 11567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildThisFunction() { 11568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we share optimized code between different closures, the 11569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this-function is not a constant, except inside an inlined body. 11570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function_state()->outer() != NULL) { 11571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HConstant>( 11572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_state()->compilation_info()->closure()); 11573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 11574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return New<HThisFunction>(); 11575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11576b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHInstruction* HOptimizedGraphBuilder::BuildFastLiteral( 11580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> boilerplate_object, 11581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteUsageContext* site_context) { 11582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NoObservableSideEffectsScope no_effects(this); 11583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> initial_map(boilerplate_object->map()); 11584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstanceType instance_type = initial_map->instance_type(); 11585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); 11586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HType type = instance_type == JS_ARRAY_TYPE 11588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? HType::JSArray() : HType::JSObject(); 11589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* object_size_constant = Add<HConstant>(initial_map->instance_size()); 11590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PretenureFlag pretenure_flag = NOT_TENURED; 11592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<AllocationSite> top_site(*site_context->top(), isolate()); 11593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_allocation_site_pretenuring) { 11594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pretenure_flag = top_site->GetPretenureMode(); 115953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 115963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<AllocationSite> current_site(*site_context->current(), isolate()); 11598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (*top_site == *current_site) { 11599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We install a dependency for pretenuring only on the outermost literal. 11600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch top_info()->dependencies()->AssumeTenuringDecision(top_site); 11601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 11602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch top_info()->dependencies()->AssumeTransitionStable(current_site); 11603958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 11604bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HInstruction* object = 11605bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Add<HAllocate>(object_size_constant, type, pretenure_flag, instance_type, 11606bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch graph()->GetConstant0(), top_site); 11607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11608f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // If allocation folding reaches kMaxRegularHeapObjectSize the 11609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // elements array may not get folded into the object. Hence, we set the 11610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // elements pointer to empty fixed array and let store elimination remove 11611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this store in the folding case. 11612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HConstant* empty_fixed_array = Add<HConstant>( 11613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->empty_fixed_array()); 11614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 11615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch empty_fixed_array); 11616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildEmitObjectHeader(boilerplate_object, object); 11618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Similarly to the elements pointer, there is no guarantee that all 11620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // property allocations can get folded, so pre-initialize all in-object 11621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // properties to a safe value. 11622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildInitializeInobjectProperties(object, initial_map); 11623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 11624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArrayBase> elements(boilerplate_object->elements()); 11625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int elements_size = (elements->length() > 0 && 11626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements->map() != isolate()->heap()->fixed_cow_array_map()) ? 11627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements->Size() : 0; 11628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (pretenure_flag == TENURED && 11630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements->map() == isolate()->heap()->fixed_cow_array_map() && 11631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->heap()->InNewSpace(*elements)) { 11632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we would like to pretenure a fixed cow array, we must ensure that the 11633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // array is already in old space, otherwise we'll create too many old-to- 11634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // new-space pointers (overflowing the store buffer). 11635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elements = Handle<FixedArrayBase>( 11636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->CopyAndTenureFixedCOWArray( 11637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray>::cast(elements))); 11638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate_object->set_elements(*elements); 11639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* object_elements = NULL; 11642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (elements_size > 0) { 11643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object_elements_size = Add<HConstant>(elements_size); 11644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstanceType instance_type = boilerplate_object->HasFastDoubleElements() 11645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? FIXED_DOUBLE_ARRAY_TYPE : FIXED_ARRAY_TYPE; 11646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object_elements = Add<HAllocate>(object_elements_size, HType::HeapObject(), 11647bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch pretenure_flag, instance_type, 11648bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch graph()->GetConstant0(), top_site); 11649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildEmitElements(boilerplate_object, elements, object_elements, 11650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site_context); 11651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 11652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object_elements); 11653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 11654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> elements_field = 11655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object>(boilerplate_object->elements(), isolate()); 11656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* object_elements_cow = Add<HConstant>(elements_field); 11657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 11658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object_elements_cow); 11659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy in-object properties. 11662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (initial_map->NumberOfFields() != 0 || 11663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch initial_map->unused_property_fields() > 0) { 11664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildEmitInObjectProperties(boilerplate_object, object, site_context, 11665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pretenure_flag); 11666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return object; 11668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildEmitObjectHeader( 11672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> boilerplate_object, 11673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* object) { 11674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(boilerplate_object->properties()->length() == 0); 11675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> boilerplate_object_map(boilerplate_object->map()); 11677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddStoreMapConstant(object, boilerplate_object_map); 11678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> properties_field = 11680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object>(boilerplate_object->properties(), isolate()); 11681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(*properties_field == isolate()->heap()->empty_fixed_array()); 11682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* properties = Add<HConstant>(properties_field); 11683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = HObjectAccess::ForPropertiesPointer(); 11684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, access, properties); 11685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (boilerplate_object->IsJSArray()) { 11687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSArray> boilerplate_array = 11688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSArray>::cast(boilerplate_object); 11689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> length_field = 11690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object>(boilerplate_array->length(), isolate()); 11691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* length = Add<HConstant>(length_field); 11692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(boilerplate_array->length()->IsSmi()); 11694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength( 11695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch boilerplate_array->GetElementsKind()), length); 11696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildEmitInObjectProperties( 11701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> boilerplate_object, 11702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* object, 11703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteUsageContext* site_context, 11704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PretenureFlag pretenure_flag) { 11705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> boilerplate_map(boilerplate_object->map()); 11706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<DescriptorArray> descriptors(boilerplate_map->instance_descriptors()); 11707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int limit = boilerplate_map->NumberOfOwnDescriptors(); 11708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int copied_fields = 0; 11710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < limit; i++) { 11711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PropertyDetails details = descriptors->GetDetails(i); 1171262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (details.location() != kField) continue; 1171362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(kData, details.kind()); 11714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch copied_fields++; 11715958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FieldIndex field_index = FieldIndex::ForDescriptor(*boilerplate_map, i); 11716958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 11717958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 11718958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int property_offset = field_index.offset(); 11719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> name(descriptors->GetKey(i)); 11720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The access for the store depends on the type of the boilerplate. 11722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = boilerplate_object->IsJSArray() ? 11723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForJSArrayOffset(property_offset) : 11724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset); 11725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11726958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (boilerplate_object->IsUnboxedDoubleField(field_index)) { 11727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(!boilerplate_object->IsJSArray()); 11728958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double value = boilerplate_object->RawFastDoublePropertyAt(field_index); 11729958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier access = access.WithRepresentation(Representation::Double()); 11730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HStoreNamedField>(object, access, Add<HConstant>(value)); 11731958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier continue; 11732958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 11733958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> value(boilerplate_object->RawFastPropertyAt(field_index), 11734958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate()); 11735958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 11736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value->IsJSObject()) { 11737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> value_object = Handle<JSObject>::cast(value); 11738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> current_site = site_context->EnterNewScope(); 11739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = 11740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildFastLiteral(value_object, site_context); 11741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site_context->ExitScope(current_site, value_object); 11742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, access, result); 11743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 11744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation representation = details.representation(); 11745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* value_instruction; 11746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (representation.IsDouble()) { 11748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate a HeapNumber box and store the value into it. 11749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize); 11750bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HInstruction* double_box = Add<HAllocate>( 11751bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch heap_number_constant, HType::HeapObject(), pretenure_flag, 11752bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch MUTABLE_HEAP_NUMBER_TYPE, graph()->GetConstant0()); 11753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddStoreMapConstant(double_box, 11754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->mutable_heap_number_map()); 11755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Unwrap the mutable heap number from the boilerplate. 11756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* double_value = 11757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(Handle<HeapNumber>::cast(value)->value()); 11758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>( 11759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double_box, HObjectAccess::ForHeapNumberValue(), double_value); 11760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_instruction = double_box; 11761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (representation.IsSmi()) { 1176213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch value_instruction = value->IsUninitialized(isolate()) 1176313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ? graph()->GetConstant0() 1176413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch : Add<HConstant>(value); 11765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Ensure that value is stored as smi. 11766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch access = access.WithRepresentation(representation); 11767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 11768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_instruction = Add<HConstant>(value); 117693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, access, value_instruction); 11772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int inobject_properties = boilerplate_object->map()->GetInObjectProperties(); 11776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* value_instruction = 11777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); 11778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = copied_fields; i < inobject_properties; i++) { 11779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(boilerplate_object->IsJSObject()); 11780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); 11781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess access = 11782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset); 11783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HStoreNamedField>(object, access, value_instruction); 11784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildEmitElements( 11789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> boilerplate_object, 11790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArrayBase> elements, 11791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object_elements, 11792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteUsageContext* site_context) { 11793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind = boilerplate_object->map()->elements_kind(); 11794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int elements_length = elements->length(); 11795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object_elements_length = Add<HConstant>(elements_length); 11796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildInitializeElementsHeader(object_elements, kind, object_elements_length); 11797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy elements backing store content. 11799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (elements->IsFixedDoubleArray()) { 11800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildEmitFixedDoubleArray(elements, kind, object_elements); 11801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (elements->IsFixedArray()) { 11802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildEmitFixedArray(elements, kind, object_elements, 11803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site_context); 11804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 11805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 11806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( 11811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArrayBase> elements, 11812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 11813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object_elements) { 11814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* boilerplate_elements = Add<HConstant>(elements); 11815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int elements_length = elements->length(); 11816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < elements_length; i++) { 11817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key_constant = Add<HConstant>(i); 11818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* value_instruction = 11819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HLoadKeyed>(boilerplate_elements, key_constant, nullptr, nullptr, 11820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kind, ALLOW_RETURN_HOLE); 11821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, 11822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value_instruction, nullptr, kind); 11823c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch store->SetFlag(HValue::kTruncatingToNumber); 11824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::BuildEmitFixedArray( 11829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArrayBase> elements, 11830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind kind, 11831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* object_elements, 11832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteUsageContext* site_context) { 11833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* boilerplate_elements = Add<HConstant>(elements); 11834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int elements_length = elements->length(); 11835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); 11836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < elements_length; i++) { 11837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> value(fast_elements->get(i), isolate()); 11838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* key_constant = Add<HConstant>(i); 11839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value->IsJSObject()) { 11840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> value_object = Handle<JSObject>::cast(value); 11841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> current_site = site_context->EnterNewScope(); 11842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = 11843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildFastLiteral(value_object, site_context); 11844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch site_context->ExitScope(current_site, value_object); 11845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreKeyed>(object_elements, key_constant, result, nullptr, kind); 11846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 11847958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ElementsKind copy_kind = 11848958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier kind == FAST_HOLEY_SMI_ELEMENTS ? FAST_HOLEY_ELEMENTS : kind; 11849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* value_instruction = 11850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HLoadKeyed>(boilerplate_elements, key_constant, nullptr, nullptr, 11851958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier copy_kind, ALLOW_RETURN_HOLE); 11852958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HStoreKeyed>(object_elements, key_constant, value_instruction, 11853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch nullptr, copy_kind); 118543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 118553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11856589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 11857589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 11858589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 11859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { 11860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 11861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 11862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 11863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instr = BuildThisFunction(); 11864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnInstruction(instr, expr->id()); 11865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::VisitSuperPropertyReference( 11869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SuperPropertyReference* expr) { 11870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!HasStackOverflow()); 11871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(current_block() != NULL); 11872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(current_block()->HasPredecessor()); 11873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Bailout(kSuperReference); 11874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 11875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 11876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 11877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::VisitSuperCallReference(SuperCallReference* expr) { 11878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasStackOverflow()); 11879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block() != NULL); 11880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_block()->HasPredecessor()); 11881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kSuperReference); 11882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitDeclarations( 11885c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Declaration::List* declarations) { 11886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(globals_.is_empty()); 11887f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AstVisitor<HOptimizedGraphBuilder>::VisitDeclarations(declarations); 11888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!globals_.is_empty()) { 11889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> array = 11890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->NewFixedArray(globals_.length(), TENURED); 11891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); 11892bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch int flags = current_info()->GetDeclareGlobalsFlags(); 1189362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FeedbackVector> vector(current_feedback_vector(), isolate()); 11894f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Add<HDeclareGlobals>(array, flags, vector); 11895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch globals_.Rewind(0); 11896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 11898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitVariableDeclaration( 11901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VariableDeclaration* declaration) { 11902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VariableProxy* proxy = declaration->proxy(); 11903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* variable = proxy->var(); 11904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (variable->location()) { 11905f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case VariableLocation::UNALLOCATED: { 11906bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(!variable->binding_needs_init()); 1190762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch globals_.Add(variable->name(), zone()); 1190862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FeedbackSlot slot = proxy->VariableFeedbackSlot(); 11909f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(!slot.IsInvalid()); 11910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch globals_.Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 11911bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch globals_.Add(isolate()->factory()->undefined_value(), zone()); 1191262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch globals_.Add(isolate()->factory()->undefined_value(), zone()); 119133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return; 11914f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 11915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::PARAMETER: 11916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOCAL: 11917f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (variable->binding_needs_init()) { 11918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = graph()->GetConstantHole(); 11919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Bind(variable, value); 11920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 11922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::CONTEXT: 11923f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (variable->binding_needs_init()) { 11924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = graph()->GetConstantHole(); 11925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = environment()->context(); 11926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreContextSlot* store = Add<HStoreContextSlot>( 11927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context, variable->index(), HStoreContextSlot::kNoCheck, value); 11928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (store->HasObservableSideEffects()) { 11929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); 11930589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 11931589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 11932589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch break; 11933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOOKUP: 11934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kUnsupportedLookupSlotInDeclaration); 11935f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case VariableLocation::MODULE: 11936f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 119373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 11938b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 11939b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11940b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 11941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::VisitFunctionDeclaration( 11942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FunctionDeclaration* declaration) { 11943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VariableProxy* proxy = declaration->proxy(); 11944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* variable = proxy->var(); 11945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (variable->location()) { 11946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::UNALLOCATED: { 1194762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch globals_.Add(variable->name(), zone()); 1194862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FeedbackSlot slot = proxy->VariableFeedbackSlot(); 1194962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(!slot.IsInvalid()); 1195062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch globals_.Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 1195162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 1195262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // We need the slot where the literals array lives, too. 1195362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch slot = declaration->fun()->LiteralFeedbackSlot(); 11954f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(!slot.IsInvalid()); 11955f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch globals_.Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 1195662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 11957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo( 11958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch declaration->fun(), current_info()->script(), top_info()); 11959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check for stack-overflow exception. 11960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function.is_null()) return SetStackOverflow(); 11961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch globals_.Add(function, zone()); 11962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 11963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::PARAMETER: 11965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOCAL: { 11966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(declaration->fun())); 11967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 11968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BindIfLive(variable, value); 11969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 11970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::CONTEXT: { 11972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitForValue(declaration->fun())); 11973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* value = Pop(); 11974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* context = environment()->context(); 11975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HStoreContextSlot* store = Add<HStoreContextSlot>( 11976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context, variable->index(), HStoreContextSlot::kNoCheck, value); 11977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (store->HasObservableSideEffects()) { 11978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); 11979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 11981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOOKUP: 11983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Bailout(kUnsupportedLookupSlotInDeclaration); 11984f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case VariableLocation::MODULE: 11985f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 11986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 119873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 119883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 119893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11990109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid HOptimizedGraphBuilder::VisitRewritableExpression( 11991109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch RewritableExpression* node) { 11992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_ALIVE(Visit(node->expression())); 119933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 119943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 119953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11996b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Generators for inline runtime functions. 11997b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Support for types. 11998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateIsSmi(CallRuntime* call) { 11999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 12000257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12001b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* value = Pop(); 12002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HIsSmiAndBranch* result = New<HIsSmiAndBranch>(value); 120033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnControl(result, call->id()); 12004b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12005b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12006b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::GenerateIsJSReceiver(CallRuntime* call) { 12008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 12009257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12010b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* value = Pop(); 120113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HHasInstanceTypeAndBranch* result = 12012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HHasInstanceTypeAndBranch>(value, 12013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FIRST_JS_RECEIVER_TYPE, 12014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LAST_JS_RECEIVER_TYPE); 120153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnControl(result, call->id()); 12016b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12017b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateIsArray(CallRuntime* call) { 12019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 12020257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12021b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* value = Pop(); 120223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HHasInstanceTypeAndBranch* result = 12023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch New<HHasInstanceTypeAndBranch>(value, JS_ARRAY_TYPE); 120243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnControl(result, call->id()); 12025b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12026b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12027b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::GenerateIsTypedArray(CallRuntime* call) { 12029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 1); 12030257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12031b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* value = Pop(); 120323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HHasInstanceTypeAndBranch* result = 12033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch New<HHasInstanceTypeAndBranch>(value, JS_TYPED_ARRAY_TYPE); 120343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnControl(result, call->id()); 12035b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12036b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::GenerateToInteger(CallRuntime* call) { 12039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(1, call->arguments()->length()); 12040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* input = Pop(); 12042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (input->type().IsSmi()) { 12043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ast_context()->ReturnValue(input); 12044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 120453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Callable callable = CodeFactory::ToInteger(isolate()); 120463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HValue* stub = Add<HConstant>(callable.code()); 12047c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* values[] = {input}; 12048bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HInstruction* result = New<HCallWithDescriptor>( 12049bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch stub, 0, callable.descriptor(), ArrayVector(values)); 120503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 12051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 12052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 12053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::GenerateToObject(CallRuntime* call) { 12056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(1, call->arguments()->length()); 12057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* value = Pop(); 12059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* result = BuildToObject(value); 12060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ast_context()->ReturnValue(result); 12061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 12062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::GenerateToString(CallRuntime* call) { 12065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(1, call->arguments()->length()); 12066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* input = Pop(); 12068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (input->type().IsString()) { 12069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ast_context()->ReturnValue(input); 12070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 12071109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Callable callable = CodeFactory::ToString(isolate()); 12072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* stub = Add<HConstant>(callable.code()); 12073c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* values[] = {input}; 12074bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HInstruction* result = New<HCallWithDescriptor>( 12075bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch stub, 0, callable.descriptor(), ArrayVector(values)); 12076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 12077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 12078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 12079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::GenerateToLength(CallRuntime* call) { 12082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(1, call->arguments()->length()); 12083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Callable callable = CodeFactory::ToLength(isolate()); 12085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* input = Pop(); 12086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* stub = Add<HConstant>(callable.code()); 12087c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* values[] = {input}; 12088bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HInstruction* result = New<HCallWithDescriptor>( 12089bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch stub, 0, callable.descriptor(), ArrayVector(values)); 12090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 12091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 12092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::GenerateToNumber(CallRuntime* call) { 12095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(1, call->arguments()->length()); 12096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Callable callable = CodeFactory::ToNumber(isolate()); 12098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* input = Pop(); 12099109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HValue* result = BuildToNumber(input); 12100109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (result->HasObservableSideEffects()) { 12101109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!ast_context()->IsEffect()) Push(result); 12102109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Add<HSimulate>(call->id(), REMOVABLE_SIMULATE); 12103109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!ast_context()->IsEffect()) result = Pop(); 12104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 12105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return ast_context()->ReturnValue(result); 12106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 12107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid HOptimizedGraphBuilder::GenerateIsJSProxy(CallRuntime* call) { 12110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(call->arguments()->length() == 1); 12111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* value = Pop(); 12113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HIfContinuation continuation; 12114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier IfBuilder if_proxy(this); 12115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* smicheck = if_proxy.IfNot<HIsSmiAndBranch>(value); 12117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if_proxy.And(); 12118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* map = Add<HLoadNamedField>(value, smicheck, HObjectAccess::ForMap()); 12119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* instance_type = 12120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapInstanceType()); 12121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if_proxy.If<HCompareNumericAndBranch>( 12122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instance_type, Add<HConstant>(JS_PROXY_TYPE), Token::EQ); 12123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if_proxy.CaptureContinuation(&continuation); 12125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ast_context()->ReturnContinuation(&continuation, call->id()); 12126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 12127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid HOptimizedGraphBuilder::GenerateHasFastPackedElements(CallRuntime* call) { 12130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(call->arguments()->length() == 1); 12131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* object = Pop(); 12133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HIfContinuation continuation(graph()->CreateBasicBlock(), 12134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier graph()->CreateBasicBlock()); 12135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier IfBuilder if_not_smi(this); 12136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if_not_smi.IfNot<HIsSmiAndBranch>(object); 12137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if_not_smi.Then(); 12138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier { 12139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier NoObservableSideEffectsScope no_effects(this); 12140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier IfBuilder if_fast_packed(this); 12142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* elements_kind = BuildGetElementsKind(object); 12143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if_fast_packed.If<HCompareNumericAndBranch>( 12144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier elements_kind, Add<HConstant>(FAST_SMI_ELEMENTS), Token::EQ); 12145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if_fast_packed.Or(); 12146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if_fast_packed.If<HCompareNumericAndBranch>( 12147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier elements_kind, Add<HConstant>(FAST_ELEMENTS), Token::EQ); 12148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if_fast_packed.Or(); 12149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if_fast_packed.If<HCompareNumericAndBranch>( 12150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier elements_kind, Add<HConstant>(FAST_DOUBLE_ELEMENTS), Token::EQ); 12151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if_fast_packed.JoinContinuation(&continuation); 12152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 12153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if_not_smi.JoinContinuation(&continuation); 12154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ast_context()->ReturnContinuation(&continuation, call->id()); 12155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 12156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Fast support for charCodeAt(n). 12159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { 12160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 2); 12161257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12162257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 121631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block HValue* index = Pop(); 121641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block HValue* string = Pop(); 12165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* result = BuildStringCharCodeAt(string, index); 121663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 12167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Fast support for SubString. 12171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { 12172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(3, call->arguments()->length()); 12173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(call->arguments())); 12174109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Callable callable = CodeFactory::SubString(isolate()); 12175109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HValue* stub = Add<HConstant>(callable.code()); 12176f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HValue* to = Pop(); 12177f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HValue* from = Pop(); 12178f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HValue* string = Pop(); 12179c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* values[] = {string, from, to}; 12180f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HInstruction* result = New<HCallWithDescriptor>( 12181f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch stub, 0, callable.descriptor(), ArrayVector(values)); 12182109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch result->set_type(HType::String()); 121833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ast_context()->ReturnInstruction(result, call->id()); 12184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Fast support for calls. 12188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::GenerateCall(CallRuntime* call) { 12189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_LE(2, call->arguments()->length()); 12190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_ALIVE(VisitExpressions(call->arguments())); 12191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallTrampolineDescriptor descriptor(isolate()); 12192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushArgumentsFromEnvironment(call->arguments()->length() - 1); 12193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* trampoline = Add<HConstant>(isolate()->builtins()->Call()); 12194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* target = Pop(); 12195c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HValue* values[] = {target, Add<HConstant>(call->arguments()->length() - 2)}; 12196bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HInstruction* result = 12197bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch New<HCallWithDescriptor>(trampoline, call->arguments()->length() - 1, 12198bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch descriptor, ArrayVector(values)); 12199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 12200b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12201b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12202b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::GenerateFixedArrayGet(CallRuntime* call) { 12204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(call->arguments()->length() == 2); 12205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 12207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* index = Pop(); 12208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* object = Pop(); 12209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HInstruction* result = New<HLoadKeyed>( 12210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object, index, nullptr, nullptr, FAST_HOLEY_ELEMENTS, ALLOW_RETURN_HOLE); 12211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ast_context()->ReturnInstruction(result, call->id()); 12212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 12213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::GenerateFixedArraySet(CallRuntime* call) { 12216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(call->arguments()->length() == 3); 12217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 12219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 12220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* value = Pop(); 12221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* index = Pop(); 12222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* object = Pop(); 12223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier NoObservableSideEffectsScope no_effects(this); 12224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Add<HStoreKeyed>(object, index, value, nullptr, FAST_HOLEY_ELEMENTS); 12225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 12226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 12227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::GenerateTheHole(CallRuntime* call) { 12230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(call->arguments()->length() == 0); 12231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ast_context()->ReturnValue(graph()->GetConstantHole()); 12232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 12233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::GenerateCreateIterResultObject(CallRuntime* call) { 12236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(2, call->arguments()->length()); 12237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 12239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* done = Pop(); 12240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* value = Pop(); 12241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* result = BuildCreateIterResultObject(value, done); 12242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ast_context()->ReturnValue(result); 12243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 12244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::GenerateJSCollectionGetTable(CallRuntime* call) { 12247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(call->arguments()->length() == 1); 12248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* receiver = Pop(); 12250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HInstruction* result = New<HLoadNamedField>( 12251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver, nullptr, HObjectAccess::ForJSCollectionTable()); 12252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ast_context()->ReturnInstruction(result, call->id()); 12253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 12254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HOptimizedGraphBuilder::GenerateStringGetRawHashField(CallRuntime* call) { 12257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(call->arguments()->length() == 1); 12258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HValue* object = Pop(); 12260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HInstruction* result = New<HLoadNamedField>( 12261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object, nullptr, HObjectAccess::ForStringHashField()); 12262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ast_context()->ReturnInstruction(result, call->id()); 12263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 12264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate <typename CollectionType> 12267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierHValue* HOptimizedGraphBuilder::BuildAllocateOrderedHashTable() { 12268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kCapacity = CollectionType::kMinCapacity; 12269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kBucketCount = kCapacity / CollectionType::kLoadFactor; 12270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kFixedArrayLength = CollectionType::kHashTableStartIndex + 12271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier kBucketCount + 12272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (kCapacity * CollectionType::kEntrySize); 12273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kSizeInBytes = 12274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FixedArray::kHeaderSize + (kFixedArrayLength * kPointerSize); 12275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Allocate the table and add the proper map. 12277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* table = 12278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HAllocate>(Add<HConstant>(kSizeInBytes), HType::HeapObject(), 12279bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NOT_TENURED, FIXED_ARRAY_TYPE, graph()->GetConstant0()); 12280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddStoreMapConstant(table, isolate()->factory()->ordered_hash_table_map()); 12281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Initialize the FixedArray... 12283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* length = Add<HConstant>(kFixedArrayLength); 12284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HStoreNamedField>(table, HObjectAccess::ForFixedArrayLength(), length); 12285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // ...and the OrderedHashTable fields. 12287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HStoreNamedField>( 12288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier table, 12289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>(), 12290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HConstant>(kBucketCount)); 12291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HStoreNamedField>( 12292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier table, 12293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HObjectAccess::ForOrderedHashTableNumberOfElements<CollectionType>(), 12294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier graph()->GetConstant0()); 12295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HStoreNamedField>( 12296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier table, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements< 12297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CollectionType>(), 12298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier graph()->GetConstant0()); 12299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Fill the buckets with kNotFound. 12301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* not_found = Add<HConstant>(CollectionType::kNotFound); 12302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < kBucketCount; ++i) { 12303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HStoreNamedField>( 12304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier table, HObjectAccess::ForOrderedHashTableBucket<CollectionType>(i), 12305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier not_found); 12306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 12307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Fill the data table with undefined. 12309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* undefined = graph()->GetConstantUndefined(); 12310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < (kCapacity * CollectionType::kEntrySize); ++i) { 12311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HStoreNamedField>(table, 12312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HObjectAccess::ForOrderedHashTableDataTableIndex< 12313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CollectionType, kBucketCount>(i), 12314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier undefined); 12315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 12316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return table; 12318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 12319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid HOptimizedGraphBuilder::GenerateSetInitialize(CallRuntime* call) { 12322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(call->arguments()->length() == 1); 12323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* receiver = Pop(); 12325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier NoObservableSideEffectsScope no_effects(this); 12327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* table = BuildAllocateOrderedHashTable<OrderedHashSet>(); 12328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HStoreNamedField>(receiver, HObjectAccess::ForJSCollectionTable(), table); 12329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ast_context()->ReturnValue(receiver); 12330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 12331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid HOptimizedGraphBuilder::GenerateMapInitialize(CallRuntime* call) { 12334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(call->arguments()->length() == 1); 12335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* receiver = Pop(); 12337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier NoObservableSideEffectsScope no_effects(this); 12339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* table = BuildAllocateOrderedHashTable<OrderedHashMap>(); 12340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HStoreNamedField>(receiver, HObjectAccess::ForJSCollectionTable(), table); 12341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ast_context()->ReturnValue(receiver); 12342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 12343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate <typename CollectionType> 12346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid HOptimizedGraphBuilder::BuildOrderedHashTableClear(HValue* receiver) { 12347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* old_table = Add<HLoadNamedField>( 12348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier receiver, nullptr, HObjectAccess::ForJSCollectionTable()); 12349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* new_table = BuildAllocateOrderedHashTable<CollectionType>(); 12350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HStoreNamedField>( 12351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier old_table, HObjectAccess::ForOrderedHashTableNextTable<CollectionType>(), 12352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier new_table); 12353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HStoreNamedField>( 12354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier old_table, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements< 12355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CollectionType>(), 12356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HConstant>(CollectionType::kClearedTableSentinel)); 12357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HStoreNamedField>(receiver, HObjectAccess::ForJSCollectionTable(), 12358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier new_table); 12359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 12360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid HOptimizedGraphBuilder::GenerateSetClear(CallRuntime* call) { 12363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(call->arguments()->length() == 1); 12364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* receiver = Pop(); 12366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier NoObservableSideEffectsScope no_effects(this); 12368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BuildOrderedHashTableClear<OrderedHashSet>(receiver); 12369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 12370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 12371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid HOptimizedGraphBuilder::GenerateMapClear(CallRuntime* call) { 12374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(call->arguments()->length() == 1); 12375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* receiver = Pop(); 12377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier NoObservableSideEffectsScope no_effects(this); 12379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BuildOrderedHashTableClear<OrderedHashMap>(receiver); 12380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 12381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 12382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateDebugBreakInOptimizedCode( 12384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime* call) { 12385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HDebugBreak>(); 12386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(graph()->GetConstant0()); 12387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOptimizedGraphBuilder::GenerateDebugIsActive(CallRuntime* call) { 12391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call->arguments()->length() == 0); 12392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* ref = 12393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Add<HConstant>(ExternalReference::debug_is_active_address(isolate())); 12394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HValue* value = 12395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Add<HLoadNamedField>(ref, nullptr, HObjectAccess::ForExternalUInteger8()); 12396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ast_context()->ReturnValue(value); 12397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef CHECK_BAILOUT 12400257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#undef CHECK_ALIVE 12401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHEnvironment::HEnvironment(HEnvironment* outer, 12404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Scope* scope, 12405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> closure, 12406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone) 12407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : closure_(closure), 12408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values_(0, zone), 124093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch frame_type_(JS_FUNCTION), 12410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch parameter_count_(0), 12411257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch specials_count_(1), 12412b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch local_count_(0), 12413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch outer_(outer), 12414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_(NULL), 12415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pop_count_(0), 12416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch push_count_(0), 12417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_id_(BailoutId::None()), 12418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone_(zone) { 12419f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeclarationScope* declaration_scope = scope->GetDeclarationScope(); 12420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Initialize(declaration_scope->num_parameters() + 1, 12421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch declaration_scope->num_stack_slots(), 0); 12422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 12423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 12424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 12425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHEnvironment::HEnvironment(Zone* zone, int parameter_count) 12426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : values_(0, zone), 12427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch frame_type_(STUB), 12428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch parameter_count_(parameter_count), 12429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch specials_count_(1), 12430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch local_count_(0), 12431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer_(NULL), 12432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_(NULL), 12433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch pop_count_(0), 12434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch push_count_(0), 12435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_id_(BailoutId::None()), 12436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone_(zone) { 12437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Initialize(parameter_count, 0, 0); 12438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) 12442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : values_(0, zone), 124433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch frame_type_(JS_FUNCTION), 12444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch parameter_count_(0), 12445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch specials_count_(0), 12446b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch local_count_(0), 12447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch outer_(NULL), 12448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_(NULL), 12449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch pop_count_(0), 12450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch push_count_(0), 12451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_id_(other->ast_id()), 12452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone_(zone) { 12453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Initialize(other); 12454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 124573ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHEnvironment::HEnvironment(HEnvironment* outer, 124583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSFunction> closure, 124593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FrameType frame_type, 12460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int arguments, 12461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone) 124623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : closure_(closure), 12463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values_(arguments, zone), 124643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch frame_type_(frame_type), 124653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch parameter_count_(arguments), 12466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch specials_count_(0), 124673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch local_count_(0), 124683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch outer_(outer), 12469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_(NULL), 124703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pop_count_(0), 124713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch push_count_(0), 12472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_id_(BailoutId::None()), 12473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone_(zone) { 124743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 124753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 124763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HEnvironment::Initialize(int parameter_count, 12478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int local_count, 12479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int stack_height) { 12480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch parameter_count_ = parameter_count; 12481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch local_count_ = local_count; 12482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Avoid reallocating the temporaries' backing store on the first Push. 12484257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int total = parameter_count + specials_count_ + local_count + stack_height; 12485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values_.Initialize(total + 4, zone()); 12486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < total; ++i) values_.Add(NULL, zone()); 12487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12489b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 124909fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockvoid HEnvironment::Initialize(const HEnvironment* other) { 124919fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block closure_ = other->closure(); 12492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values_.AddAll(other->values_, zone()); 12493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assigned_variables_.Union(other->assigned_variables_, zone()); 124943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch frame_type_ = other->frame_type_; 124959fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block parameter_count_ = other->parameter_count_; 124969fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block local_count_ = other->local_count_; 124979fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. 12498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_ = other->entry_; 124999fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block pop_count_ = other->pop_count_; 125009fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block push_count_ = other->push_count_; 12501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch specials_count_ = other->specials_count_; 125029fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block ast_id_ = other->ast_id_; 125039fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block} 125049fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 125059fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 12506b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { 12507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!block->IsLoopHeader()); 12508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(values_.length() == other->values_.length()); 12509b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12510b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int length = values_.length(); 12511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < length; ++i) { 12512b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* value = values_[i]; 12513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (value != NULL && value->IsPhi() && value->block() == block) { 12514b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // There is already a phi for the i'th value. 12515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HPhi* phi = HPhi::cast(value); 12516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Assert index is correct and that we haven't missed an incoming edge. 12517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(phi->merged_index() == i || !phi->HasMergedIndex()); 12518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(phi->OperandCount() == block->predecessors()->length()); 12519b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phi->AddInput(other->values_[i]); 12520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else if (values_[i] != other->values_[i]) { 12521b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // There is a fresh value on the incoming edge, a phi is needed. 12522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(values_[i] != NULL && other->values_[i] != NULL); 12523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhi* phi = block->AddNewPhi(i); 12524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HValue* old_value = values_[i]; 12525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int j = 0; j < block->predecessors()->length(); j++) { 12526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phi->AddInput(old_value); 12527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phi->AddInput(other->values_[i]); 12529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch this->values_[i] = phi; 12530b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12531b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12533b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12534b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 125359fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockvoid HEnvironment::Bind(int index, HValue* value) { 12536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(value != NULL); 12537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assigned_variables_.Add(index, zone()); 125389fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block values_[index] = value; 12539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 125429fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockbool HEnvironment::HasExpressionAt(int index) const { 12543257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return index >= parameter_count_ + specials_count_ + local_count_; 125449fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block} 125459fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 125469fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 125479fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockbool HEnvironment::ExpressionStackIsEmpty() const { 12548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(length() >= first_expression_index()); 125493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return length() == first_expression_index(); 125509fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block} 125519fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 125529fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 125539fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockvoid HEnvironment::SetExpressionStackAt(int index_from_top, HValue* value) { 125549fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block int count = index_from_top + 1; 125559fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block int index = values_.length() - count; 12556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(HasExpressionAt(index)); 125579fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block // The push count must include at least the element in question or else 125589fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block // the new value will not be included in this environment's history. 125599fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block if (push_count_ < count) { 125609fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block // This is the same effect as popping then re-pushing 'count' elements. 125619fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block pop_count_ += (count - push_count_); 125629fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block push_count_ = count; 125639fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block } 125649fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block values_[index] = value; 125659fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block} 125669fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 125679fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block 12568958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierHValue* HEnvironment::RemoveExpressionStackAt(int index_from_top) { 12569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int count = index_from_top + 1; 12570958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int index = values_.length() - count; 12571958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(HasExpressionAt(index)); 12572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Simulate popping 'count' elements and then 12573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // pushing 'count - 1' elements back. 12574958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier pop_count_ += Max(count - push_count_, 0); 12575958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier push_count_ = Max(push_count_ - count, 0) + (count - 1); 12576958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return values_.Remove(index); 12577958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 12578958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 12579958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 125809fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockvoid HEnvironment::Drop(int count) { 125819fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block for (int i = 0; i < count; ++i) { 125829fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block Pop(); 12583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12584b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12585b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid HEnvironment::Print() const { 12588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OFStream os(stdout); 12589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch os << *this << "\n"; 12590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 12591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12593b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHEnvironment* HEnvironment::Copy() const { 12594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new(zone()) HEnvironment(this, zone()); 12595b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12596b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12597b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12598b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHEnvironment* HEnvironment::CopyWithoutHistory() const { 12599b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HEnvironment* result = Copy(); 12600b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result->ClearHistory(); 12601b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return result; 12602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { 12606b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HEnvironment* new_env = Copy(); 12607b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < values_.length(); ++i) { 12608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HPhi* phi = loop_header->AddNewPhi(i); 12609b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch phi->AddInput(values_[i]); 12610b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch new_env->values_[i] = phi; 12611b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch new_env->ClearHistory(); 12613b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return new_env; 12614b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12615b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 126173ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, 126183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSFunction> target, 126193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FrameType frame_type, 126203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int arguments) const { 12621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HEnvironment* new_env = 12622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new(zone()) HEnvironment(outer, target, frame_type, 12623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arguments + 1, zone()); 126243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i <= arguments; ++i) { // Include receiver. 126253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_env->Push(ExpressionStackAt(arguments - i)); 126263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 126273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_env->ClearHistory(); 126283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return new_env; 126293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 126303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 126313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid HEnvironment::MarkAsTailCaller() { 126323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(JS_FUNCTION, frame_type()); 126333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch frame_type_ = TAIL_CALLER_FUNCTION; 126343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 126353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 126363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid HEnvironment::ClearTailCallerMark() { 126373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(TAIL_CALLER_FUNCTION, frame_type()); 126383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch frame_type_ = JS_FUNCTION; 126393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 126403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12641257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochHEnvironment* HEnvironment::CopyForInlining( 126423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<JSFunction> target, int arguments, FunctionLiteral* function, 126433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HConstant* undefined, InliningKind inlining_kind, 126443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch TailCallMode syntactic_tail_call_mode) const { 126453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(JS_FUNCTION, frame_type()); 126463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12647b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Outer environment is a copy of this one without the arguments. 12648b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int arity = function->scope()->num_parameters(); 126493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12650b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HEnvironment* outer = Copy(); 126513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch outer->Drop(arguments + 1); // Including receiver. 12652b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch outer->ClearHistory(); 126533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 126543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (syntactic_tail_call_mode == TailCallMode::kAllow) { 126553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(NORMAL_RETURN, inlining_kind); 126563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch outer->MarkAsTailCaller(); 126573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 126583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 12659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (inlining_kind == CONSTRUCT_CALL_RETURN) { 126603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Create artificial constructor stub environment. The receiver should 126613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // actually be the constructor function, but we pass the newly allocated 126623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // object instead, DoComputeConstructStubFrame() relies on that. 126633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch outer = CreateStubEnvironment(outer, target, JS_CONSTRUCT, arguments); 12664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (inlining_kind == GETTER_CALL_RETURN) { 12665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We need an additional StackFrame::INTERNAL frame for restoring the 12666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // correct context. 12667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer = CreateStubEnvironment(outer, target, JS_GETTER, arguments); 12668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (inlining_kind == SETTER_CALL_RETURN) { 12669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We need an additional StackFrame::INTERNAL frame for temporarily saving 12670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the argument of the setter, see StoreStubCompiler::CompileStoreViaSetter. 12671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outer = CreateStubEnvironment(outer, target, JS_SETTER, arguments); 126723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 126733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 126743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (arity != arguments) { 126753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Create artificial arguments adaptation environment. 126763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch outer = CreateStubEnvironment(outer, target, ARGUMENTS_ADAPTOR, arguments); 126773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 126783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 126798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HEnvironment* inner = 12680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new(zone()) HEnvironment(outer, function->scope(), target, zone()); 12681b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the argument values from the original environment. 126823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = 0; i <= arity; ++i) { // Include receiver. 126833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HValue* push = (i <= arguments) ? 126843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExpressionStackAt(arguments - i) : undefined; 126853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch inner->SetValueAt(i, push); 126863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 12687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inner->SetValueAt(arity + 1, context()); 12688257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch for (int i = arity + 2; i < inner->length(); ++i) { 12689257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch inner->SetValueAt(i, undefined); 12690b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12691b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inner->set_ast_id(BailoutId::FunctionEntry()); 12693b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return inner; 12694b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12695b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12696b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os, const HEnvironment& env) { 12698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < env.length(); i++) { 12699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i == 0) os << "parameters\n"; 12700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i == env.parameter_count()) os << "specials\n"; 12701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i == env.parameter_count() + env.specials_count()) os << "locals\n"; 12702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i == env.parameter_count() + env.specials_count() + env.local_count()) { 12703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << "expressions\n"; 12704257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 12705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HValue* val = env.values()->at(i); 12706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << i << ": "; 12707b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (val != NULL) { 12708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << val; 12709b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 12710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << "NULL"; 12711b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << "\n"; 12713b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return os << "\n"; 12715b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12716b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12717b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HTracer::TraceCompilation(CompilationInfo* info) { 12719b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Tag tag(this, "compilation"); 12720bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch std::string name; 1272113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (info->parse_info()) { 1272213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Object* source_name = info->script()->name(); 1272313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (source_name->IsString()) { 1272413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch String* str = String::cast(source_name); 1272513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (str->length() > 0) { 1272613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch name.append(str->ToCString().get()); 1272713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch name.append(":"); 1272813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 12729bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 12730bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 12731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::unique_ptr<char[]> method_name = info->GetDebugName(); 12732bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch name.append(method_name.get()); 12733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->IsOptimizing()) { 12734bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch PrintStringProperty("name", name.c_str()); 12735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintIndent(); 12736bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch trace_.Add("method \"%s:%d\"\n", method_name.get(), 12737bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch info->optimization_id()); 12738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 12739bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch PrintStringProperty("name", name.c_str()); 12740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintStringProperty("method", "stub"); 12741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintLongProperty("date", 12743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int64_t>(base::OS::TimeCurrentMillis())); 12744b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12745b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12746b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12747b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HTracer::TraceLithium(const char* name, LChunk* chunk) { 12748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!chunk->isolate()->concurrent_recompilation_enabled()); 12749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowHandleDereference allow_deref; 12750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference allow_deferred_deref; 12751b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Trace(name, chunk->graph(), chunk); 12752b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12753b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12754b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12755b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HTracer::TraceHydrogen(const char* name, HGraph* graph) { 12756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!graph->isolate()->concurrent_recompilation_enabled()); 12757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowHandleDereference allow_deref; 12758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference allow_deferred_deref; 12759b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Trace(name, graph, NULL); 12760b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12761b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12762b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12763b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HTracer::Trace(const char* name, HGraph* graph, LChunk* chunk) { 12764b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Tag tag(this, "cfg"); 12765b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintStringProperty("name", name); 12766b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const ZoneList<HBasicBlock*>* blocks = graph->blocks(); 12767b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < blocks->length(); i++) { 12768b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HBasicBlock* current = blocks->at(i); 12769b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Tag block_tag(this, "block"); 12770b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintBlockProperty("name", current->block_id()); 12771b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintIntProperty("from_bci", -1); 12772b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintIntProperty("to_bci", -1); 12773b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12774b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!current->predecessors()->is_empty()) { 12775b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintIndent(); 12776b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add("predecessors"); 12777b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int j = 0; j < current->predecessors()->length(); ++j) { 12778b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" \"B%d\"", current->predecessors()->at(j)->block_id()); 12779b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12780b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add("\n"); 12781b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 12782b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintEmptyProperty("predecessors"); 12783b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12784b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 127853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current->end()->SuccessorCount() == 0) { 12786b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintEmptyProperty("successors"); 127873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 127883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrintIndent(); 127893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch trace_.Add("successors"); 127903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (HSuccessorIterator it(current->end()); !it.Done(); it.Advance()) { 127913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch trace_.Add(" \"B%d\"", it.Current()->block_id()); 127923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 127933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch trace_.Add("\n"); 12794b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12795b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12796b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintEmptyProperty("xhandlers"); 12797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 12798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 12799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintIndent(); 12800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trace_.Add("flags"); 12801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current->IsLoopSuccessorDominator()) { 12802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trace_.Add(" \"dom-loop-succ\""); 12803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current->IsUnreachable()) { 12805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trace_.Add(" \"dead\""); 12806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current->is_osr_entry()) { 12808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trace_.Add(" \"osr\""); 12809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch trace_.Add("\n"); 12811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12812b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12813b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (current->dominator() != NULL) { 12814b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintBlockProperty("dominator", current->dominator()->block_id()); 12815b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12816b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12817589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch PrintIntProperty("loop_depth", current->LoopNestingDepth()); 12818589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 12819b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (chunk != NULL) { 12820b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int first_index = current->first_instruction_index(); 12821b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int last_index = current->last_instruction_index(); 12822b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintIntProperty( 12823b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "first_lir_id", 12824b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LifetimePosition::FromInstructionIndex(first_index).Value()); 12825b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintIntProperty( 12826b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "last_lir_id", 12827b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LifetimePosition::FromInstructionIndex(last_index).Value()); 12828b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12829b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12830b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 12831b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Tag states_tag(this, "states"); 12832b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Tag locals_tag(this, "locals"); 12833b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int total = current->phis()->length(); 12834257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch PrintIntProperty("size", current->phis()->length()); 12835257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch PrintStringProperty("method", "None"); 12836b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int j = 0; j < total; ++j) { 12837b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HPhi* phi = current->phis()->at(j); 12838257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch PrintIndent(); 12839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::ostringstream os; 12840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << phi->merged_index() << " " << NameOf(phi) << " " << *phi << "\n"; 12841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier trace_.Add(os.str().c_str()); 12842b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12843b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12844b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12845b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 12846b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Tag HIR_tag(this, "HIR"); 12847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (HInstructionIterator it(current); !it.Done(); it.Advance()) { 12848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HInstruction* instruction = it.Current(); 12849257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int uses = instruction->UseCount(); 12850257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch PrintIndent(); 12851958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::ostringstream os; 12852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << "0 " << uses << " " << NameOf(instruction) << " " << *instruction; 12853c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (instruction->has_position()) { 12854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const SourcePosition pos = instruction->position(); 12855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << " pos:"; 12856c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (pos.isInlined()) os << "inlining(" << pos.InliningId() << "),"; 12857c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch os << pos.ScriptOffset(); 12858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << " <|@\n"; 12860958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier trace_.Add(os.str().c_str()); 12861b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12862b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12863b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12864b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12865b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (chunk != NULL) { 12866b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Tag LIR_tag(this, "LIR"); 12867b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int first_index = current->first_instruction_index(); 12868b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int last_index = current->last_instruction_index(); 12869b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (first_index != -1 && last_index != -1) { 12870b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const ZoneList<LInstruction*>* instructions = chunk->instructions(); 12871b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = first_index; i <= last_index; ++i) { 12872b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LInstruction* linstr = instructions->at(i); 12873b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (linstr != NULL) { 12874257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch PrintIndent(); 12875b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add("%d ", 12876b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LifetimePosition::FromInstructionIndex(i).Value()); 12877b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch linstr->PrintTo(&trace_); 12878958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::ostringstream os; 12879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch os << " [hir:" << NameOf(linstr->hydrogen_value()) << "] <|@\n"; 12880958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier trace_.Add(os.str().c_str()); 12881b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12882b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12883b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12884b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12885b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12886b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12887b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12888b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12889b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HTracer::TraceLiveRanges(const char* name, LAllocator* allocator) { 12890b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Tag tag(this, "intervals"); 12891b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintStringProperty("name", name); 12892b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1289344f0eee88ff00398ff7f715fab053374d808c90dSteve Block const Vector<LiveRange*>* fixed_d = allocator->fixed_double_live_ranges(); 12894b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < fixed_d->length(); ++i) { 12895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceLiveRange(fixed_d->at(i), "fixed", allocator->zone()); 12896b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12897b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1289844f0eee88ff00398ff7f715fab053374d808c90dSteve Block const Vector<LiveRange*>* fixed = allocator->fixed_live_ranges(); 12899b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < fixed->length(); ++i) { 12900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceLiveRange(fixed->at(i), "fixed", allocator->zone()); 12901b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12902b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12903b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const ZoneList<LiveRange*>* live_ranges = allocator->live_ranges(); 12904b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < live_ranges->length(); ++i) { 12905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceLiveRange(live_ranges->at(i), "object", allocator->zone()); 12906b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12907b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12908b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12909b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HTracer::TraceLiveRange(LiveRange* range, const char* type, 12911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone) { 12912b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (range != NULL && !range->IsEmpty()) { 12913257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch PrintIndent(); 12914b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add("%d %s", range->id(), type); 12915b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (range->HasRegisterAssigned()) { 12916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* op = range->CreateAssignedOperand(zone); 12917b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int assigned_reg = op->index(); 12918b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (op->IsDoubleRegister()) { 12919b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" \"%s\"", 1292013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch GetRegConfig()->GetDoubleRegisterName(assigned_reg)); 12921b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 12922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(op->IsRegister()); 1292313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch trace_.Add(" \"%s\"", 1292413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch GetRegConfig()->GetGeneralRegisterName(assigned_reg)); 12925b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12926b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else if (range->IsSpilled()) { 12927b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LOperand* op = range->TopLevel()->GetSpillOperand(); 12928b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (op->IsDoubleStackSlot()) { 12929b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" \"double_stack:%d\"", op->index()); 12930b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 12931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(op->IsStackSlot()); 12932b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" \"stack:%d\"", op->index()); 12933b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12934b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12935b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int parent_index = -1; 12936b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (range->IsChild()) { 12937b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch parent_index = range->parent()->id(); 12938b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 12939b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch parent_index = range->id(); 12940b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12941b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LOperand* op = range->FirstHint(); 12942b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int hint_index = -1; 129433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (op != NULL && op->IsUnallocated()) { 129443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch hint_index = LUnallocated::cast(op)->virtual_register(); 129453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12946b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" %d %d", parent_index, hint_index); 12947b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UseInterval* cur_interval = range->first_interval(); 12948e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while (cur_interval != NULL && range->Covers(cur_interval->start())) { 12949b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" [%d, %d[", 12950b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch cur_interval->start().Value(), 12951b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch cur_interval->end().Value()); 12952b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch cur_interval = cur_interval->next(); 12953b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12954b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12955b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UsePosition* current_pos = range->first_pos(); 12956b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (current_pos != NULL) { 12957e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (current_pos->RegisterIsBeneficial() || FLAG_trace_all_uses) { 12958b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" %d M", current_pos->pos().Value()); 12959b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12960b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch current_pos = current_pos->next(); 12961b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12962b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12963b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Add(" \"\"\n"); 12964b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12965b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12966b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12967b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12968b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid HTracer::FlushToFile() { 12969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AppendChars(filename_.start(), trace_.ToCString().get(), trace_.length(), 12970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch false); 12971b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch trace_.Reset(); 12972b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 12973b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12974b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1297544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid HStatistics::Initialize(CompilationInfo* info) { 12976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!info->has_shared_info()) return; 1297744f0eee88ff00398ff7f715fab053374d808c90dSteve Block source_size_ += info->shared_info()->SourceSize(); 1297844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 1297944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1298044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 12981958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid HStatistics::Print() { 12982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF( 12983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "\n" 12984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "----------------------------------------" 12985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "----------------------------------------\n" 12986958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "--- Hydrogen timing results:\n" 12987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "----------------------------------------" 12988958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "----------------------------------------\n"); 12989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeDelta sum; 12990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < times_.length(); ++i) { 12991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sum += times_[i]; 12992b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 12993b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12994b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < names_.length(); ++i) { 12995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("%33s", names_[i]); 12996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double ms = times_[i].InMillisecondsF(); 12997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double percent = times_[i].PercentOf(sum); 12998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF(" %8.3f ms / %4.1f %% ", ms, percent); 12999b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 13000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t size = sizes_[i]; 13001b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch double size_percent = static_cast<double>(size) * 100 / total_size_; 13002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrintF(" %9zu bytes / %4.1f %%\n", size, size_percent); 13003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 13004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 13005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF( 13006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "----------------------------------------" 13007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "----------------------------------------\n"); 13008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeDelta total = create_graph_ + optimize_graph_ + generate_code_; 13009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("%33s %8.3f ms / %4.1f %% \n", "Create graph", 13010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch create_graph_.InMillisecondsF(), create_graph_.PercentOf(total)); 13011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("%33s %8.3f ms / %4.1f %% \n", "Optimize graph", 13012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch optimize_graph_.InMillisecondsF(), optimize_graph_.PercentOf(total)); 13013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("%33s %8.3f ms / %4.1f %% \n", "Generate and install code", 13014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch generate_code_.InMillisecondsF(), generate_code_.PercentOf(total)); 13015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF( 13016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "----------------------------------------" 13017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "----------------------------------------\n"); 13018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrintF("%33s %8.3f ms %9zu bytes\n", "Total", 13019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total.InMillisecondsF(), total_size_); 13020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("%33s (%.1f times slower than full code gen)\n", "", 13021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total.TimesOf(full_code_gen_)); 13022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1302344f0eee88ff00398ff7f715fab053374d808c90dSteve Block double source_size_in_kb = static_cast<double>(source_size_) / 1024; 1302444f0eee88ff00398ff7f715fab053374d808c90dSteve Block double normalized_time = source_size_in_kb > 0 13025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? total.InMillisecondsF() / source_size_in_kb 1302644f0eee88ff00398ff7f715fab053374d808c90dSteve Block : 0; 13027958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier double normalized_size_in_kb = 13028958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier source_size_in_kb > 0 13029958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ? static_cast<double>(total_size_) / 1024 / source_size_in_kb 13030958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : 0; 13031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("%33s %8.3f ms %7.3f kB allocated\n", 13032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "Average per kB source", normalized_time, normalized_size_in_kb); 13033b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 13034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 13035b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 13036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HStatistics::SaveTiming(const char* name, base::TimeDelta time, 13037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t size) { 13038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total_size_ += size; 13039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < names_.length(); ++i) { 13040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (strcmp(names_[i], name) == 0) { 13041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch times_[i] += time; 13042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sizes_[i] += size; 13043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 13044b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 13045b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 13046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch names_.Add(name); 13047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch times_.Add(time); 13048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sizes_.Add(size); 13049b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 13050b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 13051b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 13052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHPhase::~HPhase() { 13053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ShouldProduceTraceOutput()) { 13054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13055b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 13056b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 13057b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 13058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch graph_->Verify(false); // No full verify. 13059b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 13060b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 13061b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 13062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 13063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 13064