13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Redistribution and use in source and binary forms, with or without 3b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// modification, are permitted provided that the following conditions are 4b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// met: 5b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// 6b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// * Redistributions of source code must retain the above copyright 7b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// notice, this list of conditions and the following disclaimer. 8b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// * Redistributions in binary form must reproduce the above 9b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// copyright notice, this list of conditions and the following 10b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// disclaimer in the documentation and/or other materials provided 11b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// with the distribution. 12b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// * Neither the name of Google Inc. nor the names of its 13b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// contributors may be used to endorse or promote products derived 14b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// from this software without specific prior written permission. 15b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// 16b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 28b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include <stdlib.h> 29b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 30b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "v8.h" 31b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 32b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "api.h" 3344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "cctest.h" 34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "compilation-cache.h" 35b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "debug.h" 36b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "deoptimizer.h" 3744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "isolate.h" 38b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "platform.h" 39b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "stub-cache.h" 40b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 41b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochusing ::v8::internal::Deoptimizer; 42b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochusing ::v8::internal::EmbeddedVector; 4344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockusing ::v8::internal::Handle; 4444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockusing ::v8::internal::Isolate; 4544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockusing ::v8::internal::JSFunction; 46b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochusing ::v8::internal::OS; 4744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockusing ::v8::internal::Object; 48b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 49b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Size of temp buffer for formatting small strings. 50b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define SMALL_STRING_BUFFER_SIZE 80 51b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 52b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Utility class to set --allow-natives-syntax --always-opt and --nouse-inlining 53b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// when constructed and return to their default state when destroyed. 54b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass AlwaysOptimizeAllowNativesSyntaxNoInlining { 55b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 56b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AlwaysOptimizeAllowNativesSyntaxNoInlining() 57b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : always_opt_(i::FLAG_always_opt), 58b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch allow_natives_syntax_(i::FLAG_allow_natives_syntax), 59b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch use_inlining_(i::FLAG_use_inlining) { 60b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_always_opt = true; 61b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_allow_natives_syntax = true; 62b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_use_inlining = false; 63b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 64b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 65b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ~AlwaysOptimizeAllowNativesSyntaxNoInlining() { 66b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_allow_natives_syntax = allow_natives_syntax_; 67b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_always_opt = always_opt_; 68b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_use_inlining = use_inlining_; 69b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 70b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 71b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 72b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool always_opt_; 73b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool allow_natives_syntax_; 74b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool use_inlining_; 75b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 76b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 77b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 78b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Utility class to set --allow-natives-syntax and --nouse-inlining when 79b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// constructed and return to their default state when destroyed. 80b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass AllowNativesSyntaxNoInlining { 81b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 82b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AllowNativesSyntaxNoInlining() 83b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : allow_natives_syntax_(i::FLAG_allow_natives_syntax), 84b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch use_inlining_(i::FLAG_use_inlining) { 85b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_allow_natives_syntax = true; 86b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_use_inlining = false; 87b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 88b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 89b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ~AllowNativesSyntaxNoInlining() { 90b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_allow_natives_syntax = allow_natives_syntax_; 91b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_use_inlining = use_inlining_; 92b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 93b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 94b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 95b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool allow_natives_syntax_; 96b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool use_inlining_; 97b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 98b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 99b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Abort any ongoing incremental marking to make sure that all weak global 1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// handle callbacks are processed. 1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void NonIncrementalGC() { 1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 107053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Blockstatic Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj, 108053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block const char* property_name) { 109b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Local<v8::Function> fun = 110b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Local<v8::Function>::Cast(obj->Get(v8_str(property_name))); 111b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return v8::Utils::OpenHandle(*fun); 112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeSimple) { 116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Test lazy deoptimization of a simple function. 120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AlwaysOptimizeAllowNativesSyntaxNoInlining options; 122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun( 123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var count = 0;" 124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function h() { %DeoptimizeFunction(f); }" 125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function g() { count++; h(); }" 126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f() { g(); };" 1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "f();"); 128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonIncrementalGC(); 130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 13344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Test lazy deoptimization of a simple function. Call the function after the 136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // deoptimization while it is still activated further down the stack. 137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AlwaysOptimizeAllowNativesSyntaxNoInlining options; 139b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun( 140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var count = 0;" 141b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function g() { count++; %DeoptimizeFunction(f); f(false); }" 142b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f(x) { if (x) { g(); } else { return } };" 1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "f(true);"); 144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonIncrementalGC(); 146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 14944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 151b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeSimpleWithArguments) { 154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Test lazy deoptimization of a simple function with some arguments. 158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AlwaysOptimizeAllowNativesSyntaxNoInlining options; 160b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun( 161b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var count = 0;" 162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function h(x) { %DeoptimizeFunction(f); }" 163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function g(x, y) { count++; h(x); }" 164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f(x, y, z) { g(1,x); y+z; };" 1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "f(1, \"2\", false);"); 166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonIncrementalGC(); 168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 17144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Test lazy deoptimization of a simple function with some arguments. Call the 174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // function after the deoptimization while it is still activated further down 175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the stack. 176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 177b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AlwaysOptimizeAllowNativesSyntaxNoInlining options; 178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun( 179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var count = 0;" 180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function g(x, y) { count++; %DeoptimizeFunction(f); f(false, 1, y); }" 181b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f(x, y, z) { if (x) { g(x, y); } else { return y + z; } };" 1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "f(true, 1, \"2\");"); 183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonIncrementalGC(); 185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 187b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 18844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 190b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 191b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeSimpleNested) { 193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Test lazy deoptimization of a simple function. Have a nested function call 197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // do the deoptimization. 198b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AlwaysOptimizeAllowNativesSyntaxNoInlining options; 200b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun( 201b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var count = 0;" 202b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var result = 0;" 203b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function h(x, y, z) { return x + y + z; }" 204b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function g(z) { count++; %DeoptimizeFunction(f); return z;}" 205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f(x,y,z) { return h(x, y, g(z)); };" 2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "result = f(1, 2, 3);"); 2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonIncrementalGC(); 208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(6, env->Global()->Get(v8_str("result"))->Int32Value()); 211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 21244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 213b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 214b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 216b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeRecursive) { 218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Test lazy deoptimization of a simple function called recursively. Call 223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the function recursively a number of times before deoptimizing it. 224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AlwaysOptimizeAllowNativesSyntaxNoInlining options; 225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun( 226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var count = 0;" 227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var calls = 0;" 228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function g() { count++; %DeoptimizeFunction(f); }" 229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f(x) { calls++; if (x > 0) { f(x - 1); } else { g(); } };" 2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "f(10);"); 231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonIncrementalGC(); 233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 235b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(11, env->Global()->Get(v8_str("calls"))->Int32Value()); 23644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 237b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 238b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Local<v8::Function> fun = 239b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(!fun.IsEmpty()); 241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 242b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeMultiple) { 245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AlwaysOptimizeAllowNativesSyntaxNoInlining options; 250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun( 251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var count = 0;" 252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var result = 0;" 253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function g() { count++;" 254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " %DeoptimizeFunction(f1);" 255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " %DeoptimizeFunction(f2);" 256b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " %DeoptimizeFunction(f3);" 257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " %DeoptimizeFunction(f4);}" 258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f4(x) { g(); };" 259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f3(x, y, z) { f4(); return x + y + z; };" 260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f2(x, y) { return x + f3(y + 1, y + 1, y + 1) + y; };" 261b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f1(x) { return f2(x + 1, x + 1) + x; };" 2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "result = f1(1);"); 263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonIncrementalGC(); 265b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 267b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); 26844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 272b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeConstructor) { 273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 277b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AlwaysOptimizeAllowNativesSyntaxNoInlining options; 278b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun( 279b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var count = 0;" 280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function g() { count++;" 281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " %DeoptimizeFunction(f); }" 282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f() { g(); };" 2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "result = new f() instanceof f;"); 284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonIncrementalGC(); 286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(env->Global()->Get(v8_str("result"))->IsTrue()); 28944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AlwaysOptimizeAllowNativesSyntaxNoInlining options; 293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun( 294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var count = 0;" 295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var result = 0;" 296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function g() { count++;" 297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " %DeoptimizeFunction(f); }" 298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f(x, y) { this.x = x; g(); this.y = y; };" 299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "result = new f(1, 2);" 3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "result = result.x + result.y;"); 301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonIncrementalGC(); 303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(3, env->Global()->Get(v8_str("result"))->Int32Value()); 30644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeConstructorMultiple) { 311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 313b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AlwaysOptimizeAllowNativesSyntaxNoInlining options; 316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun( 317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var count = 0;" 318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var result = 0;" 319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function g() { count++;" 320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " %DeoptimizeFunction(f1);" 321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " %DeoptimizeFunction(f2);" 322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " %DeoptimizeFunction(f3);" 323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " %DeoptimizeFunction(f4);}" 324b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f4(x) { this.result = x; g(); };" 325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f3(x, y, z) { this.result = new f4(x + y + z).result; };" 326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f2(x, y) {" 327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " this.result = x + new f3(y + 1, y + 1, y + 1).result + y; };" 328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f1(x) { this.result = new f2(x + 1, x + 1).result + x; };" 3293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "result = new f1(1).result;"); 330b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonIncrementalGC(); 332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 334b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); 33544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeBinaryOperationADDString) { 340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 3413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* f_source = "function f(x, y) { return x + y; };"; 344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AllowNativesSyntaxNoInlining options; 347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Compile function f and collect to type feedback to insert binary op stub 348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // call in the optimized code. 349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_prepare_always_opt = true; 350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("var count = 0;" 351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var result = 0;" 352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var deopt = false;" 353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function X() { };" 354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "X.prototype.toString = function () {" 355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " if (deopt) { count++; %DeoptimizeFunction(f); } return 'an X'" 356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "};"); 357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(f_source); 358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("for (var i = 0; i < 5; i++) {" 359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " f('a+', new X());" 360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "};"); 361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Compile an optimized version of f. 363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_always_opt = true; 364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(f_source); 365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f('a+', new X());"); 366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!i::V8::UseCrankshaft() || 367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch GetJSFunction(env->Global(), "f")->IsOptimized()); 368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Call f and force deoptimization while processing the binary operation. 370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("deopt = true;" 3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var result = f('a+', new X());"); 372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonIncrementalGC(); 374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Value> result = env->Global()->Get(v8_str("result")); 378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(result->IsString()); 379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::String::AsciiValue ascii(result); 380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ("a+an X", *ascii); 38144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic void CompileConstructorWithDeoptimizingValueOf() { 386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("var count = 0;" 387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var result = 0;" 388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var deopt = false;" 389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function X() { };" 390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "X.prototype.valueOf = function () {" 391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " if (deopt) { count++; %DeoptimizeFunction(f); } return 8" 392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "};"); 393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic void TestDeoptimizeBinaryOpHelper(LocalContext* env, 397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* binary_op) { 398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> f_source_buffer; 399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch OS::SNPrintF(f_source_buffer, 400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function f(x, y) { return x %s y; };", 401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch binary_op); 402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch char* f_source = f_source_buffer.start(); 403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AllowNativesSyntaxNoInlining options; 405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Compile function f and collect to type feedback to insert binary op stub 406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // call in the optimized code. 407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_prepare_always_opt = true; 408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileConstructorWithDeoptimizingValueOf(); 409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(f_source); 410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("for (var i = 0; i < 5; i++) {" 411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " f(8, new X());" 412b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "};"); 413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Compile an optimized version of f. 415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_always_opt = true; 416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(f_source); 417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f(7, new X());"); 418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!i::V8::UseCrankshaft() || 419b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch GetJSFunction((*env)->Global(), "f")->IsOptimized()); 420b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Call f and force deoptimization while processing the binary operation. 422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("deopt = true;" 4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var result = f(7, new X());"); 4243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonIncrementalGC(); 425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!GetJSFunction((*env)->Global(), "f")->IsOptimized()); 426b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 428b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 429b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeBinaryOperationADD) { 430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TestDeoptimizeBinaryOpHelper(&env, "+"); 434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(15, env->Global()->Get(v8_str("result"))->Int32Value()); 43744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeBinaryOperationSUB) { 442b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TestDeoptimizeBinaryOpHelper(&env, "-"); 446b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(-1, env->Global()->Get(v8_str("result"))->Int32Value()); 44944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeBinaryOperationMUL) { 454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TestDeoptimizeBinaryOpHelper(&env, "*"); 458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(56, env->Global()->Get(v8_str("result"))->Int32Value()); 46144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeBinaryOperationDIV) { 466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 4673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TestDeoptimizeBinaryOpHelper(&env, "/"); 470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(0, env->Global()->Get(v8_str("result"))->Int32Value()); 47344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 474b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeBinaryOperationMOD) { 478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 4793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TestDeoptimizeBinaryOpHelper(&env, "%"); 482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(7, env->Global()->Get(v8_str("result"))->Int32Value()); 48544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 489b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeCompare) { 490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 492b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* f_source = "function f(x, y) { return x < y; };"; 494b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 496b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AllowNativesSyntaxNoInlining options; 497b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Compile function f and collect to type feedback to insert compare ic 498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // call in the optimized code. 499b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_prepare_always_opt = true; 500b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("var count = 0;" 501b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var result = 0;" 502b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var deopt = false;" 503b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function X() { };" 504b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "X.prototype.toString = function () {" 505b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " if (deopt) { count++; %DeoptimizeFunction(f); } return 'b'" 506b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "};"); 507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(f_source); 508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("for (var i = 0; i < 5; i++) {" 509b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " f('a', new X());" 510b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "};"); 511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 512b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Compile an optimized version of f. 513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_always_opt = true; 514b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(f_source); 515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f('a', new X());"); 516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!i::V8::UseCrankshaft() || 517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch GetJSFunction(env->Global(), "f")->IsOptimized()); 518b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 519b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Call f and force deoptimization while processing the comparison. 520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("deopt = true;" 5213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var result = f('a', new X());"); 522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonIncrementalGC(); 524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); 526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(true, env->Global()->Get(v8_str("result"))->BooleanValue()); 52844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 530b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 531b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeLoadICStoreIC) { 533b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 535b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Functions to generate load/store/keyed load/keyed store IC calls. 537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* f1_source = "function f1(x) { return x.y; };"; 538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* g1_source = "function g1(x) { x.y = 1; };"; 539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* f2_source = "function f2(x, y) { return x[y]; };"; 540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* g2_source = "function g2(x, y) { x[y] = 1; };"; 541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 542b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 543b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AllowNativesSyntaxNoInlining options; 544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Compile functions and collect to type feedback to insert ic 545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // calls in the optimized code. 546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_prepare_always_opt = true; 547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("var count = 0;" 548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var result = 0;" 549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var deopt = false;" 550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function X() { };" 551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "X.prototype.__defineGetter__('y', function () {" 552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " if (deopt) { count++; %DeoptimizeFunction(f1); };" 553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " return 13;" 554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "});" 555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "X.prototype.__defineSetter__('y', function () {" 556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " if (deopt) { count++; %DeoptimizeFunction(g1); };" 557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "});" 558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "X.prototype.__defineGetter__('z', function () {" 559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " if (deopt) { count++; %DeoptimizeFunction(f2); };" 560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " return 13;" 561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "});" 562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "X.prototype.__defineSetter__('z', function () {" 563b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " if (deopt) { count++; %DeoptimizeFunction(g2); };" 564b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "});"); 565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(f1_source); 566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(g1_source); 567b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(f2_source); 568b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(g2_source); 569b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("for (var i = 0; i < 5; i++) {" 570b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " f1(new X());" 571b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " g1(new X());" 572b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " f2(new X(), 'z');" 573b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " g2(new X(), 'z');" 574b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "};"); 575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 576b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Compile an optimized version of the functions. 577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_always_opt = true; 578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(f1_source); 579b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(g1_source); 580b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(f2_source); 581b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(g2_source); 582b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f1(new X());"); 583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("g1(new X());"); 584b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f2(new X(), 'z');"); 585b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("g2(new X(), 'z');"); 586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (i::V8::UseCrankshaft()) { 587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); 588b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); 589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); 590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); 591b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 592b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 593b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Call functions and force deoptimization while processing the ics. 594b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("deopt = true;" 595b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var result = f1(new X());" 596b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "g1(new X());" 597b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "f2(new X(), 'z');" 5983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "g2(new X(), 'z');"); 599b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 6003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonIncrementalGC(); 601b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); 603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); 604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); 605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); 606b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value()); 607b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); 60844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 609b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 610b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 611b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeLoadICStoreICNested) { 613b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 6143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 615b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Functions to generate load/store/keyed load/keyed store IC calls. 617b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* f1_source = "function f1(x) { return x.y; };"; 618b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* g1_source = "function g1(x) { x.y = 1; };"; 619b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* f2_source = "function f2(x, y) { return x[y]; };"; 620b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* g2_source = "function g2(x, y) { x[y] = 1; };"; 621b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch { 623b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AllowNativesSyntaxNoInlining options; 624b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Compile functions and collect to type feedback to insert ic 625b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // calls in the optimized code. 626b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_prepare_always_opt = true; 627b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("var count = 0;" 628b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var result = 0;" 629b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "var deopt = false;" 630b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function X() { };" 631b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "X.prototype.__defineGetter__('y', function () {" 632b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " g1(this);" 633b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " return 13;" 634b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "});" 635b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "X.prototype.__defineSetter__('y', function () {" 636b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " f2(this, 'z');" 637b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "});" 638b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "X.prototype.__defineGetter__('z', function () {" 639b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " g2(this, 'z');" 640b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "});" 641b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "X.prototype.__defineSetter__('z', function () {" 642b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " if (deopt) {" 643b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " count++;" 644b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " %DeoptimizeFunction(f1);" 645b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " %DeoptimizeFunction(g1);" 646b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " %DeoptimizeFunction(f2);" 647b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " %DeoptimizeFunction(g2); };" 648b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "});"); 649b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(f1_source); 650b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(g1_source); 651b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(f2_source); 652b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(g2_source); 653b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("for (var i = 0; i < 5; i++) {" 654b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " f1(new X());" 655b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " g1(new X());" 656b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " f2(new X(), 'z');" 657b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " g2(new X(), 'z');" 658b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "};"); 659b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 660b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Compile an optimized version of the functions. 661b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::FLAG_always_opt = true; 662b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(f1_source); 663b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(g1_source); 664b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(f2_source); 665b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun(g2_source); 666b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f1(new X());"); 667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("g1(new X());"); 668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("f2(new X(), 'z');"); 669b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("g2(new X(), 'z');"); 670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (i::V8::UseCrankshaft()) { 671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); 672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); 673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); 674b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); 675b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 677b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Call functions and force deoptimization while processing the ics. 678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("deopt = true;" 6793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var result = f1(new X());"); 680b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 6813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonIncrementalGC(); 682b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 683b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); 684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); 685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); 686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); 687b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); 688b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); 68944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(Isolate::Current())); 690b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 691