178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 4b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 6b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 89dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/code-stubs.h" 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/compiler.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h" 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/full-codegen.h" 14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/isolate-inl.h" 15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/parser.h" 16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopes.h" 17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/stub-cache.h" 18b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 19b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgnamespace v8 { 20b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgnamespace internal { 21b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 22b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#define __ ACCESS_MASM(masm_) 23b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 24d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 25d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.comclass JumpPatchSite BASE_EMBEDDED { 26d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com public: 27486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) { 28d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com#ifdef DEBUG 29d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com info_emitted_ = false; 30d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com#endif 31d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 32d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 33d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ~JumpPatchSite() { 34d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ASSERT(patch_site_.is_bound() == info_emitted_); 35d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 36d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 3783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void EmitJumpIfNotSmi(Register reg, 3883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* target, 3983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar) { 40d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ testb(reg, Immediate(kSmiTagMask)); 4183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org EmitJump(not_carry, target, near_jump); // Always taken before patched. 42d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 43d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 4483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void EmitJumpIfSmi(Register reg, 4583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* target, 4683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar) { 47d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ testb(reg, Immediate(kSmiTagMask)); 4883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org EmitJump(carry, target, near_jump); // Never taken before patched. 49d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 50d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 51d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com void EmitPatchInfo() { 524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (patch_site_.is_bound()) { 534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site_); 54731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org ASSERT(is_uint8(delta_to_patch_site)); 554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org __ testl(rax, Immediate(delta_to_patch_site)); 56d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com#ifdef DEBUG 574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org info_emitted_ = true; 58d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com#endif 594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } else { 604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org __ nop(); // Signals no inlined code. 614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 62d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 63d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 64d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com private: 65d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // jc will be patched with jz, jnc will become jnz. 6683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void EmitJump(Condition cc, Label* target, Label::Distance near_jump) { 67d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ASSERT(!patch_site_.is_bound() && !info_emitted_); 68d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ASSERT(cc == carry || cc == not_carry); 69d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ bind(&patch_site_); 7083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(cc, target, near_jump); 71d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 72d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 73d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com MacroAssembler* masm_; 74d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com Label patch_site_; 75d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com#ifdef DEBUG 76d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com bool info_emitted_; 77d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com#endif 78d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com}; 79d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 80d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 81b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Generate code for a JS function. On entry to the function the receiver 82b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// and arguments have been pushed on the stack left to right, with the 83b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// return address on top of them. The actual argument count matches the 84b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// formal parameter count expected by the function. 85b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// 86b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// The live registers are: 872efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// o rdi: the JS function object being called (i.e. ourselves) 88b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// o rsi: our context 89b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// o rbp: our caller's frame pointer 90b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// o rsp: stack pointer (pointing to return address) 91b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// 92b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// The function builds a JS frame. Please see JavaScriptFrameConstants in 93b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// frames-x64.h for its layout. 9456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.orgvoid FullCodeGenerator::Generate() { 9556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org CompilationInfo* info = info_; 9604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org handler_table_ = 9704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); 98f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 9941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org profiling_counter_ = isolate()->factory()->NewCell( 100fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); 1015c838251403b0be9a882540f1922577abba4c872ager@chromium.org SetFunctionPosition(function()); 102ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org Comment cmnt(masm_, "[ function compiled by full code generator"); 103b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 104753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org ProfileEntryHookStub::MaybeCallEntryHook(masm_); 105753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org 106a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org#ifdef DEBUG 107a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org if (strlen(FLAG_stop_at) > 0 && 10859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 109a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org __ int3(); 110a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org } 111a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org#endif 112a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org 113486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org // Sloppy mode functions and builtins need to replace the receiver with the 114e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // global proxy when called as functions (without an explicit receiver 115e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // object). 116486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (info->strict_mode() == SLOPPY && !info->is_native()) { 11740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Label ok; 118e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // +1 for return address. 119d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org StackArgumentsAccessor args(rsp, info->scope()->num_parameters()); 12043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, args.GetReceiverOperand()); 121e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 122e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex); 123e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ j(not_equal, &ok, Label::kNear); 124e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 12543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, GlobalObjectOperand()); 12643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); 127e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 12843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(args.GetReceiverOperand(), rcx); 129e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 13040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org __ bind(&ok); 13140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org } 13240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Open a frame scope to indicate that there is a frame on the stack. The 134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // MANUAL indicates that the scope shouldn't actually generate code to set up 135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the frame (that is done below). 136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope frame_scope(masm_, StackFrame::MANUAL); 137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 13883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org info->set_prologue_offset(masm_->pc_offset()); 139285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org __ Prologue(info->IsCodePreAgingActive()); 1404e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org info->AddNoFrameRange(0, masm_->pc_offset()); 141ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 142ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org { Comment cmnt(masm_, "[ Allocate locals"); 1434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int locals_count = info->scope()->num_stack_slots(); 144e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Generators allocate locals, if any, in context slots. 145e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(!info->function()->is_generator() || locals_count == 0); 146ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org if (locals_count == 1) { 147ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ PushRoot(Heap::kUndefinedValueRootIndex); 148ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org } else if (locals_count > 1) { 149a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org if (locals_count >= 128) { 1503ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Label ok; 1513ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ movp(rcx, rsp); 1523ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ subp(rcx, Immediate(locals_count * kPointerSize)); 1533ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ CompareRoot(rcx, Heap::kRealStackLimitRootIndex); 1543ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ j(above_equal, &ok, Label::kNear); 1553ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); 1563ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ bind(&ok); 157a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org } 158ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); 159a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org const int kMaxPushes = 32; 160a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org if (locals_count >= kMaxPushes) { 161a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org int loop_iterations = locals_count / kMaxPushes; 1622f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ movp(rcx, Immediate(loop_iterations)); 163a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Label loop_header; 164a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org __ bind(&loop_header); 165a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org // Do pushes. 166a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org for (int i = 0; i < kMaxPushes; i++) { 167a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org __ Push(rdx); 168a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org } 169a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org // Continue loop if not done. 1702f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ decp(rcx); 171a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org __ j(not_zero, &loop_header, Label::kNear); 172a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org } 173a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org int remaining = locals_count % kMaxPushes; 174a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org // Emit the remaining pushes. 175a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org for (int i = 0; i < remaining; i++) { 176763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rdx); 177b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 178b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 179ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org } 180b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 181ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org bool function_in_register = true; 182b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 183ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Possibly allocate a local context. 1844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 185ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org if (heap_slots > 0) { 18646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Comment cmnt(masm_, "[ Allocate context"); 1877e6132b924829c353864933f29124419916db550machenbach@chromium.org bool need_write_barrier = true; 188ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Argument to NewContext is the function, which is still in rdi. 18946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { 190763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rdi); 19146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ Push(info->scope()->GetScopeInfo()); 192895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); 19346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { 194f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org FastNewContextStub stub(isolate(), heap_slots); 195ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ CallStub(&stub); 1967e6132b924829c353864933f29124419916db550machenbach@chromium.org // Result of FastNewContextStub is always in new space. 1977e6132b924829c353864933f29124419916db550machenbach@chromium.org need_write_barrier = false; 198ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org } else { 199763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rdi); 200895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); 201ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org } 202ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org function_in_register = false; 203bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org // Context is returned in rax. It replaces the context passed to us. 204bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org // It's saved in the stack and kept live in rsi. 205bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org __ movp(rsi, rax); 206bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rax); 207ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 208ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Copy any necessary parameters into the context. 2094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int num_parameters = info->scope()->num_parameters(); 210ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org for (int i = 0; i < num_parameters; i++) { 211486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Variable* var = scope()->parameter(i); 212486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (var->IsContextSlot()) { 213ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org int parameter_offset = StandardFrameConstants::kCallerSPOffset + 214ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org (num_parameters - 1 - i) * kPointerSize; 215ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Load parameter from stack. 21643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, Operand(rbp, parameter_offset)); 217ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Store it in the context. 218486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org int context_offset = Context::SlotOffset(var->index()); 21943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rsi, context_offset), rax); 220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Update the write barrier. This clobbers rax and rbx. 2217e6132b924829c353864933f29124419916db550machenbach@chromium.org if (need_write_barrier) { 2227e6132b924829c353864933f29124419916db550machenbach@chromium.org __ RecordWriteContextSlot( 2237e6132b924829c353864933f29124419916db550machenbach@chromium.org rsi, context_offset, rax, rbx, kDontSaveFPRegs); 2247e6132b924829c353864933f29124419916db550machenbach@chromium.org } else if (FLAG_debug_code) { 2257e6132b924829c353864933f29124419916db550machenbach@chromium.org Label done; 2267e6132b924829c353864933f29124419916db550machenbach@chromium.org __ JumpIfInNewSpace(rsi, rax, &done, Label::kNear); 2277e6132b924829c353864933f29124419916db550machenbach@chromium.org __ Abort(kExpectedNewSpaceObject); 2287e6132b924829c353864933f29124419916db550machenbach@chromium.org __ bind(&done); 2297e6132b924829c353864933f29124419916db550machenbach@chromium.org } 230b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 231b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 232ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org } 233b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 234ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Possibly allocate an arguments object. 2354a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Variable* arguments = scope()->arguments(); 236ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org if (arguments != NULL) { 237ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Arguments object must be allocated after the context object, in 238ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // case the "arguments" or ".arguments" variables are in the context. 239ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org Comment cmnt(masm_, "[ Allocate arguments object"); 240ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org if (function_in_register) { 241763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rdi); 242ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org } else { 243763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 244b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 245ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // The receiver is just before the parameters on the caller's stack. 2464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int num_parameters = info->scope()->num_parameters(); 2474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int offset = num_parameters * kPointerSize; 248895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rdx, 249ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org Operand(rbp, StandardFrameConstants::kCallerSPOffset + offset)); 250763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rdx); 2514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org __ Push(Smi::FromInt(num_parameters)); 252ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Arguments to ArgumentsAccessStub: 253ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // function, receiver address, parameter count. 254ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // The stub will rewrite receiver and parameter count if the previous 255ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // stack frame was an arguments adapter frame. 2562efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org ArgumentsAccessStub::Type type; 257486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (strict_mode() == STRICT) { 2582efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org type = ArgumentsAccessStub::NEW_STRICT; 2592efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } else if (function()->has_duplicate_parameters()) { 260486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; 2612efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } else { 262486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org type = ArgumentsAccessStub::NEW_SLOPPY_FAST; 2632efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 264f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org ArgumentsAccessStub stub(isolate(), type); 265ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ CallStub(&stub); 2664d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org 267486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org SetVar(arguments, rax, rbx, rdx); 268b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 269b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (FLAG_trace) { 271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ CallRuntime(Runtime::kTraceEnter, 0); 272a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 273a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2745d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Visit the declarations and body unless there is an illegal 2755d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // redeclaration. 2765d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org if (scope()->HasIllegalRedeclaration()) { 2775d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org Comment cmnt(masm_, "[ Declarations"); 2785d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org scope()->VisitIllegalRedeclaration(this); 279486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 2805d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } else { 281471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 2825d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org { Comment cmnt(masm_, "[ Declarations"); 2835d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // For named function expressions, declare the function name as a 2845d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // constant. 2855d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org if (scope()->is_function_scope() && scope()->function() != NULL) { 286ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VariableDeclaration* function = scope()->function(); 287ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com ASSERT(function->proxy()->var()->mode() == CONST || 288486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org function->proxy()->var()->mode() == CONST_LEGACY); 289ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); 290ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VisitVariableDeclaration(function); 2915d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } 2925d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org VisitDeclarations(scope()->declarations()); 2935d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } 294b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2955d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org { Comment cmnt(masm_, "[ Stack check"); 296471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); 2973ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Label ok; 2983ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ CompareRoot(rsp, Heap::kStackLimitRootIndex); 2993ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ j(above_equal, &ok, Label::kNear); 3003ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET); 3013ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ bind(&ok); 3025d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } 3035d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 3045d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org { Comment cmnt(masm_, "[ Body"); 3055d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org ASSERT(loop_depth() == 0); 3065d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org VisitStatements(function()->body()); 3075d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org ASSERT(loop_depth() == 0); 3085d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } 309b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 310b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3115d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Always emit a 'return undefined' in case control fell off the end of 3125d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // the body. 313b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org { Comment cmnt(masm_, "[ return <undefined>;"); 314b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 3152cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org EmitReturnSequence(); 316b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 317b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 318b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 319b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3205f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid FullCodeGenerator::ClearAccumulator() { 3215d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ Set(rax, 0); 3225f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 3235f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 3245f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 3251456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { 3269cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org __ Move(rbx, profiling_counter_, RelocInfo::EMBEDDED_OBJECT); 32741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ SmiAddConstant(FieldOperand(rbx, Cell::kValueOffset), 3281456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Smi::FromInt(-delta)); 3291456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} 3301456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 3311456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 3321456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid FullCodeGenerator::EmitProfilingCounterReset() { 3331456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org int reset_value = FLAG_interrupt_budget; 3349cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org __ Move(rbx, profiling_counter_, RelocInfo::EMBEDDED_OBJECT); 335e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ Move(kScratchRegister, Smi::FromInt(reset_value)); 33643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rbx, Cell::kValueOffset), kScratchRegister); 3371456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} 3381456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 3391456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 340731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.orgstatic const byte kJnsOffset = kPointerSize == kInt64Size ? 0x1d : 0x14; 341731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org 342731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org 343cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.orgvoid FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, 344cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org Label* back_edge_target) { 345cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org Comment cmnt(masm_, "[ Back edge bookkeeping"); 34683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label ok; 3471456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 348afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org ASSERT(back_edge_target->is_bound()); 349afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target); 350afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org int weight = Min(kMaxBackEdgeWeight, 351afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org Max(1, distance / kCodeSizeMultiplier)); 352cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org EmitProfilingCounterDecrement(weight); 3531456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 354731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org __ j(positive, &ok, Label::kNear); 355731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org { 356731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org PredictableCodeSizeScope predictible_code_size_scope(masm_, kJnsOffset); 357731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org DontEmitDebugCodeScope dont_emit_debug_code_scope(masm_); 358731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org __ call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET); 359d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 360731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org // Record a mapping of this PC offset to the OSR id. This is used to find 361731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org // the AST id from the unoptimized code in order to use it as a key into 362731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org // the deoptimization input data found in the optimized code. 363731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org RecordBackEdge(stmt->OsrEntryId()); 3641456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 365731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org EmitProfilingCounterReset(); 366731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org } 367a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&ok); 368731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org 369a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 370d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Record a mapping of the OSR id to this PC. This is used if the OSR 371d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // entry becomes the target of a bailout. We don't expect it to be, but 372d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // we want it to work if it is. 373a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); 374a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 375a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 376a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3772cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.orgvoid FullCodeGenerator::EmitReturnSequence() { 378b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Comment cmnt(masm_, "[ Return sequence"); 379b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (return_label_.is_bound()) { 380b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ jmp(&return_label_); 381b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 382b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ bind(&return_label_); 383b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (FLAG_trace) { 384763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 385b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ CallRuntime(Runtime::kTraceExit, 1); 386b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 387afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org // Pretend that the exit is a backwards jump to the entry. 388afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org int weight = 1; 389afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org if (info_->ShouldSelfOptimize()) { 390afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org weight = FLAG_interrupt_budget / FLAG_self_opt_count; 391afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org } else { 392afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org int distance = masm_->pc_offset(); 393afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org weight = Min(kMaxBackEdgeWeight, 394afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org Max(1, distance / kCodeSizeMultiplier)); 3951456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 396afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org EmitProfilingCounterDecrement(weight); 397afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org Label ok; 398afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org __ j(positive, &ok, Label::kNear); 399763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 400afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org __ call(isolate()->builtins()->InterruptCheck(), 401afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org RelocInfo::CODE_TARGET); 402763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rax); 403afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org EmitProfilingCounterReset(); 404afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org __ bind(&ok); 405b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#ifdef DEBUG 406b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Add a label for checking the size of the code used for returning. 407b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Label check_exit_codesize; 408b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org masm_->bind(&check_exit_codesize); 409b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#endif 410e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); 411b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ RecordJSReturn(); 412b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Do not use the leave instruction here because it is too short to 413b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // patch with the code required by the debugger. 41443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsp, rbp); 415763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rbp); 4164e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org int no_frame_start = masm_->pc_offset(); 417d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 4184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int arguments_bytes = (info_->scope()->num_parameters() + 1) * kPointerSize; 419d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com __ Ret(arguments_bytes, rcx); 420d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 421b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Add padding that will be overwritten by a debugger breakpoint. We 4224edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org // have just generated at least 7 bytes: "movp rsp, rbp; pop rbp; ret k" 4234edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org // (3 + 1 + 3) for x64 and at least 6 (2 + 1 + 3) bytes for x32. 4244edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org const int kPadding = Assembler::kJSReturnSequenceLength - 4254edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org kPointerSize == kInt64Size ? 7 : 6; 426b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org for (int i = 0; i < kPadding; ++i) { 427b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org masm_->int3(); 428b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 429d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // Check that the size of the code used for returning is large enough 430d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // for the debugger's requirements. 431d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ASSERT(Assembler::kJSReturnSequenceLength <= 432d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com masm_->SizeOfCodeGeneratedSince(&check_exit_codesize)); 433865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org 4344e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); 435b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 436b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 437b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 438b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 439486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.orgvoid FullCodeGenerator::EffectContext::Plug(Variable* var) const { 440486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 4414a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 442b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 443b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 444486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.orgvoid FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const { 445486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 446486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org codegen()->GetVar(result_register(), var); 4474a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 448b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4494a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 450486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.orgvoid FullCodeGenerator::StackValueContext::Plug(Variable* var) const { 451486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 452486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org MemOperand operand = codegen()->VarOperand(var, result_register()); 453763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(operand); 454b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 455b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 456b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 457486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.orgvoid FullCodeGenerator::TestContext::Plug(Variable* var) const { 458486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org codegen()->GetVar(result_register(), var); 459c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 4606d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org codegen()->DoTest(this); 4614a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 462b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4634a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 4644a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { 465b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 466b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 467b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4684a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::AccumulatorValueContext::Plug( 4694a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Heap::RootListIndex index) const { 4704a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ LoadRoot(result_register(), index); 4714a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 472b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4734a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 4744a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::StackValueContext::Plug( 4754a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Heap::RootListIndex index) const { 4764a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ PushRoot(index); 4774a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 4784a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 4794a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 4804a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { 481c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org codegen()->PrepareForBailoutBeforeSplit(condition(), 482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org true, 483a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org true_label_, 484a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org false_label_); 4854a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (index == Heap::kUndefinedValueRootIndex || 4864a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org index == Heap::kNullValueRootIndex || 4874a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org index == Heap::kFalseValueRootIndex) { 488a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (false_label_ != fall_through_) __ jmp(false_label_); 4894a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } else if (index == Heap::kTrueValueRootIndex) { 490a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (true_label_ != fall_through_) __ jmp(true_label_); 4914a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } else { 4924a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ LoadRoot(result_register(), index); 4936d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org codegen()->DoTest(this); 494b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 495b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 496b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 497b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4984a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::EffectContext::Plug(Handle<Object> lit) const { 4994a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 500b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 501b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5024a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::AccumulatorValueContext::Plug( 5034a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Handle<Object> lit) const { 5047a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org if (lit->IsSmi()) { 5057a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ SafeMove(result_register(), Smi::cast(*lit)); 5067a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org } else { 5077a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ Move(result_register(), lit); 5087a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org } 5094a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 510b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5114a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 5124a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { 5137a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org if (lit->IsSmi()) { 5147a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ SafePush(Smi::cast(*lit)); 5157a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org } else { 5167a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org __ Push(lit); 5177a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org } 5184a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 5194a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 5204a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 5214a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { 522c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org codegen()->PrepareForBailoutBeforeSplit(condition(), 523a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org true, 524a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org true_label_, 525a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org false_label_); 5264a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org ASSERT(!lit->IsUndetectableObject()); // There are no undetectable literals. 5274a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { 528a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (false_label_ != fall_through_) __ jmp(false_label_); 5294a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } else if (lit->IsTrue() || lit->IsJSObject()) { 530a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (true_label_ != fall_through_) __ jmp(true_label_); 5314a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } else if (lit->IsString()) { 5324a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (String::cast(*lit)->length() == 0) { 533a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (false_label_ != fall_through_) __ jmp(false_label_); 5344a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } else { 535a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (true_label_ != fall_through_) __ jmp(true_label_); 5364a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 5374a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } else if (lit->IsSmi()) { 5384a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (Smi::cast(*lit)->value() == 0) { 539a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (false_label_ != fall_through_) __ jmp(false_label_); 5404a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } else { 541a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (true_label_ != fall_through_) __ jmp(true_label_); 5424a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 5434a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } else { 5444a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // For simplicity we always test the accumulator register. 5454a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ Move(result_register(), lit); 5466d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org codegen()->DoTest(this); 547b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 548b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 549b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 550b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5514a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::EffectContext::DropAndPlug(int count, 5524a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Register reg) const { 553b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(count > 0); 5544a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ Drop(count); 5554a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 556b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 557b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5584a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::AccumulatorValueContext::DropAndPlug( 5594a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org int count, 5604a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Register reg) const { 5614a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org ASSERT(count > 0); 5624a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ Drop(count); 5634a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ Move(result_register(), reg); 5644a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 565b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5664a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 5674a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::StackValueContext::DropAndPlug(int count, 5684a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Register reg) const { 5694a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org ASSERT(count > 0); 5704a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (count > 1) __ Drop(count - 1); 57143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rsp, 0), reg); 5729dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 5739dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 5749dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 5754a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::TestContext::DropAndPlug(int count, 5764a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Register reg) const { 5774a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org ASSERT(count > 0); 5784a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // For simplicity we always test the accumulator register. 5794a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ Drop(count); 5804a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ Move(result_register(), reg); 581c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 5826d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org codegen()->DoTest(this); 5834a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 584b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 585b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5864a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::EffectContext::Plug(Label* materialize_true, 5874a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label* materialize_false) const { 588a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(materialize_true == materialize_false); 5894a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ bind(materialize_true); 5904a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 591b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5924a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 5934a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::AccumulatorValueContext::Plug( 5944a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label* materialize_true, 5954a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label* materialize_false) const { 59683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 5974a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ bind(materialize_true); 598ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ Move(result_register(), isolate()->factory()->true_value()); 59983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&done, Label::kNear); 6004a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ bind(materialize_false); 601ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ Move(result_register(), isolate()->factory()->false_value()); 6024a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ bind(&done); 603b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 604b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 605b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 6064a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::StackValueContext::Plug( 6074a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label* materialize_true, 6084a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label* materialize_false) const { 60983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 6104a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ bind(materialize_true); 611ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ Push(isolate()->factory()->true_value()); 61283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&done, Label::kNear); 6134a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ bind(materialize_false); 614ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ Push(isolate()->factory()->false_value()); 6154a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ bind(&done); 6164a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 6174a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 6184a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 6194a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::TestContext::Plug(Label* materialize_true, 6204a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Label* materialize_false) const { 6214a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org ASSERT(materialize_true == true_label_); 622a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(materialize_false == false_label_); 6234a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 6244a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 6254a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 6264a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::EffectContext::Plug(bool flag) const { 6274a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 6284a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 6294a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 6304a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { 6314a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Heap::RootListIndex value_root_index = 6324a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; 6334a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ LoadRoot(result_register(), value_root_index); 6344a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 6354a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 6364a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 6374a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::StackValueContext::Plug(bool flag) const { 6384a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Heap::RootListIndex value_root_index = 6394a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; 6404a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org __ PushRoot(value_root_index); 6414a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 6424a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 6434a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 6444a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::TestContext::Plug(bool flag) const { 645c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org codegen()->PrepareForBailoutBeforeSplit(condition(), 646d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org true, 647d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org true_label_, 648d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org false_label_); 6494a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (flag) { 6504a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (true_label_ != fall_through_) __ jmp(true_label_); 6514a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } else { 6524a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (false_label_ != fall_through_) __ jmp(false_label_); 6539dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 6549dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 6559dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 6569dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 6576d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgvoid FullCodeGenerator::DoTest(Expression* condition, 6586d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org Label* if_true, 65965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* if_false, 66065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through) { 661b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); 662f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallIC(ic, condition->test_id()); 6637a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(result_register(), result_register()); 66465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // The stub returns nonzero for true. 66565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(not_zero, if_true, if_false, fall_through); 66665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org} 667b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 668b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 66965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgvoid FullCodeGenerator::Split(Condition cc, 67065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* if_true, 67165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* if_false, 67265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through) { 67365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (if_false == fall_through) { 67465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ j(cc, if_true); 67565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } else if (if_true == fall_through) { 67665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ j(NegateCondition(cc), if_false); 67765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } else { 67865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ j(cc, if_true); 67965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ jmp(if_false); 680b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 681b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 682b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 683b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 684486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.orgMemOperand FullCodeGenerator::StackOperand(Variable* var) { 685486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ASSERT(var->IsStackAllocated()); 686486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Offset is negative because higher indexes are at lower addresses. 687486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org int offset = -var->index() * kPointerSize; 688486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Adjust by a (parameter or local) base offset. 689486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (var->IsParameter()) { 690d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org offset += kFPOnStackSize + kPCOnStackSize + 691d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org (info_->scope()->num_parameters() - 1) * kPointerSize; 692486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } else { 693486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org offset += JavaScriptFrameConstants::kLocal0Offset; 694486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 695486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org return Operand(rbp, offset); 696486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org} 697486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 698486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 699486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.orgMemOperand FullCodeGenerator::VarOperand(Variable* var, Register scratch) { 700486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ASSERT(var->IsContextSlot() || var->IsStackAllocated()); 701486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (var->IsContextSlot()) { 702486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org int context_chain_length = scope()->ContextChainLength(var->scope()); 703486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ LoadContext(scratch, context_chain_length); 704486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org return ContextOperand(scratch, var->index()); 705486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } else { 706486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org return StackOperand(var); 707b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 708b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 709b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 710b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 711486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.orgvoid FullCodeGenerator::GetVar(Register dest, Variable* var) { 712486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ASSERT(var->IsContextSlot() || var->IsStackAllocated()); 713486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org MemOperand location = VarOperand(var, dest); 71443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(dest, location); 715b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 716b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 717b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 718486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.orgvoid FullCodeGenerator::SetVar(Variable* var, 719486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Register src, 720486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Register scratch0, 721486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Register scratch1) { 722486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ASSERT(var->IsContextSlot() || var->IsStackAllocated()); 723486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ASSERT(!scratch0.is(src)); 724486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ASSERT(!scratch0.is(scratch1)); 725486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ASSERT(!scratch1.is(src)); 726486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org MemOperand location = VarOperand(var, scratch0); 72743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(location, src); 728c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 729b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Emit the write barrier code if the location is in the heap. 730486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (var->IsContextSlot()) { 731486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org int offset = Context::SlotOffset(var->index()); 732c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ RecordWriteContextSlot(scratch0, offset, src, scratch1, kDontSaveFPRegs); 733b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 734b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 735b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 736b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 737c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, 738a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org bool should_normalize, 739a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Label* if_true, 740a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Label* if_false) { 741d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Only prepare for bailouts before splits if we're in a test 742d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // context. Otherwise, we let the Visit function deal with the 743d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // preparation to avoid preparing with the same AST id twice. 744d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org if (!context()->IsTest() || !info_->IsOptimizable()) return; 745d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 74683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label skip; 74783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (should_normalize) __ jmp(&skip, Label::kNear); 748c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailout(expr, TOS_REG); 749d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org if (should_normalize) { 750d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org __ CompareRoot(rax, Heap::kTrueValueRootIndex); 751d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org Split(equal, if_true, if_false, NULL); 752d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org __ bind(&skip); 753d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 754a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 755a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 756a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 757ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comvoid FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { 7588e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // The variable in the declaration always resides in the current context. 759ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); 760000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (generate_debug_code_) { 761ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // Check that we're not inside a with or catch context. 76243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, FieldOperand(rsi, HeapObject::kMapOffset)); 763ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com __ CompareRoot(rbx, Heap::kWithContextMapRootIndex); 764594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Check(not_equal, kDeclarationInWithContext); 765ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com __ CompareRoot(rbx, Heap::kCatchContextMapRootIndex); 766594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Check(not_equal, kDeclarationInCatchContext); 767ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 768ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com} 769ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 770ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 771ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comvoid FullCodeGenerator::VisitVariableDeclaration( 772ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VariableDeclaration* declaration) { 773486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // If it was not possible to allocate the variable at compile time, we 774486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // need to "declare" it at runtime to make sure it actually exists in the 775486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // local context. 776ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VariableProxy* proxy = declaration->proxy(); 777ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VariableMode mode = declaration->mode(); 7781805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Variable* variable = proxy->var(); 779486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY; 780486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org switch (variable->location()) { 781486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::UNALLOCATED: 7827028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org globals_->Add(variable->name(), zone()); 783ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com globals_->Add(variable->binding_needs_init() 784ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com ? isolate()->factory()->the_hole_value() 7857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org : isolate()->factory()->undefined_value(), 7867028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org zone()); 787486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org break; 788486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 789486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::PARAMETER: 790486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::LOCAL: 791ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if (hole_init) { 792ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Comment cmnt(masm_, "[ VariableDeclaration"); 79380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); 79443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(StackOperand(variable), kScratchRegister); 795b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 7964668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org break; 797b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 798486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::CONTEXT: 799ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if (hole_init) { 800ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Comment cmnt(masm_, "[ VariableDeclaration"); 801ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com EmitDebugCheckDeclarationContext(variable); 80280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); 80343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(ContextOperand(rsi, variable->index()), kScratchRegister); 80480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // No write barrier since the hole value is in old space. 8051805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 8064668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org } 8074668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org break; 808b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 809486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::LOOKUP: { 810ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Comment cmnt(masm_, "[ VariableDeclaration"); 811763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); 8124668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org __ Push(variable->name()); 813394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Declaration nodes are always introduced in one of four modes. 814355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org ASSERT(IsDeclaredVariableMode(mode)); 815394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com PropertyAttributes attr = 816355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org IsImmutableVariableMode(mode) ? READ_ONLY : NONE; 8174668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org __ Push(Smi::FromInt(attr)); 8184668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org // Push initial value, if any. 8194668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org // Note: For variables we must not push an initial value (such as 8204668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org // 'undefined') because we may have a (legal) redeclaration and we 8214668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org // must not destroy the current value. 822ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if (hole_init) { 82380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org __ PushRoot(Heap::kTheHoleValueRootIndex); 8244668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org } else { 825486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ Push(Smi::FromInt(0)); // Indicates no initial value. 8264668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org } 827895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenDeclareContextSlot, 4); 8284668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org break; 829b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 830b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 831b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 832b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 833b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 834ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comvoid FullCodeGenerator::VisitFunctionDeclaration( 835ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com FunctionDeclaration* declaration) { 836ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VariableProxy* proxy = declaration->proxy(); 837ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Variable* variable = proxy->var(); 838ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com switch (variable->location()) { 839ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com case Variable::UNALLOCATED: { 8407028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org globals_->Add(variable->name(), zone()); 841ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Handle<SharedFunctionInfo> function = 842ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Compiler::BuildFunctionInfo(declaration->fun(), script()); 843ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // Check for stack-overflow exception. 844ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if (function.is_null()) return SetStackOverflow(); 8457028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org globals_->Add(function, zone()); 846ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com break; 847ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 848ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 849ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com case Variable::PARAMETER: 850ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com case Variable::LOCAL: { 851ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Comment cmnt(masm_, "[ FunctionDeclaration"); 852ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VisitForAccumulatorValue(declaration->fun()); 85343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(StackOperand(variable), result_register()); 854ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com break; 855ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 856ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 857ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com case Variable::CONTEXT: { 858ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Comment cmnt(masm_, "[ FunctionDeclaration"); 859ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com EmitDebugCheckDeclarationContext(variable); 860ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VisitForAccumulatorValue(declaration->fun()); 86143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(ContextOperand(rsi, variable->index()), result_register()); 862ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com int offset = Context::SlotOffset(variable->index()); 863ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // We know that we have written a function, which is not a smi. 864ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com __ RecordWriteContextSlot(rsi, 865ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com offset, 866ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com result_register(), 867ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com rcx, 868ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com kDontSaveFPRegs, 869ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com EMIT_REMEMBERED_SET, 870ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com OMIT_SMI_CHECK); 871ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 872ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com break; 873ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 874ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 875ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com case Variable::LOOKUP: { 876ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Comment cmnt(masm_, "[ FunctionDeclaration"); 877763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); 878ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com __ Push(variable->name()); 879ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com __ Push(Smi::FromInt(NONE)); 880ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VisitForStackValue(declaration->fun()); 881895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenDeclareContextSlot, 4); 882ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com break; 883ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 884ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 885ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com} 886ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 887ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 888ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comvoid FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { 8898e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org Variable* variable = declaration->proxy()->var(); 8908e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org ASSERT(variable->location() == Variable::CONTEXT); 8918e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org ASSERT(variable->interface()->IsFrozen()); 8928e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 8938e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org Comment cmnt(masm_, "[ ModuleDeclaration"); 8948e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org EmitDebugCheckDeclarationContext(variable); 8958e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 8968e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // Load instance object. 8978e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org __ LoadContext(rax, scope_->ContextChainLength(scope_->GlobalScope())); 89843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, ContextOperand(rax, variable->interface()->Index())); 89943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, ContextOperand(rax, Context::EXTENSION_INDEX)); 9008e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 9018e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // Assign it. 90243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(ContextOperand(rsi, variable->index()), rax); 9038e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // We know that we have written a module, which is not a smi. 9048e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org __ RecordWriteContextSlot(rsi, 9058e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org Context::SlotOffset(variable->index()), 9068e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org rax, 9078e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org rcx, 9088e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org kDontSaveFPRegs, 9098e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org EMIT_REMEMBERED_SET, 9108e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org OMIT_SMI_CHECK); 9118e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org PrepareForBailoutForId(declaration->proxy()->id(), NO_REGISTERS); 9128e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 9138e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // Traverse into body. 9148e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org Visit(declaration->module()); 915ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com} 916ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 917ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 918ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comvoid FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { 919ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com VariableProxy* proxy = declaration->proxy(); 920ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Variable* variable = proxy->var(); 921ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com switch (variable->location()) { 922ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com case Variable::UNALLOCATED: 923ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // TODO(rossberg) 924ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com break; 925ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 926ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com case Variable::CONTEXT: { 927ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Comment cmnt(masm_, "[ ImportDeclaration"); 928ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com EmitDebugCheckDeclarationContext(variable); 929ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // TODO(rossberg) 930ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com break; 931ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 932ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 933ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com case Variable::PARAMETER: 934ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com case Variable::LOCAL: 935ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com case Variable::LOOKUP: 936ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com UNREACHABLE(); 937ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 938ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com} 939ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 940ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 941ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comvoid FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { 942ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // TODO(rossberg) 943ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com} 944ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 945ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 946b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 947b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Call the runtime to declare the globals. 948763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); // The context is the first argument. 949b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ Push(pairs); 9501805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org __ Push(Smi::FromInt(DeclareGlobalsFlags())); 951895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenDeclareGlobals, 3); 952b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Return value is ignored. 953b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 954b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 955b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 9568e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgvoid FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { 9578e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // Call the runtime to declare the modules. 9588e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org __ Push(descriptions); 959895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenDeclareModules, 1); 9608e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // Return value is ignored. 9618e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org} 9628e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 9638e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 9649dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comvoid FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 9659dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Comment cmnt(masm_, "[ SwitchStatement"); 9669dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Breakable nested_statement(this, stmt); 9679dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com SetStatementPosition(stmt); 968d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 9699dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Keep the switch value on the stack until a case matches. 9704a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(stmt->tag()); 971d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 9729dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 9739dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ZoneList<CaseClause*>* clauses = stmt->cases(); 9749dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com CaseClause* default_clause = NULL; // Can occur anywhere in the list. 9759dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 9769dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label next_test; // Recycled for each test. 9779dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Compile all the tests with branches to their bodies. 9789dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com for (int i = 0; i < clauses->length(); i++) { 9799dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com CaseClause* clause = clauses->at(i); 98044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org clause->body_target()->Unuse(); 981d218783b5ca3a9706b143874e9372e469f3e6f71fschneider@chromium.org 9829dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // The default is not a test, but remember it as final fall through. 9839dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com if (clause->is_default()) { 9849dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com default_clause = clause; 9859dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com continue; 9869dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 9879dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 9889dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Comment cmnt(masm_, "[ Case comparison"); 9899dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&next_test); 9909dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com next_test.Unuse(); 9919dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 9929dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Compile the label expression. 9934a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(clause->label()); 9949dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 99565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Perform the comparison as if via '==='. 99643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, Operand(rsp, 0)); // Switch value. 997d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com bool inline_smi_code = ShouldInlineSmiCase(Token::EQ_STRICT); 998d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com JumpPatchSite patch_site(masm_); 999d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (inline_smi_code) { 100083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label slow_case; 100143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, rdx); 1002895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ orp(rcx, rax); 100383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); 1004d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 10057a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rdx, rax); 100665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ j(not_equal, &next_test); 100765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ Drop(1); // Switch value is no longer needed. 100844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org __ jmp(clause->body_target()); 100965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ bind(&slow_case); 101065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } 10119dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 1012d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // Record position before stub call for type feedback. 1013d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com SetSourcePosition(clause->position()); 10148432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); 1015f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallIC(ic, clause->CompareId()); 10164f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org patch_site.EmitPatchInfo(); 1017d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 10184f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org Label skip; 10194f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org __ jmp(&skip, Label::kNear); 10204f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org PrepareForBailout(clause, TOS_REG); 10214f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org __ CompareRoot(rax, Heap::kTrueValueRootIndex); 10224f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org __ j(not_equal, &next_test); 10234f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org __ Drop(1); 10244f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org __ jmp(clause->body_target()); 10254f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org __ bind(&skip); 10264f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org 10277a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rax, rax); 10289dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ j(not_equal, &next_test); 10299dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ Drop(1); // Switch value is no longer needed. 103044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org __ jmp(clause->body_target()); 10319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 10329dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 10339dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Discard the test value and jump to the default if present, otherwise to 10349dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // the end of the statement. 10359dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&next_test); 10369dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ Drop(1); // Switch value is no longer needed. 10379dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com if (default_clause == NULL) { 103828a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org __ jmp(nested_statement.break_label()); 10399dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } else { 104044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org __ jmp(default_clause->body_target()); 10419dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 10429dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 10439dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Compile all the case bodies. 10449dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com for (int i = 0; i < clauses->length(); i++) { 10459dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Comment cmnt(masm_, "[ Case body"); 10469dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com CaseClause* clause = clauses->at(i); 104744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org __ bind(clause->body_target()); 10484d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); 10499dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com VisitStatements(clause->statements()); 10509dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 10519dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 105228a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org __ bind(nested_statement.break_label()); 1053d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 10549dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 10559dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 10569dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 10579dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comvoid FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 10589dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Comment cmnt(masm_, "[ ForInStatement"); 1059f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int slot = stmt->ForInFeedbackSlot(); 10609dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com SetStatementPosition(stmt); 10619dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 10629dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label loop, exit; 10639dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ForIn loop_statement(this, stmt); 10649dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com increment_loop_depth(); 10659dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 10661fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // Get the object to enumerate over. If the object is null or undefined, skip 10671fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // over the loop. See ECMA-262 version 5, section 12.6.4. 10684a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(stmt->enumerable()); 10699dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 10709dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ j(equal, &exit); 10715d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org Register null_value = rdi; 10725d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ LoadRoot(null_value, Heap::kNullValueRootIndex); 10737a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rax, null_value); 10749dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ j(equal, &exit); 10759dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 1076be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); 1077be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 10789dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Convert the object to a JS object. 10799dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label convert, done_convert; 10809dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ JumpIfSmi(rax, &convert); 1081d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx); 10829dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ j(above_equal, &done_convert); 10839dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&convert); 1084763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 10859dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 10869dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&done_convert); 1087763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 10889dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 1089394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Check for proxies. 1090394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label call_runtime; 1091394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 1092394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ CmpObjectType(rax, LAST_JS_PROXY_TYPE, rcx); 1093394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ j(below_equal, &call_runtime); 1094394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 10955d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Check cache validity in generated code. This is a fast case for 10965d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // the JSObject::IsSimpleEnum cache validity checks. If we cannot 10975d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // guarantee cache validity, call the runtime system to check cache 10985d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // validity or get the property names in a fixed array. 1099be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org __ CheckEnumCache(null_value, &call_runtime); 11005d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 11015d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // The enum cache is valid. Load the map of the object being 11025d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // iterated over and use the cache for the iteration. 110383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label use_cache; 110443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, FieldOperand(rax, HeapObject::kMapOffset)); 110583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&use_cache, Label::kNear); 11069dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 11079dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Get the set of properties to enumerate. 11085d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ bind(&call_runtime); 1109763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // Duplicate the enumerable object on the stack. 11109dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CallRuntime(Runtime::kGetPropertyNamesFast, 1); 11119dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 11129dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // If we got a map from the runtime call, we can do a fast 11139dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // modification check. Otherwise, we got a fixed array, and we have 11149dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // to do a slow check. 111583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label fixed_array; 11169dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), 11179dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Heap::kMetaMapRootIndex); 1118355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ j(not_equal, &fixed_array); 11199dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 11209dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // We got a map in register rax. Get the enumeration cache from it. 11215d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org __ bind(&use_cache); 1122355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 1123355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Label no_descriptors; 1124355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 1125355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ EnumLength(rdx, rax); 1126355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ Cmp(rdx, Smi::FromInt(0)); 1127355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ j(equal, &no_descriptors); 1128355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 112940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org __ LoadInstanceDescriptors(rax, rcx); 113043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, FieldOperand(rcx, DescriptorArray::kEnumCacheOffset)); 113143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, FieldOperand(rcx, DescriptorArray::kEnumCacheBridgeCacheOffset)); 11329dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 1133f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up the four remaining stack slots. 1134763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // Map. 1135763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rcx); // Enumeration cache. 1136763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rdx); // Number of valid entries for the map in the enum cache. 11379dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ Push(Smi::FromInt(0)); // Initial index. 11389dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ jmp(&loop); 11399dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 1140355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ bind(&no_descriptors); 1141fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rsp, Immediate(kPointerSize)); 1142355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org __ jmp(&exit); 1143355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 11449dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // We got a fixed array in register rax. Iterate through that. 1145394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label non_proxy; 11469dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&fixed_array); 11479a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 1148f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // No need for a write barrier, we are storing a Smi in the feedback vector. 1149f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ Move(rbx, FeedbackVector()); 1150f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ Move(FieldOperand(rbx, FixedArray::OffsetOfElementAt(slot)), 1151a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org TypeFeedbackInfo::MegamorphicSentinel(isolate())); 1152394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Move(rbx, Smi::FromInt(1)); // Smi indicates slow check 115343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, Operand(rsp, 0 * kPointerSize)); // Get enumerated object 1154394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 1155394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ CmpObjectType(rcx, LAST_JS_PROXY_TYPE, rcx); 1156394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ j(above, &non_proxy); 1157394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Move(rbx, Smi::FromInt(0)); // Zero indicates proxy 1158394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&non_proxy); 1159763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rbx); // Smi 1160763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // Array 116143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, FieldOperand(rax, FixedArray::kLengthOffset)); 1162763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // Fixed array length (as smi). 11639dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ Push(Smi::FromInt(0)); // Initial index. 11649dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 11659dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Generate code for doing the condition check. 1166be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 11679dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&loop); 116843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, Operand(rsp, 0 * kPointerSize)); // Get the current index. 11697a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rax, Operand(rsp, 1 * kPointerSize)); // Compare to the array length. 117028a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org __ j(above_equal, loop_statement.break_label()); 11719dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 11729dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Get the current entry of the array into register rbx. 117343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, Operand(rsp, 2 * kPointerSize)); 1174eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org SmiIndex index = masm()->SmiToIndex(rax, rax, kPointerSizeLog2); 117543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, FieldOperand(rbx, 11769dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com index.reg, 11779dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com index.scale, 11789dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com FixedArray::kHeaderSize)); 11799dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 1180394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Get the expected map from the stack or a smi in the 11819dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // permanent slow case into register rdx. 118243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, Operand(rsp, 3 * kPointerSize)); 11839dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 11849dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Check if the expected map still matches that of the enumerable. 1185394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // If not, we may have to filter the key. 118683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label update_each; 118743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, Operand(rsp, 4 * kPointerSize)); 11887a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rdx, FieldOperand(rcx, HeapObject::kMapOffset)); 118983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(equal, &update_each, Label::kNear); 11909dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 1191394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // For proxies, no filtering is done. 1192394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // TODO(rossberg): What if only a prototype is a proxy? Not specified yet. 1193394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Cmp(rdx, Smi::FromInt(0)); 1194394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ j(equal, &update_each, Label::kNear); 1195394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 11969dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Convert the entry to a string or null if it isn't a property 11979dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // anymore. If the property has been removed while iterating, we 11989dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // just skip it. 1199763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rcx); // Enumerable. 1200763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rbx); // Current entry. 12019dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); 1202badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ Cmp(rax, Smi::FromInt(0)); 120328a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org __ j(equal, loop_statement.continue_label()); 120443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, rax); 12059dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 12069dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Update the 'each' property or variable from the possibly filtered 12079dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // entry in register rbx. 12089dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&update_each); 120943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result_register(), rbx); 12109dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Perform the assignment as if via '='. 12115f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org { EffectContext context(this); 1212be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org EmitAssignment(stmt->each()); 12135f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 12149dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 12159dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Generate code for the body of the loop. 12169dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Visit(stmt->body()); 12179dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 12189dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Generate code for going to the next element by incrementing the 12199dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // index (smi) stored on top of the stack. 122028a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org __ bind(loop_statement.continue_label()); 12219dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ SmiAddConstant(Operand(rsp, 0 * kPointerSize), Smi::FromInt(1)); 12229dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 1223cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org EmitBackEdgeBookkeeping(stmt, &loop); 1224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ jmp(&loop); 12259dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 12269dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Remove the pointers stored on the stack. 122728a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org __ bind(loop_statement.break_label()); 1228fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rsp, Immediate(5 * kPointerSize)); 12299dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 12309dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Exit and decrement the loop depth. 1231be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 12329dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&exit); 12339dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com decrement_loop_depth(); 12349dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 1235b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1236b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 12371fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgvoid FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { 12381fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Comment cmnt(masm_, "[ ForOfStatement"); 12391fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org SetStatementPosition(stmt); 12401fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 12411fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Iteration loop_statement(this, stmt); 12421fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org increment_loop_depth(); 12431fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 12441845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // var iterable = subject 12451845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org VisitForAccumulatorValue(stmt->assign_iterable()); 12461fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 12471845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // As with for-in, skip the loop if the iterable is null or undefined. 12481fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 12491fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org __ j(equal, loop_statement.break_label()); 12501fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org __ CompareRoot(rax, Heap::kNullValueRootIndex); 12511fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org __ j(equal, loop_statement.break_label()); 12521fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 12531845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // var iterator = iterable[Symbol.iterator](); 12541845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org VisitForEffect(stmt->assign_iterator()); 12551fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 12561fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // Loop entry. 12571fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org __ bind(loop_statement.continue_label()); 12581fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 12591fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // result = iterator.next() 12601fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org VisitForEffect(stmt->next_result()); 12611fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 12621fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // if (result.done) break; 12631fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Label result_not_done; 12641fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org VisitForControl(stmt->result_done(), 12651fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org loop_statement.break_label(), 12661fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org &result_not_done, 12671fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org &result_not_done); 12681fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org __ bind(&result_not_done); 12691fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 12701fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // each = result.value 12711fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org VisitForEffect(stmt->assign_each()); 12721fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 12731fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // Generate code for the body of the loop. 12741fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org Visit(stmt->body()); 12751fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 12761fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // Check stack before looping. 12771fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); 12781fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label()); 12791fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org __ jmp(loop_statement.continue_label()); 12801fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 12811fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org // Exit and decrement the loop depth. 12821fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 12831fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org __ bind(loop_statement.break_label()); 12841fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org decrement_loop_depth(); 12851fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org} 12861fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 12871fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org 128821b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.orgvoid FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 128921b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org bool pretenure) { 12909dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Use the fast case closure allocation code that allocates in new 12915d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // space for nested functions that don't need literals cloning. If 12925d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // we're running with the --always-opt or the --prepare-always-opt 12935d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // flag, we need to use the runtime function so that the new function 12945d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // we are creating here gets a chance to have its code optimized and 12955d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // doesn't just get a copy of the existing unoptimized code. 12965d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org if (!FLAG_always_opt && 12975d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org !FLAG_prepare_always_opt && 1298ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org !pretenure && 12995d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org scope()->is_function_scope() && 1300ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org info->num_literals() == 0) { 1301f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org FastNewClosureStub stub(isolate(), 1302f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org info->strict_mode(), 1303f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org info->is_generator()); 1304662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ Move(rbx, info); 13059dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CallStub(&stub); 13069dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } else { 1307763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); 13089dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ Push(info); 1309ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ Push(pretenure 1310ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ? isolate()->factory()->true_value() 1311ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org : isolate()->factory()->false_value()); 1312895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenNewClosure, 3); 13139dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 13144a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 1315b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 1316b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1317b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1318b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 1319b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Comment cmnt(masm_, "[ VariableProxy"); 1320030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org EmitVariableLoad(expr); 1321b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 1322b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1323b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1324486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.orgvoid FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, 1325486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org TypeofState typeof_state, 1326486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Label* slow) { 13272ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org Register context = rsi; 13282ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org Register temp = rdx; 13292ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 13302ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org Scope* s = scope(); 13312ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org while (s != NULL) { 13322ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org if (s->num_heap_slots() > 0) { 1333486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (s->calls_sloppy_eval()) { 13342ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // Check that extension is NULL. 13357a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(ContextOperand(context, Context::EXTENSION_INDEX), 13362ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org Immediate(0)); 13372ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org __ j(not_equal, slow); 13382ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org } 13392ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // Load next context in chain. 134043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(temp, ContextOperand(context, Context::PREVIOUS_INDEX)); 13412ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // Walk the rest of the chain without clobbering rsi. 13422ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org context = temp; 13432ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org } 13442ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // If no outer scope calls eval, we do not need to check more 13452ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // context extensions. If we have reached an eval scope, we check 13462ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // all extensions from this point. 1347486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break; 13482ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org s = s->outer_scope(); 13492ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org } 13502ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 13512ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org if (s != NULL && s->is_eval_scope()) { 13522ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // Loop up the context chain. There is no frame effect so it is 13532ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // safe to use raw labels here. 135483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label next, fast; 13552ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org if (!context.is(temp)) { 135643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(temp, context); 13572ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org } 13582ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // Load map for comparison into register, outside loop. 135946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ LoadRoot(kScratchRegister, Heap::kNativeContextMapRootIndex); 13602ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org __ bind(&next); 136146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Terminate at native context. 13627a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(kScratchRegister, FieldOperand(temp, HeapObject::kMapOffset)); 136383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(equal, &fast, Label::kNear); 13642ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // Check that extension is NULL. 13657a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); 13662ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org __ j(not_equal, slow); 13672ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // Load next context in chain. 136843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); 13692ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org __ jmp(&next); 13702ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org __ bind(&fast); 13712ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org } 13722ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 13732ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // All extension objects were empty and it is safe to use a global 13742ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // load IC call. 137543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, GlobalObjectOperand()); 1376486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ Move(rcx, var->name()); 13779cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org ContextualMode mode = (typeof_state == INSIDE_TYPEOF) 13789cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org ? NOT_CONTEXTUAL 13799cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org : CONTEXTUAL; 13809cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org CallLoadIC(mode); 13812ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org} 13822ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 13832ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 1384486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.orgMemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, 1385486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Label* slow) { 1386486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ASSERT(var->IsContextSlot()); 13872ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org Register context = rsi; 13882ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org Register temp = rbx; 13892ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 1390486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { 13912ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org if (s->num_heap_slots() > 0) { 1392486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (s->calls_sloppy_eval()) { 13932ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // Check that extension is NULL. 13947a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(ContextOperand(context, Context::EXTENSION_INDEX), 13952ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org Immediate(0)); 13962ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org __ j(not_equal, slow); 13972ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org } 139843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(temp, ContextOperand(context, Context::PREVIOUS_INDEX)); 13992ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // Walk the rest of the chain without clobbering rsi. 14002ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org context = temp; 14012ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org } 14022ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org } 14032ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // Check that last extension is NULL. 14047a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(ContextOperand(context, Context::EXTENSION_INDEX), Immediate(0)); 14052ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org __ j(not_equal, slow); 14065d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 14075d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // This function is used only for loads, not stores, so it's safe to 14085d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // return an rsi-based operand (the write barrier cannot be allowed to 14095d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // destroy the rsi register). 1410486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org return ContextOperand(context, var->index()); 14112ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org} 14122ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 14132ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 1414486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.orgvoid FullCodeGenerator::EmitDynamicLookupFastCase(Variable* var, 1415486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org TypeofState typeof_state, 1416486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Label* slow, 1417486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Label* done) { 14182ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // Generate fast-case code for variables that might be shadowed by 14192ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // eval-introduced variables. Eval is used a lot without 14202ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // introducing variables. In those cases, we do not want to 14212ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // perform a runtime call for all variables in the scope 14222ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // containing the eval. 1423b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org if (var->mode() == DYNAMIC_GLOBAL) { 1424486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org EmitLoadGlobalCheckExtensions(var, typeof_state, slow); 14252ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org __ jmp(done); 1426b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org } else if (var->mode() == DYNAMIC_LOCAL) { 1427486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Variable* local = var->local_if_not_shadowed(); 142843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, ContextSlotOperandCheckExtensions(local, slow)); 1429486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (local->mode() == LET || local->mode() == CONST || 1430486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org local->mode() == CONST_LEGACY) { 1431486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); 1432486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ j(not_equal, done); 1433486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (local->mode() == CONST_LEGACY) { 1434a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 1435486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org } else { // LET || CONST 1436a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org __ Push(var->name()); 1437895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); 1438a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org } 14392ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org } 1440486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ jmp(done); 14412ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org } 14422ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org} 14432ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 14442ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 1445030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.orgvoid FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { 1446030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org // Record position before possible IC call. 1447030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org SetSourcePosition(proxy->position()); 1448030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org Variable* var = proxy->var(); 1449030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org 1450486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Three cases: global variables, lookup variables, and all other types of 1451486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // variables. 1452486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org switch (var->location()) { 1453486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::UNALLOCATED: { 1454f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Comment cmnt(masm_, "[ Global variable"); 1455486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Use inline caching. Variable name is passed in rcx and the global 1456486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // object on the stack. 1457486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ Move(rcx, var->name()); 145843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, GlobalObjectOperand()); 14599cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org CallLoadIC(CONTEXTUAL); 1460486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org context()->Plug(rax); 1461486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org break; 1462486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 14632ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 1464486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::PARAMETER: 1465486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::LOCAL: 1466486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::CONTEXT: { 1467f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot" 1468f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org : "[ Stack slot"); 1469c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org if (var->binding_needs_init()) { 1470c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // var->scope() may be NULL when the proxy is located in eval code and 1471c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // refers to a potential outside binding. Currently those bindings are 1472c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // always looked up dynamically, i.e. in that case 1473c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // var->location() == LOOKUP. 1474c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // always holds. 1475c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org ASSERT(var->scope() != NULL); 1476c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 1477c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Check if the binding really needs an initialization check. The check 1478c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // can be skipped in the following situation: we have a LET or CONST 1479c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // binding in harmony mode, both the Variable and the VariableProxy have 1480c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // the same declaration scope (i.e. they are both in global code, in the 1481c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // same function or in the same eval code) and the VariableProxy is in 1482c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // the source physically located after the initializer of the variable. 1483c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // 1484c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // We cannot skip any initialization checks for CONST in non-harmony 1485c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // mode because const variables may be declared but never initialized: 1486c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // if (false) { const x; }; var y = x; 1487c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // 1488c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // The condition on the declaration scopes is a conservative check for 1489c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // nested functions that access a binding and are called before the 1490c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // binding is initialized: 1491c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // function() { f(); let x = 1; function f() { x = 2; } } 1492c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // 1493c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org bool skip_init_check; 1494c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) { 1495c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org skip_init_check = false; 1496ac45fedf88208de9636b896863f0942bae969d67jkummerow@chromium.org } else { 1497c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Check that we always have valid source position. 1498c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org ASSERT(var->initializer_position() != RelocInfo::kNoPosition); 1499c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org ASSERT(proxy->position() != RelocInfo::kNoPosition); 1500486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org skip_init_check = var->mode() != CONST_LEGACY && 1501c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org var->initializer_position() < proxy->position(); 1502c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org } 1503c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 1504c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org if (!skip_init_check) { 1505c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Let and const need a read barrier. 1506c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Label done; 1507c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org GetVar(rax, var); 1508c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); 1509c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org __ j(not_equal, &done, Label::kNear); 1510486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (var->mode() == LET || var->mode() == CONST) { 1511c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Throw a reference error when using an uninitialized let/const 1512c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // binding in harmony mode. 1513c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org __ Push(var->name()); 1514895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); 1515c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org } else { 1516c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Uninitalized const bindings outside of harmony mode are unholed. 1517486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org ASSERT(var->mode() == CONST_LEGACY); 1518c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 1519c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org } 1520c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org __ bind(&done); 1521c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org context()->Plug(rax); 1522c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org break; 1523486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 1524486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 1525c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org context()->Plug(var); 1526486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org break; 1527486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 1528b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1529486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org case Variable::LOOKUP: { 1530f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Comment cmnt(masm_, "[ Lookup slot"); 1531486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Label done, slow; 1532486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Generate code for loading from variables potentially shadowed 1533486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // by eval-introduced variables. 1534486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); 1535486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ bind(&slow); 1536763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); // Context. 153780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org __ Push(var->name()); 1538895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenLoadContextSlot, 2); 153980c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org __ bind(&done); 154080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org context()->Plug(rax); 1541486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org break; 15429dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 1543b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 1544b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 1545b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1546b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1547b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1548b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Comment cmnt(masm_, "[ RegExpLiteral"); 1549c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Label materialized; 1550b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Registers will be used as follows: 1551b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // rdi = JS function. 1552c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // rcx = literals array. 1553c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // rbx = regexp literal. 1554c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // rax = regexp literal clone. 155543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 155643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, FieldOperand(rdi, JSFunction::kLiteralsOffset)); 1557b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int literal_offset = 155865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; 155943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, FieldOperand(rcx, literal_offset)); 1560c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex); 1561486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ j(not_equal, &materialized, Label::kNear); 1562c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org 1563b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Create regexp literal using runtime function 1564b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Result will be in rax. 1565763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rcx); 1566b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ Push(Smi::FromInt(expr->literal_index())); 1567b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ Push(expr->pattern()); 1568b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ Push(expr->flags()); 1569895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenMaterializeRegExpLiteral, 4); 157043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, rax); 1571c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org 1572c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org __ bind(&materialized); 1573c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; 1574c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Label allocated, runtime_allocate; 15752bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ Allocate(size, rax, rcx, rdx, &runtime_allocate, TAG_OBJECT); 1576c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org __ jmp(&allocated); 1577c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org 1578c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org __ bind(&runtime_allocate); 1579763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rbx); 1580c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org __ Push(Smi::FromInt(size)); 1581895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1); 1582763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rbx); 1583c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org 1584c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org __ bind(&allocated); 1585c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // Copy the content into the newly allocated memory. 1586c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org // (Unroll copy loop once for better throughput). 1587c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) { 158843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, FieldOperand(rbx, i)); 158943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, FieldOperand(rbx, i + kPointerSize)); 159043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rax, i), rdx); 159143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rax, i + kPointerSize), rcx); 1592c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } 1593c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org if ((size % (2 * kPointerSize)) != 0) { 159443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, FieldOperand(rbx, size - kPointerSize)); 159543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rax, size - kPointerSize), rdx); 1596c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } 15974a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 1598b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 1599b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1600b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 16012c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.orgvoid FullCodeGenerator::EmitAccessor(Expression* expression) { 16022c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org if (expression == NULL) { 16032c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org __ PushRoot(Heap::kNullValueRootIndex); 16042c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org } else { 16052c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org VisitForStackValue(expression); 16062c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org } 16072c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org} 16082c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org 16092c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org 1610b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 1611b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Comment cmnt(masm_, "[ ObjectLiteral"); 1612e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 16137ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org expr->BuildConstantProperties(isolate()); 1614f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org Handle<FixedArray> constant_properties = expr->constant_properties(); 1615ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int flags = expr->fast_elements() 1616ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ? ObjectLiteral::kFastElements 1617ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org : ObjectLiteral::kNoFlags; 1618ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org flags |= expr->has_function() 1619ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ? ObjectLiteral::kHasFunction 1620ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org : ObjectLiteral::kNoFlags; 1621f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org int properties_count = constant_properties->length() / 2; 1622a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (expr->may_store_doubles() || expr->depth() > 1 || 1623874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org masm()->serializer_enabled() || flags != ObjectLiteral::kFastElements || 1624f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { 162543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 1626763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(FieldOperand(rdi, JSFunction::kLiteralsOffset)); 162771fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org __ Push(Smi::FromInt(expr->literal_index())); 162871fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org __ Push(constant_properties); 162971fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org __ Push(Smi::FromInt(flags)); 1630895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4); 1631f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org } else { 163243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 163343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, FieldOperand(rdi, JSFunction::kLiteralsOffset)); 163471fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org __ Move(rbx, Smi::FromInt(expr->literal_index())); 163571fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org __ Move(rcx, constant_properties); 163671fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org __ Move(rdx, Smi::FromInt(flags)); 1637f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org FastCloneShallowObjectStub stub(isolate(), properties_count); 1638f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org __ CallStub(&stub); 1639b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 1640b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1641b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // If result_saved is true the result is on top of the stack. If 1642b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // result_saved is false the result is in rax. 1643b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org bool result_saved = false; 1644b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1645e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org // Mark all computed expressions that are bound to a key that 1646e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org // is shadowed by a later occurrence of the same key. For the 1647e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org // marked expressions, no store code is emitted. 16487028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org expr->CalculateEmitStore(zone()); 1649e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org 16505a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org AccessorTable accessor_table(zone()); 1651b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org for (int i = 0; i < expr->properties()->length(); i++) { 1652b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ObjectLiteral::Property* property = expr->properties()->at(i); 1653b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (property->IsCompileTimeValue()) continue; 1654b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1655b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Literal* key = property->key(); 1656b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Expression* value = property->value(); 1657b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (!result_saved) { 1658763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // Save result on the stack 1659b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org result_saved = true; 1660b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 1661b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org switch (property->kind()) { 1662b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org case ObjectLiteral::Property::CONSTANT: 1663b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org UNREACHABLE(); 1664b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1665b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 1666b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Fall through. 1667b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org case ObjectLiteral::Property::COMPUTED: 16681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (key->value()->IsInternalizedString()) { 1669e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org if (property->emit_store()) { 167040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org VisitForAccumulatorValue(value); 16711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Move(rcx, key->value()); 167243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, Operand(rsp, 0)); 1673f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallStoreIC(key->LiteralFeedbackId()); 1674d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org PrepareForBailoutForId(key->id(), NO_REGISTERS); 167540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org } else { 167640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org VisitForEffect(value); 1677e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org } 1678b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org break; 1679b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 1680763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Operand(rsp, 0)); // Duplicate receiver. 16814a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(key); 16824a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(value); 1683e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org if (property->emit_store()) { 16849ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org __ Push(Smi::FromInt(NONE)); // PropertyAttributes 16859ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org __ CallRuntime(Runtime::kSetProperty, 4); 1686e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org } else { 1687e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org __ Drop(3); 1688e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org } 1689b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org break; 1690750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org case ObjectLiteral::Property::PROTOTYPE: 1691763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Operand(rsp, 0)); // Duplicate receiver. 1692750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org VisitForStackValue(value); 1693750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (property->emit_store()) { 1694750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org __ CallRuntime(Runtime::kSetPrototype, 2); 1695750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } else { 1696750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org __ Drop(2); 1697750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 1698750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org break; 1699b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org case ObjectLiteral::Property::GETTER: 17002c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org accessor_table.lookup(key)->second->getter = value; 17012c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org break; 17022c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org case ObjectLiteral::Property::SETTER: 17032c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org accessor_table.lookup(key)->second->setter = value; 1704b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org break; 1705b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 1706b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 1707b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 17082c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // Emit code to define accessors, using only a single call to the runtime for 17092c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org // each pair of corresponding getters and setters. 17102c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org for (AccessorTable::Iterator it = accessor_table.begin(); 17112c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org it != accessor_table.end(); 17122c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org ++it) { 1713763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Operand(rsp, 0)); // Duplicate receiver. 17142c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org VisitForStackValue(it->first); 17152c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org EmitAccessor(it->second->getter); 17162c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org EmitAccessor(it->second->setter); 17172c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org __ Push(Smi::FromInt(NONE)); 17182c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org __ CallRuntime(Runtime::kDefineOrRedefineAccessorProperty, 5); 17192c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org } 17202c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org 1721ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (expr->has_function()) { 1722ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(result_saved); 1723763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Operand(rsp, 0)); 1724ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ CallRuntime(Runtime::kToFastProperties, 1); 1725ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 1726ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1727b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (result_saved) { 17284a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PlugTOS(); 1729b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 17304a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 1731b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 1732b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 1733b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1734b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1735b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 1736b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Comment cmnt(masm_, "[ ArrayLiteral"); 17379dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 17387ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org expr->BuildConstantElements(isolate()); 173937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org int flags = expr->depth() == 1 174037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org ? ArrayLiteral::kShallowElements 174137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org : ArrayLiteral::kNoFlags; 174237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 17439dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ZoneList<Expression*>* subexprs = expr->values(); 17449dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com int length = subexprs->length(); 1745394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<FixedArray> constant_elements = expr->constant_elements(); 1746394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT_EQ(2, constant_elements->length()); 1747394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ElementsKind constant_elements_kind = 1748394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value()); 1749830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org bool has_constant_fast_elements = 1750830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org IsFastObjectElementsKind(constant_elements_kind); 1751394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<FixedArrayBase> constant_elements_values( 1752394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com FixedArrayBase::cast(constant_elements->get(1))); 17539dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 17549cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org AllocationSiteMode allocation_site_mode = TRACK_ALLOCATION_SITE; 1755c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org if (has_constant_fast_elements && !FLAG_allocation_site_pretenuring) { 1756c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org // If the only customer of allocation sites is transitioning, then 1757c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org // we can turn it off if we don't have anywhere else to transition to. 1758c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; 1759c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org } 1760c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org 1761e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org if (expr->depth() > 1 || length > JSObject::kInitialMaxFastElementArray) { 176243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 1763763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(FieldOperand(rbx, JSFunction::kLiteralsOffset)); 1764e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ Push(Smi::FromInt(expr->literal_index())); 1765e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ Push(constant_elements); 176637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org __ Push(Smi::FromInt(flags)); 1767895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4); 17689dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } else { 176943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 177043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, FieldOperand(rbx, JSFunction::kLiteralsOffset)); 1771e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ Move(rbx, Smi::FromInt(expr->literal_index())); 1772e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ Move(rcx, constant_elements); 1773a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); 17749dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CallStub(&stub); 1775b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 1776b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1777b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org bool result_saved = false; // Is the result saved to the stack? 1778b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1779b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Emit code to evaluate all the non-constant subexpressions and to store 1780b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // them into the newly cloned array. 17819dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com for (int i = 0; i < length; i++) { 1782b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Expression* subexpr = subexprs->at(i); 1783b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // If the subexpression is a literal or a simple materialized literal it 1784b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // is already set in the cloned array. 17851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1786b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1787b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (!result_saved) { 1788763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // array literal 1789b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Push(Smi::FromInt(expr->literal_index())); 1790b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org result_saved = true; 1791b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 17924a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(subexpr); 1793b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1794830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (IsFastObjectElementsKind(constant_elements_kind)) { 1795830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org // Fast-case array literal with ElementsKind of FAST_*_ELEMENTS, they 1796830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org // cannot transition and don't need to call the runtime stub. 17971b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int offset = FixedArray::kHeaderSize + (i * kPointerSize); 179843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, Operand(rsp, kPointerSize)); // Copy of array literal. 179943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, FieldOperand(rbx, JSObject::kElementsOffset)); 18001b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Store the subexpression value in the array's elements. 180143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rbx, offset), result_register()); 18021b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Update the write barrier for the array store. 18031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ RecordWriteField(rbx, offset, result_register(), rcx, 18041b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org kDontSaveFPRegs, 18051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org EMIT_REMEMBERED_SET, 18061b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org INLINE_SMI_CHECK); 18071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } else { 18081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Store the subexpression value in the array's elements. 18091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ Move(rcx, Smi::FromInt(i)); 1810f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org StoreArrayLiteralElementStub stub(isolate()); 18111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ CallStub(&stub); 18121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 1813d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 1814d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); 1815b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 1816b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1817b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (result_saved) { 1818fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rsp, Immediate(kPointerSize)); // literal index 18194a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PlugTOS(); 1820b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 18214a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 1822b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 1823b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 1824b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1825b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 18265c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid FullCodeGenerator::VisitAssignment(Assignment* expr) { 18274edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org ASSERT(expr->target()->IsValidReferenceExpression()); 18282904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org 18295c838251403b0be9a882540f1922577abba4c872ager@chromium.org Comment cmnt(masm_, "[ Assignment"); 18309dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 18315c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Left-hand side can only be a property, a global or a (parameter or local) 18327b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // slot. 18335c838251403b0be9a882540f1922577abba4c872ager@chromium.org enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 18345c838251403b0be9a882540f1922577abba4c872ager@chromium.org LhsKind assign_type = VARIABLE; 1835d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Property* property = expr->target()->AsProperty(); 1836d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org if (property != NULL) { 1837d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org assign_type = (property->key()->IsPropertyName()) 1838d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org ? NAMED_PROPERTY 1839d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org : KEYED_PROPERTY; 18405c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 18415c838251403b0be9a882540f1922577abba4c872ager@chromium.org 18425c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Evaluate LHS expression. 18435c838251403b0be9a882540f1922577abba4c872ager@chromium.org switch (assign_type) { 18445c838251403b0be9a882540f1922577abba4c872ager@chromium.org case VARIABLE: 18455c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Nothing to do here. 18465c838251403b0be9a882540f1922577abba4c872ager@chromium.org break; 18475c838251403b0be9a882540f1922577abba4c872ager@chromium.org case NAMED_PROPERTY: 18485c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (expr->is_compound()) { 18495c838251403b0be9a882540f1922577abba4c872ager@chromium.org // We need the receiver both on the stack and in the accumulator. 18504a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(property->obj()); 1851763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(result_register()); 18525c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else { 18534a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(property->obj()); 18545c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 18555c838251403b0be9a882540f1922577abba4c872ager@chromium.org break; 1856d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org case KEYED_PROPERTY: { 18579dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com if (expr->is_compound()) { 18587b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org VisitForStackValue(property->obj()); 18597b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org VisitForAccumulatorValue(property->key()); 186043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, Operand(rsp, 0)); 1861763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 18629dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } else { 18637b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org VisitForStackValue(property->obj()); 18647b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org VisitForStackValue(property->key()); 18659dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 18665c838251403b0be9a882540f1922577abba4c872ager@chromium.org break; 1867d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 18685c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 18695c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1870c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // For compound assignments we need another deoptimization point after the 1871c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // variable/property load. 18725c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (expr->is_compound()) { 18734a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org { AccumulatorValueContext context(this); 18744a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org switch (assign_type) { 18754a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org case VARIABLE: 1876030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org EmitVariableLoad(expr->target()->AsVariableProxy()); 1877c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org PrepareForBailout(expr->target(), TOS_REG); 18784a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org break; 18794a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org case NAMED_PROPERTY: 18804a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org EmitNamedPropertyLoad(property); 1881471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org PrepareForBailoutForId(property->LoadId(), TOS_REG); 18824a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org break; 18834a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org case KEYED_PROPERTY: 18844a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org EmitKeyedPropertyLoad(property); 1885471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org PrepareForBailoutForId(property->LoadId(), TOS_REG); 18864a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org break; 18874a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 18885c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 18895c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1890d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Token::Value op = expr->binary_op(); 1891763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // Left operand goes on the stack. 18929ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org VisitForAccumulatorValue(expr->value()); 18935c838251403b0be9a882540f1922577abba4c872ager@chromium.org 189465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 189565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org ? OVERWRITE_RIGHT 189665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org : NO_OVERWRITE; 1897d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org SetSourcePosition(expr->position() + 1); 18984a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org AccumulatorValueContext context(this); 1899d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org if (ShouldInlineSmiCase(op)) { 19008e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org EmitInlineSmiBinaryOp(expr->binary_operation(), 1901d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org op, 1902d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org mode, 1903d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org expr->target(), 19049ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org expr->value()); 1905d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } else { 19068e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org EmitBinaryOp(expr->binary_operation(), op, mode); 1907d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } 1908d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Deoptimization point in case the binary operation may have side effects. 1909d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org PrepareForBailout(expr->binary_operation(), TOS_REG); 1910d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } else { 19114a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(expr->value()); 19125c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 19135c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19145c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Record source position before possible IC call. 19155c838251403b0be9a882540f1922577abba4c872ager@chromium.org SetSourcePosition(expr->position()); 19165c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19175c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Store the value. 19185c838251403b0be9a882540f1922577abba4c872ager@chromium.org switch (assign_type) { 19195c838251403b0be9a882540f1922577abba4c872ager@chromium.org case VARIABLE: 19205c838251403b0be9a882540f1922577abba4c872ager@chromium.org EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 19214a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org expr->op()); 1922d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 19235f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org context()->Plug(rax); 19245c838251403b0be9a882540f1922577abba4c872ager@chromium.org break; 19255c838251403b0be9a882540f1922577abba4c872ager@chromium.org case NAMED_PROPERTY: 19265c838251403b0be9a882540f1922577abba4c872ager@chromium.org EmitNamedPropertyAssignment(expr); 19275c838251403b0be9a882540f1922577abba4c872ager@chromium.org break; 19285c838251403b0be9a882540f1922577abba4c872ager@chromium.org case KEYED_PROPERTY: 19295c838251403b0be9a882540f1922577abba4c872ager@chromium.org EmitKeyedPropertyAssignment(expr); 19305c838251403b0be9a882540f1922577abba4c872ager@chromium.org break; 19315c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 19325c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 19335c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19345c838251403b0be9a882540f1922577abba4c872ager@chromium.org 193577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.orgvoid FullCodeGenerator::VisitYield(Yield* expr) { 193677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Comment cmnt(masm_, "[ Yield"); 193777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org // Evaluate yielded value first; the initial iterator definition depends on 193877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org // this. It stays on the stack while we update the iterator. 193977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org VisitForStackValue(expr->expression()); 194077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 194177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org switch (expr->yield_kind()) { 194241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org case Yield::SUSPEND: 194341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // Pop value from top-of-stack slot; box result into result register. 194441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org EmitCreateIteratorResult(false); 1945763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(result_register()); 194641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // Fall through. 194741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org case Yield::INITIAL: { 19481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label suspend, continuation, post_runtime, resume; 19491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 19501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ jmp(&suspend); 19511510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 19521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ bind(&continuation); 19531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ jmp(&resume); 19541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 19551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ bind(&suspend); 19561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org VisitForAccumulatorValue(expr->generator_object()); 19571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ASSERT(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); 19581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Move(FieldOperand(rax, JSGeneratorObject::kContinuationOffset), 19591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Smi::FromInt(continuation.pos())); 196043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rax, JSGeneratorObject::kContextOffset), rsi); 196143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, rsi); 19621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ RecordWriteField(rax, JSGeneratorObject::kContextOffset, rcx, rdx, 19631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org kDontSaveFPRegs); 1964895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rbx, Operand(rbp, StandardFrameConstants::kExpressionsOffset)); 19657a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rsp, rbx); 19661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ j(equal, &post_runtime); 1967763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // generator object 1968895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); 196943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(context_register(), 197077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Operand(rbp, StandardFrameConstants::kContextOffset)); 19711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ bind(&post_runtime); 197277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 1973763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(result_register()); 197441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org EmitReturnSequence(); 197577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 197677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ bind(&resume); 197777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org context()->Plug(result_register()); 197877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org break; 197977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 198077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 198177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org case Yield::FINAL: { 198277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org VisitForAccumulatorValue(expr->generator_object()); 198377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org __ Move(FieldOperand(result_register(), 198477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org JSGeneratorObject::kContinuationOffset), 198577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org Smi::FromInt(JSGeneratorObject::kGeneratorClosed)); 198641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // Pop value from top-of-stack slot, box result into result register. 198741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org EmitCreateIteratorResult(true); 198841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org EmitUnwindBeforeReturn(); 198941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org EmitReturnSequence(); 199077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org break; 199177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 199277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 19934e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org case Yield::DELEGATING: { 19944e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org VisitForStackValue(expr->generator_object()); 19954e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 19964e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org // Initial stack layout is as follows: 19974e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org // [sp + 1 * kPointerSize] iter 19984e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org // [sp + 0 * kPointerSize] g 19994e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 20001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label l_catch, l_try, l_suspend, l_continuation, l_resume; 20011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label l_next, l_call, l_loop; 20024e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org // Initial send value is undefined. 20034e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 20048a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ jmp(&l_next); 20054e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 2006f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 20074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org __ bind(&l_catch); 20084e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 20094e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org __ LoadRoot(rcx, Heap::kthrow_stringRootIndex); // "throw" 2010763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rcx); 2011763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Operand(rsp, 2 * kPointerSize)); // iter 2012763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // exception 20134e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org __ jmp(&l_call); 20144e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 2015f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org // try { received = %yield result } 2016f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org // Shuffle the received result above a try handler and yield it without 2017f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org // re-boxing. 20184e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org __ bind(&l_try); 2019763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rax); // result 20204e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org __ PushTryHandler(StackHandler::CATCH, expr->index()); 20214e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org const int handler_size = StackHandlerConstants::kSize; 2022763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // result 20231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ jmp(&l_suspend); 20241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ bind(&l_continuation); 20251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ jmp(&l_resume); 20261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ bind(&l_suspend); 20271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org const int generator_object_depth = kPointerSize + handler_size; 202843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, Operand(rsp, generator_object_depth)); 2029763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // g 20301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); 20311510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Move(FieldOperand(rax, JSGeneratorObject::kContinuationOffset), 20321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Smi::FromInt(l_continuation.pos())); 203343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rax, JSGeneratorObject::kContextOffset), rsi); 203443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, rsi); 20351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ RecordWriteField(rax, JSGeneratorObject::kContextOffset, rcx, rdx, 20361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org kDontSaveFPRegs); 2037895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); 203843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(context_register(), 20394e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org Operand(rbp, StandardFrameConstants::kContextOffset)); 2040763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rax); // result 204141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org EmitReturnSequence(); 20424e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org __ bind(&l_resume); // received in rax 20434e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org __ PopTryHandler(); 20444e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 2045f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org // receiver = iter; f = 'next'; arg = received; 20468a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ bind(&l_next); 20478a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ LoadRoot(rcx, Heap::knext_stringRootIndex); // "next" 2048763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rcx); 2049763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Operand(rsp, 2 * kPointerSize)); // iter 2050763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // received 20514e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 2052f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org // result = receiver[f](arg); 20534e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org __ bind(&l_call); 2054a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org __ movp(rdx, Operand(rsp, kPointerSize)); 2055a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org __ movp(rax, Operand(rsp, 2 * kPointerSize)); 2056a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2057f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallIC(ic, TypeFeedbackId::None()); 2058a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org __ movp(rdi, rax); 2059a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org __ movp(Operand(rsp, 2 * kPointerSize), rdi); 2060f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); 2061a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org __ CallStub(&stub); 2062a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 206343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2064a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org __ Drop(1); // The function is still on the stack; drop it. 20654e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 2066f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org // if (!result.done) goto l_try; 20674e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org __ bind(&l_loop); 2068763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // save result 20694e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org __ LoadRoot(rcx, Heap::kdone_stringRootIndex); // "done" 20709cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org CallLoadIC(NOT_CONTEXTUAL); // result.done in rax 2071b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2072b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org CallIC(bool_ic); 20737a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(result_register(), result_register()); 20744e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org __ j(zero, &l_try); 20754e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 20764e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org // result.value 2077763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rax); // result 2078f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org __ LoadRoot(rcx, Heap::kvalue_stringRootIndex); // "value" 20799cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org CallLoadIC(NOT_CONTEXTUAL); // result.value in rax 20804e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org context()->DropAndPlug(2, rax); // drop iter and g 20814e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org break; 20824e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } 208377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 208477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org} 208577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 208677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 2087ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvoid FullCodeGenerator::EmitGeneratorResume(Expression *generator, 2088ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Expression *value, 2089ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org JSGeneratorObject::ResumeMode resume_mode) { 2090ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // The value stays in rax, and is ultimately read by the resumed generator, as 2091895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org // if CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject) returned it. Or it 2092e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // is read to throw the value when the resumed generator is already closed. 2093e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // rbx will hold the generator object until the activation has been resumed. 2094ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org VisitForStackValue(generator); 2095ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org VisitForAccumulatorValue(value); 2096763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rbx); 2097ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2098ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Check generator state. 2099e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org Label wrong_state, closed_state, done; 2100e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); 2101e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); 2102ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ SmiCompare(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), 2103ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Smi::FromInt(0)); 2104e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ j(equal, &closed_state); 2105e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ j(less, &wrong_state); 2106ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2107ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Load suspended function and context. 210843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset)); 210943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset)); 2110ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2111ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Push receiver. 2112763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(FieldOperand(rbx, JSGeneratorObject::kReceiverOffset)); 2113ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2114ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Push holes for arguments to generator function. 211543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 211604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org __ LoadSharedFunctionInfoSpecialField(rdx, rdx, 211704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org SharedFunctionInfo::kFormalParameterCountOffset); 2118ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ LoadRoot(rcx, Heap::kTheHoleValueRootIndex); 2119ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Label push_argument_holes, push_frame; 2120ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ bind(&push_argument_holes); 2121fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rdx, Immediate(1)); 2122ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ j(carry, &push_frame); 2123763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rcx); 2124ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ jmp(&push_argument_holes); 2125ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2126ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Enter a new JavaScript frame, and initialize its slots as they were when 2127ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // the generator was suspended. 2128ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Label resume_frame; 2129ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ bind(&push_frame); 2130ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ call(&resume_frame); 2131ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ jmp(&done); 2132ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ bind(&resume_frame); 2133763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rbp); // Caller's frame pointer. 213443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbp, rsp); 2135763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); // Callee's context. 2136763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rdi); // Callee's JS Function. 2137ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2138ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Load the operand stack size. 213943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, FieldOperand(rbx, JSGeneratorObject::kOperandStackOffset)); 214043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, FieldOperand(rdx, FixedArray::kLengthOffset)); 2141ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ SmiToInteger32(rdx, rdx); 2142ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2143ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // If we are sending a value and there is no operand stack, we can jump back 2144ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // in directly. 21458a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (resume_mode == JSGeneratorObject::NEXT) { 2146ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Label slow_resume; 21477a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rdx, Immediate(0)); 2148ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ j(not_zero, &slow_resume); 214943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 2150ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ SmiToInteger64(rcx, 2151ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org FieldOperand(rbx, JSGeneratorObject::kContinuationOffset)); 2152fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rdx, rcx); 2153ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ Move(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), 2154ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)); 2155ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ jmp(rdx); 2156ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ bind(&slow_resume); 2157ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 2158ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2159ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Otherwise, we push holes for the operand stack and call the runtime to fix 2160ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // up the stack and the handlers. 2161ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Label push_operand_holes, call_resume; 2162ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ bind(&push_operand_holes); 2163fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rdx, Immediate(1)); 2164ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ j(carry, &call_resume); 2165763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rcx); 2166ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ jmp(&push_operand_holes); 2167ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ bind(&call_resume); 2168763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rbx); 2169763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(result_register()); 2170ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ Push(Smi::FromInt(resume_mode)); 2171895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenResumeJSGeneratorObject, 3); 2172ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Not reached: the runtime call returns elsewhere. 2173594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Abort(kGeneratorFailedToResume); 2174ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2175e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // Reach here when generator is closed. 2176e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ bind(&closed_state); 2177e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org if (resume_mode == JSGeneratorObject::NEXT) { 2178e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // Return completed iterator result when generator is closed. 2179e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ PushRoot(Heap::kUndefinedValueRootIndex); 2180e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // Pop value from top-of-stack slot; box result into result register. 2181e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org EmitCreateIteratorResult(true); 2182e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org } else { 2183e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // Throw the provided value. 2184763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 2185895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenThrow, 1); 2186e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org } 2187e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ jmp(&done); 2188e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 2189ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Throw error if we attempt to operate on a running generator. 2190ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ bind(&wrong_state); 2191763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rbx); 2192895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenThrowGeneratorStateError, 1); 2193ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2194ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ bind(&done); 2195ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org context()->Plug(result_register()); 2196ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 2197ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2198ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 219941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgvoid FullCodeGenerator::EmitCreateIteratorResult(bool done) { 220057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Label gc_required; 220157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Label allocated; 220257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 22034ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org Handle<Map> map(isolate()->native_context()->iterator_result_map()); 220457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 220557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ Allocate(map->instance_size(), rax, rcx, rdx, &gc_required, TAG_OBJECT); 220641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ jmp(&allocated); 220741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 220841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ bind(&gc_required); 220941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ Push(Smi::FromInt(map->instance_size())); 2210895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1); 221143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(context_register(), 221241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Operand(rbp, StandardFrameConstants::kContextOffset)); 221357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 221457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ bind(&allocated); 221557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ Move(rbx, map); 2216763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rcx); 221757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ Move(rdx, isolate()->factory()->ToBoolean(done)); 221857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ASSERT_EQ(map->instance_size(), 5 * kPointerSize); 221943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx); 222057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ Move(FieldOperand(rax, JSObject::kPropertiesOffset), 222157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org isolate()->factory()->empty_fixed_array()); 222257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ Move(FieldOperand(rax, JSObject::kElementsOffset), 222357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org isolate()->factory()->empty_fixed_array()); 222443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rax, JSGeneratorObject::kResultValuePropertyOffset), 222557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org rcx); 222643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rax, JSGeneratorObject::kResultDonePropertyOffset), 222757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org rdx); 222857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 222957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // Only the value field needs a write barrier, as the other values are in the 223057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // root set. 223157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, 223257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org rcx, rdx, kDontSaveFPRegs); 223357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org} 223457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 223557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 2236b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2237b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org SetSourcePosition(prop->position()); 2238b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Literal* key = prop->key()->AsLiteral(); 22391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Move(rcx, key->value()); 22409cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2241b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2242b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2243b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2244b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2245b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org SetSourcePosition(prop->position()); 22467979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2247f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallIC(ic, prop->PropertyFeedbackId()); 2248b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2249b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2250b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 22518e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgvoid FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2252d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Token::Value op, 2253d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org OverwriteMode mode, 2254d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Expression* left, 22559ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org Expression* right) { 2256d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Do combined smi check of the operands. Left operand is on the 2257d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // stack (popped into rdx). Right operand is in rax but moved into 2258d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // rcx to make the shifts easier. 225983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done, stub_call, smi_case; 2260763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rdx); 226143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, rax); 2262895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ orp(rax, rdx); 2263d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com JumpPatchSite patch_site(masm_); 226483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); 2265d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2266d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ bind(&stub_call); 226743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, rcx); 2268f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org BinaryOpICStub stub(isolate(), op, mode); 2269f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId()); 22704f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org patch_site.EmitPatchInfo(); 227183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&done, Label::kNear); 2272d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2273d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ bind(&smi_case); 2274d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org switch (op) { 2275d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org case Token::SAR: 2276d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ SmiShiftArithmeticRight(rax, rdx, rcx); 2277d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org break; 2278d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org case Token::SHL: 2279e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ SmiShiftLeft(rax, rdx, rcx, &stub_call); 2280d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org break; 2281d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org case Token::SHR: 2282d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ SmiShiftLogicalRight(rax, rdx, rcx, &stub_call); 2283d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org break; 2284d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org case Token::ADD: 2285d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ SmiAdd(rax, rdx, rcx, &stub_call); 2286d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org break; 2287d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org case Token::SUB: 2288d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ SmiSub(rax, rdx, rcx, &stub_call); 2289d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org break; 2290d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org case Token::MUL: 2291d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ SmiMul(rax, rdx, rcx, &stub_call); 2292d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org break; 2293d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org case Token::BIT_OR: 2294d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ SmiOr(rax, rdx, rcx); 2295d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org break; 2296d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org case Token::BIT_AND: 2297d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ SmiAnd(rax, rdx, rcx); 2298d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org break; 2299d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org case Token::BIT_XOR: 2300d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ SmiXor(rax, rdx, rcx); 2301d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org break; 2302d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org default: 2303d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org UNREACHABLE(); 2304d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org break; 2305d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } 2306d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2307d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ bind(&done); 23084a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 2309d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 2310d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2311d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 23128e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgvoid FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 23138e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org Token::Value op, 231465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org OverwriteMode mode) { 2315763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rdx); 2316f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org BinaryOpICStub stub(isolate(), op, mode); 23174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2318f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId()); 23194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org patch_site.EmitPatchInfo(); 23204a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 2321b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2322b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2323b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2324be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid FullCodeGenerator::EmitAssignment(Expression* expr) { 23254edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org ASSERT(expr->IsValidReferenceExpression()); 23269dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 23279dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Left-hand side can only be a property, a global or a (parameter or local) 23287b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // slot. 23299dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 23309dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com LhsKind assign_type = VARIABLE; 23319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Property* prop = expr->AsProperty(); 23329dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com if (prop != NULL) { 23339dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com assign_type = (prop->key()->IsPropertyName()) 23349dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ? NAMED_PROPERTY 23359dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com : KEYED_PROPERTY; 23369dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 23379dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 23389dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com switch (assign_type) { 23399dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com case VARIABLE: { 23409dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Variable* var = expr->AsVariableProxy()->var(); 23414a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org EffectContext context(this); 23424a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org EmitVariableAssignment(var, Token::ASSIGN); 23439dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com break; 23449dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 23459dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com case NAMED_PROPERTY: { 2346763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // Preserve value. 23474a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(prop->obj()); 234843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, rax); 2349763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rax); // Restore value. 23501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Move(rcx, prop->key()->AsLiteral()->value()); 2351f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallStoreIC(); 23529dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com break; 23539dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 23549dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com case KEYED_PROPERTY: { 2355763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // Preserve value. 23567b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org VisitForStackValue(prop->obj()); 23577b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org VisitForAccumulatorValue(prop->key()); 235843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, rax); 2359763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rdx); 2360763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rax); // Restore value. 2361486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org Handle<Code> ic = strict_mode() == SLOPPY 23621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ? isolate()->builtins()->KeyedStoreIC_Initialize() 23631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 23641456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org CallIC(ic); 23659dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com break; 23669dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 23679dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 23685f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org context()->Plug(rax); 23699dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 23709dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 23719dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 2372f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( 2373f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Variable* var, MemOperand location) { 2374f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ movp(location, rax); 2375f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (var->IsContextSlot()) { 2376f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ movp(rdx, rax); 2377f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ RecordWriteContextSlot( 2378f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); 2379f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 2380f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 2381f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 2382f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 2383f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid FullCodeGenerator::EmitCallStoreContextSlot( 2384486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org Handle<String> name, StrictMode strict_mode) { 2385763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // Value. 2386763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); // Context. 2387f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ Push(name); 2388486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org __ Push(Smi::FromInt(strict_mode)); 2389895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenStoreContextSlot, 4); 2390f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 2391f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 2392f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 2393b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::EmitVariableAssignment(Variable* var, 23944a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Token::Value op) { 2395486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (var->IsUnallocated()) { 2396486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Global var, const, or let. 2397b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ Move(rcx, var->name()); 239843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, GlobalObjectOperand()); 2399f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallStoreIC(); 2400f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 2401486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org } else if (op == Token::INIT_CONST_LEGACY) { 2402486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Const initializers need a write barrier. 2403486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ASSERT(!var->IsParameter()); // No const parameters. 2404f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (var->IsLookupSlot()) { 2405763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 2406763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); 2407052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org __ Push(var->name()); 2408895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenInitializeConstContextSlot, 3); 2409f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 2410f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ASSERT(var->IsStackLocal() || var->IsContextSlot()); 2411f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Label skip; 2412f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org MemOperand location = VarOperand(var, rcx); 2413f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ movp(rdx, location); 2414f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 2415f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ j(not_equal, &skip); 2416f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org EmitStoreToStackLocalOrContextSlot(var, location); 2417f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ bind(&skip); 24185d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } 24195d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 2420b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org } else if (var->mode() == LET && op != Token::INIT_LET) { 2421486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Non-initializing assignment to let variable needs a write barrier. 2422486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (var->IsLookupSlot()) { 2423486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org EmitCallStoreContextSlot(var->name(), strict_mode()); 2424486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } else { 2425486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2426486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Label assign; 2427486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org MemOperand location = VarOperand(var, rcx); 242843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, location); 2429486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 2430486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ j(not_equal, &assign, Label::kNear); 2431486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ Push(var->name()); 2432895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); 2433486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ bind(&assign); 2434f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org EmitStoreToStackLocalOrContextSlot(var, location); 243580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org } 2436b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2437486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org } else if (!var->is_const_mode() || op == Token::INIT_CONST) { 2438394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Assignment to var or initializing assignment to let/const 2439394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // in harmony mode. 2440f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (var->IsLookupSlot()) { 2441486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org EmitCallStoreContextSlot(var->name(), strict_mode()); 2442f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 2443f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2444486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org MemOperand location = VarOperand(var, rcx); 2445000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (generate_debug_code_ && op == Token::INIT_LET) { 2446486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Check for an uninitialized let binding. 244743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, location); 2448486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 2449594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Check(equal, kLetBindingReInitialization); 2450486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 2451f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org EmitStoreToStackLocalOrContextSlot(var, location); 2452b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 2453b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 2454486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Non-initializing assignments to consts are ignored. 2455b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2456b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2457b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2458b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2459b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Assignment to a property, using a named store IC. 2460b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Property* prop = expr->target()->AsProperty(); 2461b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(prop != NULL); 2462196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ASSERT(prop->key()->IsLiteral()); 2463b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2464b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Record source code position before IC call. 2465b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org SetSourcePosition(expr->position()); 24661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Move(rcx, prop->key()->AsLiteral()->value()); 2467763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rdx); 2468f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallStoreIC(expr->AssignmentFeedbackId()); 2469b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2470d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 24715f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org context()->Plug(rax); 2472b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2473b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2474b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2475b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2476b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Assignment to a property, using a keyed store IC. 2477b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2478763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rcx); 2479763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rdx); 2480b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Record source code position before IC call. 2481b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org SetSourcePosition(expr->position()); 2482486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org Handle<Code> ic = strict_mode() == SLOPPY 24831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ? isolate()->builtins()->KeyedStoreIC_Initialize() 24841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2485f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallIC(ic, expr->AssignmentFeedbackId()); 2486b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2487d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 24884a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 2489b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2490b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2491b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2492b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::VisitProperty(Property* expr) { 2493b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Comment cmnt(masm_, "[ Property"); 2494b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Expression* key = expr->key(); 2495b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2496b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (key->IsPropertyName()) { 24974a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(expr->obj()); 2498b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org EmitNamedPropertyLoad(expr); 2499471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2500a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org context()->Plug(rax); 2501b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 25024a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(expr->obj()); 25034a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(expr->key()); 2504763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rdx); 2505b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org EmitKeyedPropertyLoad(expr); 2506a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org context()->Plug(rax); 2507b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 2508b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2509b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2510b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 25111456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid FullCodeGenerator::CallIC(Handle<Code> code, 2512471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org TypeFeedbackId ast_id) { 25131456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org ic_total_count_++; 25149cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org __ call(code, RelocInfo::CODE_TARGET, ast_id); 25151456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} 25161456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 25171456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 2518a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org// Code common for calls using the IC. 2519a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgvoid FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { 2520a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Expression* callee = expr->expression(); 2521a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 2522a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org CallIC::CallType call_type = callee->IsVariableProxy() 2523a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org ? CallIC::FUNCTION 2524a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org : CallIC::METHOD; 2525a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // Get the target function. 2526a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (call_type == CallIC::FUNCTION) { 2527a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org { StackValueContext context(this); 2528a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org EmitVariableLoad(callee->AsVariableProxy()); 2529a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org PrepareForBailout(callee, NO_REGISTERS); 2530a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org } 2531a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Push undefined as receiver. This is patched in the method prologue if it 2532486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org // is a sloppy mode method. 2533a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org __ Push(isolate()->factory()->undefined_value()); 2534a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org } else { 2535a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Load the function from the receiver. 2536a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org ASSERT(callee->IsProperty()); 2537a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org __ movp(rax, Operand(rsp, 0)); 2538a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org EmitNamedPropertyLoad(callee->AsProperty()); 2539a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2540a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Push the target function under the receiver. 2541763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Operand(rsp, 0)); 2542a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org __ movp(Operand(rsp, kPointerSize), rax); 2543b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 2544a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 2545a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org EmitCall(expr, call_type); 2546b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2547b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2548b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2549a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org// Common code for calls using the IC. 2550a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgvoid FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2551a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Expression* key) { 25524a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Load the key. 25534a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com VisitForAccumulatorValue(key); 25544a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 2555a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org Expression* callee = expr->expression(); 2556a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 2557a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Load the function from the receiver. 2558a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org ASSERT(callee->IsProperty()); 2559a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org __ movp(rdx, Operand(rsp, 0)); 2560a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org EmitKeyedPropertyLoad(callee->AsProperty()); 2561a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2562a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 2563a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Push the target function under the receiver. 2564763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Operand(rsp, 0)); 2565a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org __ movp(Operand(rsp, kPointerSize), rax); 2566a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 2567a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org EmitCall(expr, CallIC::METHOD); 25682c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org} 25692c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org 25702c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org 2571a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgvoid FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) { 2572a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // Load the arguments. 2573b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ZoneList<Expression*>* args = expr->arguments(); 2574b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int arg_count = args->length(); 2575a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org { PreservePositionScope scope(masm()->positions_recorder()); 2576f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org for (int i = 0; i < arg_count; i++) { 2577f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org VisitForStackValue(args->at(i)); 2578f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org } 2579b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 258088d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org 2581a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // Record source position of the IC call. 2582a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org SetSourcePosition(expr->position()); 2583a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Handle<Code> ic = CallIC::initialize_stub( 2584a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org isolate(), arg_count, call_type); 2585f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ Move(rdx, Smi::FromInt(expr->CallFeedbackSlot())); 258643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); 2587a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // Don't assign a type feedback id to the IC, since type feedback is provided 2588a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // by the vector above. 2589a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org CallIC(ic); 2590a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 2591d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org RecordJSReturnSite(expr); 2592a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 2593b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Restore context register. 259443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2595b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Discard the function left on TOS. 25964a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->DropAndPlug(1, rax); 2597b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2598b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2599b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2600c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 26019ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Push copy of the first argument or undefined if it doesn't exist. 26029ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org if (arg_count > 0) { 2603763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Operand(rsp, arg_count * kPointerSize)); 26049ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } else { 26059ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org __ PushRoot(Heap::kUndefinedValueRootIndex); 26069ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } 26079ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 26089ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org // Push the receiver of the enclosing function and do runtime call. 2609d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org StackArgumentsAccessor args(rbp, info_->scope()->num_parameters()); 2610763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(args.GetReceiverOperand()); 26119ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 26121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Push the language mode. 2613486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org __ Push(Smi::FromInt(strict_mode())); 26149ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 261504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Push the start position of the scope the calls resides in. 261604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org __ Push(Smi::FromInt(scope()->start_position())); 261704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 26181b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Do the runtime call. 2619895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenResolvePossiblyDirectEval, 5); 26209ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org} 26219ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 26229ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 2623b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::VisitCall(Call* expr) { 2624d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org#ifdef DEBUG 2625d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // We want to verify that RecordJSReturnSite gets called on all paths 2626d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // through this function. Avoid early returns. 2627d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org expr->return_is_recorded_ = false; 2628d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org#endif 2629d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 2630b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Comment cmnt(masm_, "[ Call"); 2631486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Expression* callee = expr->expression(); 263243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org Call::CallType call_type = expr->GetCallType(isolate()); 2633b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 263443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org if (call_type == Call::POSSIBLY_EVAL_CALL) { 2635895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval 2636895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org // to resolve the function we need to call and the receiver of the call. 2637486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Then we call the resolved function using the given arguments. 26389dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ZoneList<Expression*>* args = expr->arguments(); 26399dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com int arg_count = args->length(); 2640a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org { PreservePositionScope pos_scope(masm()->positions_recorder()); 2641486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org VisitForStackValue(callee); 2642f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org __ PushRoot(Heap::kUndefinedValueRootIndex); // Reserved receiver slot. 26439dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 2644f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org // Push the arguments. 2645f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org for (int i = 0; i < arg_count; i++) { 2646f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org VisitForStackValue(args->at(i)); 2647f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org } 26489dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 2649486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Push a copy of the function (found below the arguments) and resolve 2650486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // eval. 2651763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Operand(rsp, (arg_count + 1) * kPointerSize)); 2652c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org EmitResolvePossiblyDirectEval(arg_count); 26539dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 2654f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org // The runtime call returns a pair of values in rax (function) and 2655f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org // rdx (receiver). Touch up the stack with the right values. 265643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rsp, (arg_count + 0) * kPointerSize), rdx); 265743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax); 2658f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org } 26599dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Record source position for debugger. 2660a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org SetSourcePosition(expr->position()); 2661f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); 266243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); 26639dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CallStub(&stub); 2664d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org RecordJSReturnSite(expr); 26659dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Restore context register. 266643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 26674a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->DropAndPlug(1, rax); 266843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org } else if (call_type == Call::GLOBAL_CALL) { 2669a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org EmitCallWithLoadIC(expr); 2670a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 267143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org } else if (call_type == Call::LOOKUP_SLOT_CALL) { 26722ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // Call to a lookup slot (dynamically introduced variable). 267343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org VariableProxy* proxy = callee->AsVariableProxy(); 26742ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org Label slow, done; 26752ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 2676a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org { PreservePositionScope scope(masm()->positions_recorder()); 2677486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Generate code for loading from variables potentially shadowed by 2678486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // eval-introduced variables. 2679486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); 2680d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 2681486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ bind(&slow); 2682486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Call the runtime to find the function to call (returned in rax) and 2683486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // the object holding it (returned in rdx). 2684763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(context_register()); 2685486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ Push(proxy->name()); 2686895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenLoadContextSlot, 2); 2687763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // Function. 2688763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rdx); // Receiver. 2689d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 2690486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // If fast case code has been generated, emit code to push the function 2691486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // and receiver and have the slow path jump around this code. 2692d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org if (done.is_linked()) { 269383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label call; 269483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&call, Label::kNear); 2695d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org __ bind(&done); 2696d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // Push function. 2697763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 2698486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // The receiver is implicitly the global receiver. Indicate this by 2699486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // passing the hole to the call function stub. 2700e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ PushRoot(Heap::kUndefinedValueRootIndex); 27018e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org __ bind(&call); 27022ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org } 27032ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 2704486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // The receiver is either the global receiver or an object found by 2705e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // LoadContextSlot. 2706a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org EmitCall(expr); 270743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org } else if (call_type == Call::PROPERTY_CALL) { 270843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org Property* property = callee->AsProperty(); 2709486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org { PreservePositionScope scope(masm()->positions_recorder()); 2710486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org VisitForStackValue(property->obj()); 2711486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 2712486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (property->key()->IsPropertyName()) { 2713a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org EmitCallWithLoadIC(expr); 2714b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 2715a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org EmitKeyedCallWithLoadIC(expr, property->key()); 2716b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 2717b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 271843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org ASSERT(call_type == Call::OTHER_CALL); 2719486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Call to an arbitrary expression not handled specially above. 2720a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org { PreservePositionScope scope(masm()->positions_recorder()); 2721486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org VisitForStackValue(callee); 2722f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org } 2723e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ PushRoot(Heap::kUndefinedValueRootIndex); 2724b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Emit function call. 2725a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org EmitCall(expr); 2726b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 2727d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 2728d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org#ifdef DEBUG 2729d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // RecordJSReturnSite should have been called. 2730d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org ASSERT(expr->return_is_recorded_); 2731d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org#endif 2732b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2733b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2734b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2735b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::VisitCallNew(CallNew* expr) { 2736b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Comment cmnt(masm_, "[ CallNew"); 2737b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // According to ECMA-262, section 11.2.2, page 44, the function 2738b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // expression in new calls must be evaluated before the 2739b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // arguments. 2740b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 274165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Push constructor on the stack. If it's not a function it's used as 274265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is 274365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // ignored. 27444a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(expr->expression()); 2745b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2746b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Push the arguments ("left-to-right") on the stack. 2747b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ZoneList<Expression*>* args = expr->arguments(); 2748b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int arg_count = args->length(); 2749b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org for (int i = 0; i < arg_count; i++) { 27504a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(i)); 2751b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 2752b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2753b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Call the construct call builtin that handles allocation and 2754b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // constructor invocation. 2755b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org SetSourcePosition(expr->position()); 2756b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 275765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Load function and argument count into rdi and rax. 2758b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ Set(rax, arg_count); 275943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdi, Operand(rsp, arg_count * kPointerSize)); 2760b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2761fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // Record call targets in unoptimized code, but not in the snapshot. 276269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org if (FLAG_pretenuring_call_new) { 2763a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); 276469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org ASSERT(expr->AllocationSiteFeedbackSlot() == 276569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org expr->CallNewFeedbackSlot() + 1); 276669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 276769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 2768f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ Move(rbx, FeedbackVector()); 2769f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ Move(rdx, Smi::FromInt(expr->CallNewFeedbackSlot())); 2770fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 2771a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET); 2772f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); 2773967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 27744a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 2775b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 2776b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2777b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 2778c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2779c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 27809dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 1); 27819dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 27824a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(0)); 27839dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 27849dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label materialize_true, materialize_false; 27859dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_true = NULL; 27869dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_false = NULL; 278765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through = NULL; 27884a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 27894a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org &if_true, &if_false, &fall_through); 27909dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 2791c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 27929dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ JumpIfSmi(rax, if_true); 27939dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ jmp(if_false); 27949dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 27954a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(if_true, if_false); 27969dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 27979dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 27989dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 2799c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { 2800c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 28019dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 1); 28029dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 28034a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(0)); 28049dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 28059dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label materialize_true, materialize_false; 28069dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_true = NULL; 28079dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_false = NULL; 280865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through = NULL; 28094a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 28104a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org &if_true, &if_false, &fall_through); 28119dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 2812c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 2813eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org Condition non_negative_smi = masm()->CheckNonNegativeSmi(rax); 2814eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org Split(non_negative_smi, if_true, if_false, fall_through); 28159dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 28164a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(if_true, if_false); 28179dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 28189dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 28199dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 2820c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitIsObject(CallRuntime* expr) { 2821c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 28229dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 1); 28239dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 28244a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(0)); 28259dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 28269dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label materialize_true, materialize_false; 28279dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_true = NULL; 28289dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_false = NULL; 282965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through = NULL; 28304a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 28314a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org &if_true, &if_false, &fall_through); 28329dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 28339dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ JumpIfSmi(rax, if_false); 28349dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CompareRoot(rax, Heap::kNullValueRootIndex); 28359dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ j(equal, if_true); 283643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, FieldOperand(rax, HeapObject::kMapOffset)); 28379dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Undetectable objects behave like undefined when tested with typeof. 28389dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ testb(FieldOperand(rbx, Map::kBitFieldOffset), 28399dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Immediate(1 << Map::kIsUndetectable)); 28409dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ j(not_zero, if_false); 2841895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ movzxbp(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset)); 28427a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rbx, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 28439dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ j(below, if_false); 28447a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rbx, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2845c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 284665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(below_equal, if_true, if_false, fall_through); 28479dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 28484a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(if_true, if_false); 28499dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 28509dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 28519dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 2852c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) { 2853c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 28544980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org ASSERT(args->length() == 1); 28554980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org 28564a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(0)); 28574980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org 28584980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org Label materialize_true, materialize_false; 28594980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org Label* if_true = NULL; 28604980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org Label* if_false = NULL; 286165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through = NULL; 28624a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 28634a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org &if_true, &if_false, &fall_through); 28644980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org 28654980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org __ JumpIfSmi(rax, if_false); 2866d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rbx); 2867c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 286865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(above_equal, if_true, if_false, fall_through); 28694980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org 28704a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(if_true, if_false); 28714980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org} 28724980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org 28734980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org 2874c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitIsUndetectableObject(CallRuntime* expr) { 2875c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 28769dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 1); 28779dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 28784a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(0)); 28799dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 28809dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label materialize_true, materialize_false; 28819dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_true = NULL; 28829dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_false = NULL; 288365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through = NULL; 28844a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 28854a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org &if_true, &if_false, &fall_through); 28869dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 28879dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ JumpIfSmi(rax, if_false); 288843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, FieldOperand(rax, HeapObject::kMapOffset)); 28899dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ testb(FieldOperand(rbx, Map::kBitFieldOffset), 28909dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Immediate(1 << Map::kIsUndetectable)); 2891c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 289265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(not_zero, if_true, if_false, fall_through); 28939dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 28944a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(if_true, if_false); 28959dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 28969dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 28979dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 2898ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgvoid FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf( 2899c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CallRuntime* expr) { 2900c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 2901ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org ASSERT(args->length() == 1); 2902ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 29034a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(0)); 2904ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 29054a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org Label materialize_true, materialize_false, skip_lookup; 2906ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org Label* if_true = NULL; 2907ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org Label* if_false = NULL; 290865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through = NULL; 29094a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 29104a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org &if_true, &if_false, &fall_through); 2911ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 2912c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org __ AssertNotSmi(rax); 2913c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 2914c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Check whether this map has already been checked to be safe for default 2915c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // valueOf. 291643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, FieldOperand(rax, HeapObject::kMapOffset)); 2917c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org __ testb(FieldOperand(rbx, Map::kBitField2Offset), 2918c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf)); 29194a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ j(not_zero, &skip_lookup); 2920c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 2921c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Check for fast case object. Generate false result for slow case object. 292243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, FieldOperand(rax, JSObject::kPropertiesOffset)); 292343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, FieldOperand(rcx, HeapObject::kMapOffset)); 2924c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org __ CompareRoot(rcx, Heap::kHashTableMapRootIndex); 2925c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org __ j(equal, if_false); 2926c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 29274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Look for valueOf string in the descriptor array, and indicate false if 292806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org // found. Since we omit an enumeration index check, if it is added via a 292906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org // transition that shares its descriptor array, this is a false positive. 293006ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org Label entry, loop, done; 293106ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org 293206ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org // Skip loop if no descriptors are valid. 293306ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org __ NumberOfOwnDescriptors(rcx, rbx); 29347a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rcx, Immediate(0)); 293506ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org __ j(equal, &done); 293606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org 29374a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ LoadInstanceDescriptors(rbx, r8); 293806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org // rbx: descriptor array. 293906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org // rcx: valid entries in the descriptor array. 2940c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Calculate the end of the descriptor array. 2941fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ imulp(rcx, rcx, Immediate(DescriptorArray::kDescriptorSize)); 29423c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org __ leap(rcx, Operand(r8, rcx, times_8, DescriptorArray::kFirstOffset)); 2943c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Calculate location of the first key name. 2944fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(r8, Immediate(DescriptorArray::kFirstOffset)); 2945c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Loop through all the keys in the descriptor array. If one of these is the 29464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // internalized string "valueOf" the result is false. 2947c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org __ jmp(&entry); 2948c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org __ bind(&loop); 294943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, FieldOperand(r8, 0)); 2950d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org __ Cmp(rdx, isolate()->factory()->value_of_string()); 2951c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org __ j(equal, if_false); 2952fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(r8, Immediate(DescriptorArray::kDescriptorSize * kPointerSize)); 2953c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org __ bind(&entry); 29547a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(r8, rcx); 2955c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org __ j(not_equal, &loop); 2956c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 295706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org __ bind(&done); 29584a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org 29594a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // Set the bit in the map to indicate that there is no local valueOf field. 2960895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ orp(FieldOperand(rbx, Map::kBitField2Offset), 29614a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf)); 29624a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org 29634a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ bind(&skip_lookup); 2964c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 296506ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org // If a valueOf property is not found on the object check that its 2966c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // prototype is the un-modified String prototype. If not result is false. 296743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, FieldOperand(rbx, Map::kPrototypeOffset)); 29687a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rcx, Immediate(kSmiTagMask)); 2969c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org __ j(zero, if_false); 297043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, FieldOperand(rcx, HeapObject::kMapOffset)); 297143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 297243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, FieldOperand(rdx, GlobalObject::kNativeContextOffset)); 29737a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rcx, 2974c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org ContextOperand(rdx, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX)); 2975c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 29764a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org Split(equal, if_true, if_false, fall_through); 29774a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org 29784a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(if_true, if_false); 2979ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org} 2980ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 2981ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 2982c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitIsFunction(CallRuntime* expr) { 2983c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 29849dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 1); 29859dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 29864a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(0)); 29879dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 29889dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label materialize_true, materialize_false; 29899dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_true = NULL; 29909dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_false = NULL; 299165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through = NULL; 29924a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 29934a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org &if_true, &if_false, &fall_through); 29949dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 29959dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ JumpIfSmi(rax, if_false); 29969dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); 2997c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 299865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(equal, if_true, if_false, fall_through); 29999dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30004a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(if_true, if_false); 30019dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 30029dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30039dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30040cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.orgvoid FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) { 30050cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 30060cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org ASSERT(args->length() == 1); 30070cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 30080cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 30090cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 30100cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Label materialize_true, materialize_false; 30110cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Label* if_true = NULL; 30120cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Label* if_false = NULL; 30130cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Label* fall_through = NULL; 30140cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 30150cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org &if_true, &if_false, &fall_through); 30160cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 30170cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Handle<Map> map = masm()->isolate()->factory()->heap_number_map(); 30180cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org __ CheckMap(rax, map, if_false, DO_SMI_CHECK); 30190cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org __ cmpl(FieldOperand(rax, HeapNumber::kExponentOffset), 3020a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Immediate(0x1)); 3021a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org __ j(no_overflow, if_false); 30220cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org __ cmpl(FieldOperand(rax, HeapNumber::kMantissaOffset), 30230cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Immediate(0x00000000)); 30240cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 30250cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Split(equal, if_true, if_false, fall_through); 30260cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 30270cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org context()->Plug(if_true, if_false); 30280cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org} 30290cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 30300cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 3031c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitIsArray(CallRuntime* expr) { 3032c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 30339dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 1); 30349dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30354a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(0)); 30369dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30379dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label materialize_true, materialize_false; 30389dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_true = NULL; 30399dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_false = NULL; 304065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through = NULL; 30414a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 30424a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org &if_true, &if_false, &fall_through); 30439dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30449dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ JumpIfSmi(rax, if_false); 30459dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CmpObjectType(rax, JS_ARRAY_TYPE, rbx); 3046c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 304765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(equal, if_true, if_false, fall_through); 30489dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30494a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(if_true, if_false); 30509dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 30519dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30529dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3053c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) { 3054c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 30559dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 1); 30569dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30574a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(0)); 30589dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30599dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label materialize_true, materialize_false; 30609dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_true = NULL; 30619dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_false = NULL; 306265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through = NULL; 30634a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 30644a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org &if_true, &if_false, &fall_through); 30659dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30669dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ JumpIfSmi(rax, if_false); 30679dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CmpObjectType(rax, JS_REGEXP_TYPE, rbx); 3068c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 306965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(equal, if_true, if_false, fall_through); 30709dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30714a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(if_true, if_false); 30729dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 30739dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30749dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30759dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3076c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) { 3077c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(expr->arguments()->length() == 0); 30789dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30799dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label materialize_true, materialize_false; 30809dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_true = NULL; 30819dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_false = NULL; 308265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through = NULL; 30834a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 30844a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org &if_true, &if_false, &fall_through); 30859dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30869dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Get the frame pointer for the calling frame. 308743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 30889dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30899dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Skip the arguments adaptor frame if it exists. 30909dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label check_frame_marker; 3091badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ Cmp(Operand(rax, StandardFrameConstants::kContextOffset), 3092badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 30939dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ j(not_equal, &check_frame_marker); 309443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, Operand(rax, StandardFrameConstants::kCallerFPOffset)); 30959dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 30969dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Check the marker in the calling frame. 30979dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&check_frame_marker); 3098badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ Cmp(Operand(rax, StandardFrameConstants::kMarkerOffset), 3099badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org Smi::FromInt(StackFrame::CONSTRUCT)); 3100c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 310165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(equal, if_true, if_false, fall_through); 31029dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 31034a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(if_true, if_false); 31049dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 31059dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 31069dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3107c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) { 3108c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 31099dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 2); 31109dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 31119dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Load the two objects into registers and perform the comparison. 31124a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(0)); 31134a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(1)); 31149dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 31159dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label materialize_true, materialize_false; 31169dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_true = NULL; 31179dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_false = NULL; 311865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through = NULL; 31194a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 31204a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org &if_true, &if_false, &fall_through); 31219dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3122763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rbx); 31237a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rax, rbx); 3124c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 312565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(equal, if_true, if_false, fall_through); 31269dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 31274a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(if_true, if_false); 31289dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 31299dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 31309dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3131c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitArguments(CallRuntime* expr) { 3132c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 31339dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 1); 31349dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3135d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // ArgumentsAccessStub expects the key in rdx and the formal 3136d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // parameter count in rax. 31374a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(0)); 313843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, rax); 31394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org __ Move(rax, Smi::FromInt(info_->scope()->num_parameters())); 3140f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org ArgumentsAccessStub stub(isolate(), ArgumentsAccessStub::READ_ELEMENT); 31419dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CallStub(&stub); 31424a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 31439dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 31449dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 31459dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3146c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { 3147c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(expr->arguments()->length() == 0); 31489dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 314983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label exit; 31509dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Get the number of formal parameters. 31514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org __ Move(rax, Smi::FromInt(info_->scope()->num_parameters())); 31529dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 31539dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Check if the calling frame is an arguments adaptor frame. 315443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 3155badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org __ Cmp(Operand(rbx, StandardFrameConstants::kContextOffset), 3156badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 315783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_equal, &exit, Label::kNear); 31589dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 31599dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Arguments adaptor case: Read the arguments length from the 31609dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // adaptor frame. 316143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 31629dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 31639dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&exit); 3164c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org __ AssertSmi(rax); 31654a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 31669dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 31679dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 31689dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3169c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitClassOf(CallRuntime* expr) { 3170c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 31719dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 1); 31729dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label done, null, function, non_function_constructor; 31739dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 31744a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(0)); 31759dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 31769dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // If the object is a smi, we return null. 31779dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ JumpIfSmi(rax, &null); 31789dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 31799dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Check that the object is a JS object but take special care of JS 31809dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // functions to make sure they have 'Function' as their class. 3181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Assume that there are only two callable types, and one of them is at 3182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // either end of the type range for JS object types. Saves extra comparisons. 3183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 3184d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rax); 3185d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // Map is now in rax. 31869dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ j(below, &null); 3187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == 3188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FIRST_SPEC_OBJECT_TYPE + 1); 3189c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ j(equal, &function); 3190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CmpInstanceType(rax, LAST_SPEC_OBJECT_TYPE); 3192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == 3193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LAST_SPEC_OBJECT_TYPE - 1); 3194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ j(equal, &function); 3195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Assume that there is no larger type. 3196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE - 1); 3197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if the constructor in the map is a JS function. 319943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, FieldOperand(rax, Map::kConstructorOffset)); 32009dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); 32019dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ j(not_equal, &non_function_constructor); 32029dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32039dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // rax now contains the constructor function. Grab the 32049dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // instance class name from there. 320543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset)); 320643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, FieldOperand(rax, SharedFunctionInfo::kInstanceClassNameOffset)); 32079dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ jmp(&done); 32089dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32099dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Functions have class 'Function'. 32109dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&function); 32114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Move(rax, isolate()->factory()->function_class_string()); 32129dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ jmp(&done); 32139dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32149dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Objects with a non-function constructor have class 'Object'. 32159dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&non_function_constructor); 32164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Move(rax, isolate()->factory()->Object_string()); 32179dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ jmp(&done); 32189dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32199dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Non-JS objects have class null. 32209dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&null); 32219dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ LoadRoot(rax, Heap::kNullValueRootIndex); 32229dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32239dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // All done. 32249dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&done); 32259dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32264a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 32279dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 32289dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32299dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3230c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitSubString(CallRuntime* expr) { 32319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Load the arguments on the stack and call the stub. 3232f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org SubStringStub stub(isolate()); 3233c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 32349dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 3); 32354a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(0)); 32364a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(1)); 32374a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(2)); 32389dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CallStub(&stub); 32394a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 32409dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 32419dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32429dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3243c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { 32449dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Load the arguments on the stack and call the stub. 3245f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org RegExpExecStub stub(isolate()); 3246c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 32479dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 4); 32484a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(0)); 32494a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(1)); 32504a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(2)); 32514a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(3)); 32529dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CallStub(&stub); 32534a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 32549dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 32559dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32569dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3257c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitValueOf(CallRuntime* expr) { 3258c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 32599dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 1); 32609dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32614a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(0)); // Load the object. 32629dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32639dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label done; 32649dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // If the object is a smi return the object. 32659dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ JumpIfSmi(rax, &done); 32669dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // If the object is not a value type, return the object. 32679dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CmpObjectType(rax, JS_VALUE_TYPE, rbx); 32689dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ j(not_equal, &done); 326943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, FieldOperand(rax, JSValue::kValueOffset)); 32709dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32719dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&done); 32724a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 32739dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 32749dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32759dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32764efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.orgvoid FullCodeGenerator::EmitDateField(CallRuntime* expr) { 32774efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org ZoneList<Expression*>* args = expr->arguments(); 32784efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org ASSERT(args->length() == 2); 32794efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org ASSERT_NE(NULL, args->at(1)->AsLiteral()); 32801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value())); 32814efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 32824efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org VisitForAccumulatorValue(args->at(0)); // Load the object. 32834efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 3284de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org Label runtime, done, not_date_object; 32854efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org Register object = rax; 32864efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org Register result = rax; 32874efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org Register scratch = rcx; 32884efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 3289de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org __ JumpIfSmi(object, ¬_date_object); 32904efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ CmpObjectType(object, JS_DATE_TYPE, scratch); 3291de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org __ j(not_equal, ¬_date_object); 32924efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 32934efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org if (index->value() == 0) { 329443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, FieldOperand(object, JSDate::kValueOffset)); 3295de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org __ jmp(&done); 32964efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } else { 32974efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org if (index->value() < JSDate::kFirstUncachedField) { 32984efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org ExternalReference stamp = ExternalReference::date_cache_stamp(isolate()); 32996e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org Operand stamp_operand = __ ExternalOperand(stamp); 330043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(scratch, stamp_operand); 33017a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(scratch, FieldOperand(object, JSDate::kCacheStampOffset)); 33024efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ j(not_equal, &runtime, Label::kNear); 330343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, FieldOperand(object, JSDate::kValueOffset + 33044efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org kPointerSize * index->value())); 33054efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ jmp(&done); 33064efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } 33074efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ bind(&runtime); 33084efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ PrepareCallCFunction(2); 330943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(arg_reg_1, object); 3310af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org __ Move(arg_reg_2, index, Assembler::RelocInfoNone()); 33114efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 331243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 3313de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org __ jmp(&done); 33144efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } 3315de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 3316de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org __ bind(¬_date_object); 3317895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenThrowNotDateError, 0); 3318de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org __ bind(&done); 33194efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org context()->Plug(rax); 33204efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org} 33214efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 33224efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 332332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.orgvoid FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { 332432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org ZoneList<Expression*>* args = expr->arguments(); 332532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org ASSERT_EQ(3, args->length()); 332632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 3327a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register string = rax; 3328a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register index = rbx; 3329a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register value = rcx; 3330a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 333132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org VisitForStackValue(args->at(1)); // index 333232280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org VisitForStackValue(args->at(2)); // value 33339af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org VisitForAccumulatorValue(args->at(0)); // string 3334763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(value); 3335763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(index); 333632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 3337a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (FLAG_debug_code) { 333805150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org __ Check(__ CheckSmi(value), kNonSmiValue); 333905150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org __ Check(__ CheckSmi(index), kNonSmiValue); 3340a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 3341a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 3342a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ SmiToInteger32(value, value); 3343a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ SmiToInteger32(index, index); 33449af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 33459af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org if (FLAG_debug_code) { 33469af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 33479af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org __ EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type); 33489af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org } 33499af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 3350a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ movb(FieldOperand(string, index, times_1, SeqOneByteString::kHeaderSize), 3351a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org value); 3352a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org context()->Plug(string); 335332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org} 335432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 335532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 335632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.orgvoid FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { 335732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org ZoneList<Expression*>* args = expr->arguments(); 335832280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org ASSERT_EQ(3, args->length()); 335932280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 3360a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register string = rax; 3361a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register index = rbx; 3362a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Register value = rcx; 3363a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 336432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org VisitForStackValue(args->at(1)); // index 336532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org VisitForStackValue(args->at(2)); // value 33669af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org VisitForAccumulatorValue(args->at(0)); // string 3367763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(value); 3368763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(index); 336932280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 3370a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (FLAG_debug_code) { 337105150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org __ Check(__ CheckSmi(value), kNonSmiValue); 337205150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org __ Check(__ CheckSmi(index), kNonSmiValue); 3373a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 3374a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 3375a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ SmiToInteger32(value, value); 3376a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ SmiToInteger32(index, index); 33779af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 33789af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org if (FLAG_debug_code) { 33799af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 33809af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); 33819af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org } 33829af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 3383a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ movw(FieldOperand(string, index, times_2, SeqTwoByteString::kHeaderSize), 3384a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org value); 338532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org context()->Plug(rax); 338632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org} 338732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 338832280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 3389c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitMathPow(CallRuntime* expr) { 33909dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Load the arguments on the stack and call the runtime function. 3391c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 33929dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 2); 33934a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(0)); 33944a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(1)); 3395f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org MathPowStub stub(isolate(), MathPowStub::ON_STACK); 33969ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org __ CallStub(&stub); 33974a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 33989dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 33999dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 34009dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3401c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { 3402c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 34039dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 2); 34049dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 34054a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(0)); // Load the object. 34064a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(1)); // Load the value. 3407763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rbx); // rax = value. rbx = object. 34089dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 34099dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label done; 34109dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // If the object is a smi, return the value. 34119dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ JumpIfSmi(rbx, &done); 34129dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 34139dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // If the object is not a value type, return the value. 34149dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CmpObjectType(rbx, JS_VALUE_TYPE, rcx); 34159dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ j(not_equal, &done); 34169dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 34179dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Store the value. 341843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rbx, JSValue::kValueOffset), rax); 34199dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Update the write barrier. Save the value as it will be 34209dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // overwritten by the write barrier code and is needed afterward. 342143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, rax); 3422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ RecordWriteField(rbx, JSValue::kValueOffset, rdx, rcx, kDontSaveFPRegs); 34239dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 34249dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&done); 34254a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 34269dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 34279dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 34289dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3429c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { 3430c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 34319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT_EQ(args->length(), 1); 34329dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 34333d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // Load the argument into rax and call the stub. 34343d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 34359dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3436f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org NumberToStringStub stub(isolate()); 34379dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CallStub(&stub); 34384a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 34399dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 34409dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 34419dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3442c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { 3443c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 34449dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 1); 34459dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 34464a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(0)); 34479dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 344830ce411529579186181838984710b0b0980857aaricow@chromium.org Label done; 344930ce411529579186181838984710b0b0980857aaricow@chromium.org StringCharFromCodeGenerator generator(rax, rbx); 345030ce411529579186181838984710b0b0980857aaricow@chromium.org generator.GenerateFast(masm_); 345130ce411529579186181838984710b0b0980857aaricow@chromium.org __ jmp(&done); 34529dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 345330ce411529579186181838984710b0b0980857aaricow@chromium.org NopRuntimeCallHelper call_helper; 345430ce411529579186181838984710b0b0980857aaricow@chromium.org generator.GenerateSlow(masm_, call_helper); 34559dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 345630ce411529579186181838984710b0b0980857aaricow@chromium.org __ bind(&done); 34574a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rbx); 345830ce411529579186181838984710b0b0980857aaricow@chromium.org} 345930ce411529579186181838984710b0b0980857aaricow@chromium.org 346030ce411529579186181838984710b0b0980857aaricow@chromium.org 3461c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) { 3462c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 346330ce411529579186181838984710b0b0980857aaricow@chromium.org ASSERT(args->length() == 2); 346430ce411529579186181838984710b0b0980857aaricow@chromium.org 34654a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(0)); 34664a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(1)); 346730ce411529579186181838984710b0b0980857aaricow@chromium.org 346830ce411529579186181838984710b0b0980857aaricow@chromium.org Register object = rbx; 346930ce411529579186181838984710b0b0980857aaricow@chromium.org Register index = rax; 347030ce411529579186181838984710b0b0980857aaricow@chromium.org Register result = rdx; 347130ce411529579186181838984710b0b0980857aaricow@chromium.org 3472763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(object); 347330ce411529579186181838984710b0b0980857aaricow@chromium.org 347430ce411529579186181838984710b0b0980857aaricow@chromium.org Label need_conversion; 347530ce411529579186181838984710b0b0980857aaricow@chromium.org Label index_out_of_range; 347630ce411529579186181838984710b0b0980857aaricow@chromium.org Label done; 347730ce411529579186181838984710b0b0980857aaricow@chromium.org StringCharCodeAtGenerator generator(object, 347830ce411529579186181838984710b0b0980857aaricow@chromium.org index, 347930ce411529579186181838984710b0b0980857aaricow@chromium.org result, 348030ce411529579186181838984710b0b0980857aaricow@chromium.org &need_conversion, 348130ce411529579186181838984710b0b0980857aaricow@chromium.org &need_conversion, 348230ce411529579186181838984710b0b0980857aaricow@chromium.org &index_out_of_range, 348330ce411529579186181838984710b0b0980857aaricow@chromium.org STRING_INDEX_IS_NUMBER); 348430ce411529579186181838984710b0b0980857aaricow@chromium.org generator.GenerateFast(masm_); 34859dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ jmp(&done); 34869dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 348730ce411529579186181838984710b0b0980857aaricow@chromium.org __ bind(&index_out_of_range); 348830ce411529579186181838984710b0b0980857aaricow@chromium.org // When the index is out of range, the spec requires us to return 348930ce411529579186181838984710b0b0980857aaricow@chromium.org // NaN. 349030ce411529579186181838984710b0b0980857aaricow@chromium.org __ LoadRoot(result, Heap::kNanValueRootIndex); 349130ce411529579186181838984710b0b0980857aaricow@chromium.org __ jmp(&done); 349230ce411529579186181838984710b0b0980857aaricow@chromium.org 349330ce411529579186181838984710b0b0980857aaricow@chromium.org __ bind(&need_conversion); 349430ce411529579186181838984710b0b0980857aaricow@chromium.org // Move the undefined value into the result register, which will 349530ce411529579186181838984710b0b0980857aaricow@chromium.org // trigger conversion. 349630ce411529579186181838984710b0b0980857aaricow@chromium.org __ LoadRoot(result, Heap::kUndefinedValueRootIndex); 349730ce411529579186181838984710b0b0980857aaricow@chromium.org __ jmp(&done); 349830ce411529579186181838984710b0b0980857aaricow@chromium.org 349930ce411529579186181838984710b0b0980857aaricow@chromium.org NopRuntimeCallHelper call_helper; 350030ce411529579186181838984710b0b0980857aaricow@chromium.org generator.GenerateSlow(masm_, call_helper); 35019dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 35029dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&done); 35034a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(result); 35049dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 35059dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 35069dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3507c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) { 3508c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 350930ce411529579186181838984710b0b0980857aaricow@chromium.org ASSERT(args->length() == 2); 351030ce411529579186181838984710b0b0980857aaricow@chromium.org 35114a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(0)); 35124a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(1)); 351330ce411529579186181838984710b0b0980857aaricow@chromium.org 351430ce411529579186181838984710b0b0980857aaricow@chromium.org Register object = rbx; 351530ce411529579186181838984710b0b0980857aaricow@chromium.org Register index = rax; 3516c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Register scratch = rdx; 351730ce411529579186181838984710b0b0980857aaricow@chromium.org Register result = rax; 351830ce411529579186181838984710b0b0980857aaricow@chromium.org 3519763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(object); 352030ce411529579186181838984710b0b0980857aaricow@chromium.org 352130ce411529579186181838984710b0b0980857aaricow@chromium.org Label need_conversion; 352230ce411529579186181838984710b0b0980857aaricow@chromium.org Label index_out_of_range; 352330ce411529579186181838984710b0b0980857aaricow@chromium.org Label done; 352430ce411529579186181838984710b0b0980857aaricow@chromium.org StringCharAtGenerator generator(object, 352530ce411529579186181838984710b0b0980857aaricow@chromium.org index, 3526c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org scratch, 352730ce411529579186181838984710b0b0980857aaricow@chromium.org result, 352830ce411529579186181838984710b0b0980857aaricow@chromium.org &need_conversion, 352930ce411529579186181838984710b0b0980857aaricow@chromium.org &need_conversion, 353030ce411529579186181838984710b0b0980857aaricow@chromium.org &index_out_of_range, 353130ce411529579186181838984710b0b0980857aaricow@chromium.org STRING_INDEX_IS_NUMBER); 353230ce411529579186181838984710b0b0980857aaricow@chromium.org generator.GenerateFast(masm_); 353330ce411529579186181838984710b0b0980857aaricow@chromium.org __ jmp(&done); 353430ce411529579186181838984710b0b0980857aaricow@chromium.org 353530ce411529579186181838984710b0b0980857aaricow@chromium.org __ bind(&index_out_of_range); 353630ce411529579186181838984710b0b0980857aaricow@chromium.org // When the index is out of range, the spec requires us to return 353730ce411529579186181838984710b0b0980857aaricow@chromium.org // the empty string. 35384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ LoadRoot(result, Heap::kempty_stringRootIndex); 353930ce411529579186181838984710b0b0980857aaricow@chromium.org __ jmp(&done); 354030ce411529579186181838984710b0b0980857aaricow@chromium.org 354130ce411529579186181838984710b0b0980857aaricow@chromium.org __ bind(&need_conversion); 354230ce411529579186181838984710b0b0980857aaricow@chromium.org // Move smi zero into the result register, which will trigger 354330ce411529579186181838984710b0b0980857aaricow@chromium.org // conversion. 354430ce411529579186181838984710b0b0980857aaricow@chromium.org __ Move(result, Smi::FromInt(0)); 354530ce411529579186181838984710b0b0980857aaricow@chromium.org __ jmp(&done); 354630ce411529579186181838984710b0b0980857aaricow@chromium.org 354730ce411529579186181838984710b0b0980857aaricow@chromium.org NopRuntimeCallHelper call_helper; 354830ce411529579186181838984710b0b0980857aaricow@chromium.org generator.GenerateSlow(masm_, call_helper); 354930ce411529579186181838984710b0b0980857aaricow@chromium.org 355030ce411529579186181838984710b0b0980857aaricow@chromium.org __ bind(&done); 35514a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(result); 35529dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 35539dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 355430ce411529579186181838984710b0b0980857aaricow@chromium.org 3555c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { 3556c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 35579dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT_EQ(2, args->length()); 3558bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org VisitForStackValue(args->at(0)); 3559bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org VisitForAccumulatorValue(args->at(1)); 35609dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3561763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rdx); 3562f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); 3563bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org __ CallStub(&stub); 35644a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 35659dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 35669dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 35679dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3568c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { 3569c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 35709dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT_EQ(2, args->length()); 35719dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 35724a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(0)); 35734a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(1)); 35749dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3575f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org StringCompareStub stub(isolate()); 35769dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ CallStub(&stub); 35774a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 35789dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 35799dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 35809dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3581c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { 3582c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 35839dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() >= 2); 35849dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3585160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org int arg_count = args->length() - 2; // 2 ~ receiver and function. 3586160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org for (int i = 0; i < arg_count + 1; i++) { 3587160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org VisitForStackValue(args->at(i)); 35889dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 3589160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org VisitForAccumulatorValue(args->last()); // Function. 35909dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3591de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org Label runtime, done; 3592de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org // Check for non-function argument (including proxy). 3593de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org __ JumpIfSmi(rax, &runtime); 3594de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); 3595de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org __ j(not_equal, &runtime); 3596c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 3597160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // InvokeFunction requires the function in rdi. Move it in there. 359843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdi, result_register()); 35999dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ParameterCount count(arg_count); 3600e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ InvokeFunction(rdi, count, CALL_FUNCTION, NullCallWrapper()); 360143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 3602c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org __ jmp(&done); 3603c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 3604de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org __ bind(&runtime); 3605763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 3606c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org __ CallRuntime(Runtime::kCall, args->length()); 3607c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org __ bind(&done); 3608c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 36094a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 36109dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 36119dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 36129dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3613c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { 3614f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org RegExpConstructResultStub stub(isolate()); 3615c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 36169dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT(args->length() == 3); 36174a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(0)); 36184a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(args->at(1)); 361909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org VisitForAccumulatorValue(args->at(2)); 3620763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rbx); 3621763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rcx); 3622a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ CallStub(&stub); 36234a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 36249dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 36259dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 36269dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3627c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { 3628c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 36299dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT_EQ(2, args->length()); 36309dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 36319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com ASSERT_NE(NULL, args->at(0)->AsLiteral()); 36321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->value()))->value(); 36339dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 36349dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Handle<FixedArray> jsfunction_result_caches( 363546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org isolate()->native_context()->jsfunction_result_caches()); 36369dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com if (jsfunction_result_caches->length() <= cache_id) { 3637594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Abort(kAttemptToUseUndefinedCache); 36389dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 36394a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 36409dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com return; 36419dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 36429dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 36434a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(1)); 36449dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 36459dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Register key = rax; 36469dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Register cache = rbx; 36479dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Register tmp = rcx; 364843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(cache, ContextOperand(rsi, Context::GLOBAL_OBJECT_INDEX)); 364943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(cache, 365046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FieldOperand(cache, GlobalObject::kNativeContextOffset)); 365143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(cache, 36522ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org ContextOperand(cache, Context::JSFUNCTION_RESULT_CACHES_INDEX)); 365343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(cache, 36549dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com FieldOperand(cache, FixedArray::OffsetOfElementAt(cache_id))); 36559dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 365683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done, not_found; 365780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); 365843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(tmp, FieldOperand(cache, JSFunctionResultCache::kFingerOffset)); 36590a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org // tmp now holds finger offset as a smi. 36609dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com SmiIndex index = 36619dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ SmiToIndex(kScratchRegister, tmp, kPointerSizeLog2); 36627a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(key, FieldOperand(cache, 36639dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com index.reg, 36649dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com index.scale, 36659dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com FixedArray::kHeaderSize)); 366683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(not_equal, ¬_found, Label::kNear); 366743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, FieldOperand(cache, 36689dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com index.reg, 36699dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com index.scale, 36709dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com FixedArray::kHeaderSize + kPointerSize)); 367183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ jmp(&done, Label::kNear); 36729dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 36739dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(¬_found); 36749dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Call runtime to perform the lookup. 3675763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(cache); 3676763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(key); 36779b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org __ CallRuntime(Runtime::kHiddenGetFromCache, 2); 36789dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 36799dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ bind(&done); 36804a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 36819dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 36829dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 36839dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3684c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3685c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3686d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org ASSERT(args->length() == 1); 3687d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 36884a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(0)); 3689d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 3690d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Label materialize_true, materialize_false; 3691d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Label* if_true = NULL; 3692d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Label* if_false = NULL; 3693d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Label* fall_through = NULL; 36944a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 36954a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org &if_true, &if_false, &fall_through); 3696d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 3697d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ testl(FieldOperand(rax, String::kHashFieldOffset), 3698d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Immediate(String::kContainsCachedArrayIndexMask)); 3699c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3700d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ j(zero, if_true); 3701d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ jmp(if_false); 3702d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 37034a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(if_true, if_false); 3704d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 3705d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 3706d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 3707c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) { 3708c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3709d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org ASSERT(args->length() == 1); 37104a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(args->at(0)); 3711d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 3712c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org __ AssertString(rax); 37135d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 3714d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ movl(rax, FieldOperand(rax, String::kHashFieldOffset)); 3715d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org ASSERT(String::kHashShift >= kSmiTagSize); 3716d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ IndexFromHash(rax, rax); 3717d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 37184a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 3719d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 3720d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 3721d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 3722c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { 37237979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Label bailout, return_result, done, one_char_separator, long_separator, 37247979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org non_trivial_array, not_size_one_array, loop, 37257979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org loop_1, loop_1_condition, loop_2, loop_2_entry, loop_3, loop_3_entry; 3726c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ZoneList<Expression*>* args = expr->arguments(); 37277979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org ASSERT(args->length() == 2); 37287979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // We will leave the separator on the stack until the end of the function. 37297979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org VisitForStackValue(args->at(1)); 37307979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Load this to rax (= array) 37317979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org VisitForAccumulatorValue(args->at(0)); 37327979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // All aliases of the same register have disjoint lifetimes. 37337979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register array = rax; 37347979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register elements = no_reg; // Will be rax. 37357979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 37367979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register index = rdx; 37377979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 37387979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register string_length = rcx; 37397979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 37407979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register string = rsi; 37417979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 37427979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register scratch = rbx; 37437979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 37447979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register array_length = rdi; 37457979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register result_pos = no_reg; // Will be rdi. 37467979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 37477979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Operand separator_operand = Operand(rsp, 2 * kPointerSize); 37487979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Operand result_operand = Operand(rsp, 1 * kPointerSize); 37497979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Operand array_length_operand = Operand(rsp, 0 * kPointerSize); 37507979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Separator operand is already pushed. Make room for the two 37517979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // other stack fields, and clear the direction flag in anticipation 37527979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // of calling CopyBytes. 3753fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rsp, Immediate(2 * kPointerSize)); 37547979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ cld(); 37557979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Check that the array is a JSArray 37567979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ JumpIfSmi(array, &bailout); 37577979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ CmpObjectType(array, JS_ARRAY_TYPE, scratch); 37587979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ j(not_equal, &bailout); 37597979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 37607979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Check that the array has fast elements. 3761d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com __ CheckFastElements(scratch, &bailout); 37627979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 37637979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Array has fast elements, so its length must be a smi. 37647979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // If the array has length zero, return the empty string. 376543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(array_length, FieldOperand(array, JSArray::kLengthOffset)); 37667979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ SmiCompare(array_length, Smi::FromInt(0)); 37677979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ j(not_zero, &non_trivial_array); 37684a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ LoadRoot(rax, Heap::kempty_stringRootIndex); 37697979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ jmp(&return_result); 37707979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 37717979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Save the array length on the stack. 37727979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ bind(&non_trivial_array); 37737979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ SmiToInteger32(array_length, array_length); 37747979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ movl(array_length_operand, array_length); 37757979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 37767979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Save the FixedArray containing array's elements. 37777979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // End of array's live range. 37787979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org elements = array; 377943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(elements, FieldOperand(array, JSArray::kElementsOffset)); 37807979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org array = no_reg; 37817979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 37827979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 37837979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Check that all array elements are sequential ASCII strings, and 37847979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // accumulate the sum of their lengths, as a smi-encoded value. 37857979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ Set(index, 0); 37867979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ Set(string_length, 0); 37877979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Loop condition: while (index < array_length). 37887979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Live loop registers: index(int32), array_length(int32), string(String*), 37897979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // scratch, string_length(int32), elements(FixedArray*). 3790000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (generate_debug_code_) { 37917a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(index, array_length); 3792594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(below, kNoEmptyArraysHereInEmitFastAsciiArrayJoin); 37937979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } 37947979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ bind(&loop); 379543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(string, FieldOperand(elements, 37967979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org index, 37977979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org times_pointer_size, 37987979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org FixedArray::kHeaderSize)); 37997979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ JumpIfSmi(string, &bailout); 380043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(scratch, FieldOperand(string, HeapObject::kMapOffset)); 38017979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ movzxbl(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 38027979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ andb(scratch, Immediate( 38037979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); 3804e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ cmpb(scratch, Immediate(kStringTag | kOneByteStringTag | kSeqStringTag)); 38057979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ j(not_equal, &bailout); 38067979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ AddSmiField(string_length, 3807fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org FieldOperand(string, SeqOneByteString::kLengthOffset)); 38087979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ j(overflow, &bailout); 38097979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ incl(index); 38107979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ cmpl(index, array_length); 38117979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ j(less, &loop); 38127979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 38137979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Live registers: 38147979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // string_length: Sum of string lengths. 38157979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // elements: FixedArray of strings. 38167979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // index: Array length. 38177979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // array_length: Array length. 38187979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 38197979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // If array_length is 1, return elements[0], a string. 38207979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ cmpl(array_length, Immediate(1)); 38217979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ j(not_equal, ¬_size_one_array); 382243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, FieldOperand(elements, FixedArray::kHeaderSize)); 38237979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ jmp(&return_result); 38247979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 38257979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ bind(¬_size_one_array); 38267979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 38277979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // End of array_length live range. 38287979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org result_pos = array_length; 38297979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org array_length = no_reg; 38307979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 38317979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Live registers: 38327979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // string_length: Sum of string lengths. 38337979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // elements: FixedArray of strings. 38347979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // index: Array length. 38357979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 38367979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Check that the separator is a sequential ASCII string. 383743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(string, separator_operand); 38387979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ JumpIfSmi(string, &bailout); 383943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(scratch, FieldOperand(string, HeapObject::kMapOffset)); 38407979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ movzxbl(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 38417979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ andb(scratch, Immediate( 38427979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); 3843e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ cmpb(scratch, Immediate(kStringTag | kOneByteStringTag | kSeqStringTag)); 38447979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ j(not_equal, &bailout); 38457979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 38467979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Live registers: 38477979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // string_length: Sum of string lengths. 38487979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // elements: FixedArray of strings. 38497979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // index: Array length. 38507979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // string: Separator string. 38517979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 38527979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Add (separator length times (array_length - 1)) to string_length. 38537979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ SmiToInteger32(scratch, 3854fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org FieldOperand(string, SeqOneByteString::kLengthOffset)); 38557979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ decl(index); 38567979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ imull(scratch, index); 38577979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ j(overflow, &bailout); 38587979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ addl(string_length, scratch); 38597979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ j(overflow, &bailout); 38607979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 38617979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Live registers and stack values: 38627979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // string_length: Total length of result string. 38637979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // elements: FixedArray of strings. 38647979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ AllocateAsciiString(result_pos, string_length, scratch, 38657979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org index, string, &bailout); 386643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result_operand, result_pos); 3867895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(result_pos, FieldOperand(result_pos, SeqOneByteString::kHeaderSize)); 38687979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 386943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(string, separator_operand); 3870fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ SmiCompare(FieldOperand(string, SeqOneByteString::kLengthOffset), 38717979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Smi::FromInt(1)); 38727979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ j(equal, &one_char_separator); 38737979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ j(greater, &long_separator); 38747979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 38757979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 38767979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Empty separator case: 38777979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ Set(index, 0); 38787979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ movl(scratch, array_length_operand); 38797979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ jmp(&loop_1_condition); 38807979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Loop condition: while (index < array_length). 38817979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ bind(&loop_1); 38827979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Each iteration of the loop concatenates one string to the result. 38837979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Live values in registers: 38847979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // index: which element of the elements array we are adding to the result. 38857979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // result_pos: the position to which we are currently copying characters. 38867979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // elements: the FixedArray of strings we are joining. 38877979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // scratch: array length. 38887979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 38897979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Get string = array[index]. 389043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(string, FieldOperand(elements, index, 38917979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org times_pointer_size, 38927979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org FixedArray::kHeaderSize)); 38937979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ SmiToInteger32(string_length, 38947979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org FieldOperand(string, String::kLengthOffset)); 3895895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(string, 3896fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org FieldOperand(string, SeqOneByteString::kHeaderSize)); 38977979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ CopyBytes(result_pos, string, string_length); 38987979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ incl(index); 38997979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ bind(&loop_1_condition); 39007979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ cmpl(index, scratch); 39017979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ j(less, &loop_1); // Loop while (index < array_length). 39027979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ jmp(&done); 39037979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 39047979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Generic bailout code used from several places. 39057979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ bind(&bailout); 39067979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 39077979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ jmp(&return_result); 39087979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 39097979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 39107979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // One-character separator case 39117979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ bind(&one_char_separator); 39122efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Get the separator ASCII character value. 39137979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Register "string" holds the separator. 3914fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ movzxbl(scratch, FieldOperand(string, SeqOneByteString::kHeaderSize)); 39157979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ Set(index, 0); 39167979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Jump into the loop after the code that copies the separator, so the first 39177979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // element is not preceded by a separator 39187979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ jmp(&loop_2_entry); 39197979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Loop condition: while (index < length). 39207979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ bind(&loop_2); 39217979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Each iteration of the loop concatenates one string to the result. 39227979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Live values in registers: 39237979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // elements: The FixedArray of strings we are joining. 39247979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // index: which element of the elements array we are adding to the result. 39257979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // result_pos: the position to which we are currently copying characters. 39267979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // scratch: Separator character. 39277979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 39287979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Copy the separator character to the result. 39297979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ movb(Operand(result_pos, 0), scratch); 39307a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ incp(result_pos); 39317979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 39327979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ bind(&loop_2_entry); 39337979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Get string = array[index]. 393443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(string, FieldOperand(elements, index, 39357979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org times_pointer_size, 39367979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org FixedArray::kHeaderSize)); 39377979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ SmiToInteger32(string_length, 39387979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org FieldOperand(string, String::kLengthOffset)); 3939895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(string, 3940fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org FieldOperand(string, SeqOneByteString::kHeaderSize)); 39417979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ CopyBytes(result_pos, string, string_length); 39427979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ incl(index); 39437979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ cmpl(index, array_length_operand); 39447979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ j(less, &loop_2); // End while (index < length). 39457979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ jmp(&done); 39467979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 39477979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 39487979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Long separator case (separator is more than one character). 39497979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ bind(&long_separator); 39507979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 39517979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Make elements point to end of elements array, and index 39527979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // count from -array_length to zero, so we don't need to maintain 39537979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // a loop limit. 39547979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ movl(index, array_length_operand); 3955895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(elements, FieldOperand(elements, index, times_pointer_size, 39567979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org FixedArray::kHeaderSize)); 39577a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ negq(index); 39587979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 39597979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Replace separator string with pointer to its first character, and 39607979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // make scratch be its length. 396143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(string, separator_operand); 39627979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ SmiToInteger32(scratch, 39637979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org FieldOperand(string, String::kLengthOffset)); 3964895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(string, 3965fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org FieldOperand(string, SeqOneByteString::kHeaderSize)); 396643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(separator_operand, string); 39677979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 39687979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Jump into the loop after the code that copies the separator, so the first 39697979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // element is not preceded by a separator 39707979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ jmp(&loop_3_entry); 39717979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Loop condition: while (index < length). 39727979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ bind(&loop_3); 39737979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Each iteration of the loop concatenates one string to the result. 39747979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Live values in registers: 39757979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // index: which element of the elements array we are adding to the result. 39767979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // result_pos: the position to which we are currently copying characters. 39777979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // scratch: Separator length. 39787979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // separator_operand (rsp[0x10]): Address of first char of separator. 39797979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 39807979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Copy the separator to the result. 398143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(string, separator_operand); 39827979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ movl(string_length, scratch); 39837979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ CopyBytes(result_pos, string, string_length, 2); 39847979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 39857979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ bind(&loop_3_entry); 39867979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Get string = array[index]. 398743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(string, Operand(elements, index, times_pointer_size, 0)); 39887979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ SmiToInteger32(string_length, 39897979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org FieldOperand(string, String::kLengthOffset)); 3990895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(string, 3991fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org FieldOperand(string, SeqOneByteString::kHeaderSize)); 39927979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ CopyBytes(result_pos, string, string_length); 39937979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ incq(index); 39947979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ j(not_equal, &loop_3); // Loop while (index < 0). 39957979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 39967979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ bind(&done); 399743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, result_operand); 39987979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 39997979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ bind(&return_result); 40007979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Drop temp values from the stack, and restore context register. 4001fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rsp, Immediate(3 * kPointerSize)); 400243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 40037979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org context()->Plug(rax); 400421b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org} 400521b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org 400621b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org 4007b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 40089b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org if (expr->function() != NULL && 40099b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org expr->function()->intrinsic_type == Runtime::INLINE) { 40109dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Comment cmnt(masm_, "[ InlineRuntimeCall"); 40119dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com EmitInlineRuntimeCall(expr); 40129dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com return; 40139dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 40149dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 4015b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Comment cmnt(masm_, "[ CallRuntime"); 4016b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ZoneList<Expression*>* args = expr->arguments(); 4017a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org int arg_count = args->length(); 4018b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4019b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (expr->is_jsruntime()) { 4020a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Push the builtins object as receiver. 402143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, GlobalObjectOperand()); 4022763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); 4023b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4024a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Load the function from the receiver. 4025a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org __ movp(rax, Operand(rsp, 0)); 40265c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ Move(rcx, expr->name()); 4027a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); 4028a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 4029a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Push the target function under the receiver. 4030763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Operand(rsp, 0)); 4031a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org __ movp(Operand(rsp, kPointerSize), rax); 4032a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 4033a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Push the arguments ("left-to-right"). 4034a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org for (int i = 0; i < arg_count; i++) { 4035a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org VisitForStackValue(args->at(i)); 4036a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org } 4037a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 4038a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Record source position of the IC call. 4039a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org SetSourcePosition(expr->position()); 4040f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); 4041a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); 4042a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org __ CallStub(&stub); 4043a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 4044b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Restore context register. 404543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 4046a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org context()->DropAndPlug(1, rax); 4047a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 4048b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 4049a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Push the arguments ("left-to-right"). 4050a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org for (int i = 0; i < arg_count; i++) { 4051a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org VisitForStackValue(args->at(i)); 4052a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org } 4053a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 4054a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org // Call the C runtime. 4055b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ CallRuntime(expr->function(), arg_count); 4056a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org context()->Plug(rax); 4057b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4058b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4059b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4060b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4061b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 4062b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org switch (expr->op()) { 40639dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com case Token::DELETE: { 40649dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 4065486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Property* property = expr->expression()->AsProperty(); 4066486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org VariableProxy* proxy = expr->expression()->AsVariableProxy(); 406749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 4068486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (property != NULL) { 4069486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org VisitForStackValue(property->obj()); 4070486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org VisitForStackValue(property->key()); 4071486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org __ Push(Smi::FromInt(strict_mode())); 40724668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 40734668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org context()->Plug(rax); 4074486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } else if (proxy != NULL) { 4075486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org Variable* var = proxy->var(); 407649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Delete of an unqualified identifier is disallowed in strict mode 4077486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // but "delete this" is allowed. 4078486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org ASSERT(strict_mode() == SLOPPY || var->is_this()); 4079486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (var->IsUnallocated()) { 4080763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(GlobalObjectOperand()); 408149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org __ Push(var->name()); 4082486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org __ Push(Smi::FromInt(SLOPPY)); 408349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 408449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org context()->Plug(rax); 4085486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } else if (var->IsStackAllocated() || var->IsContextSlot()) { 4086486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Result of deleting non-global variables is false. 'this' is 4087486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // not really a variable, though we implement it as one. The 4088486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // subexpression does not have side effects. 4089486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org context()->Plug(var->is_this()); 409049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } else { 409149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Non-global variable. Call the runtime to try to delete from the 409249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // context where the variable was introduced. 4093763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(context_register()); 409449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org __ Push(var->name()); 4095895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenDeleteContextSlot, 2); 409649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org context()->Plug(rax); 409749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 4098496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org } else { 409949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Result of deleting non-property, non-variable reference is true. 410049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // The subexpression may have side effects. 410149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org VisitForEffect(expr->expression()); 410249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org context()->Plug(true); 41039dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 41049dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com break; 41059dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 41069dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 4107b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org case Token::VOID: { 4108b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Comment cmnt(masm_, "[ UnaryOperation (VOID)"); 4109b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org VisitForEffect(expr->expression()); 41104a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(Heap::kUndefinedValueRootIndex); 4111b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org break; 4112b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4113b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4114b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org case Token::NOT: { 4115b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Comment cmnt(masm_, "[ UnaryOperation (NOT)"); 41163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (context()->IsEffect()) { 41173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Unary NOT has no side effects so it's only necessary to visit the 41183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // subexpression. Match the optimizing compiler by not branching. 41193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org VisitForEffect(expr->expression()); 4120c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else if (context()->IsTest()) { 4121c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org const TestContext* test = TestContext::cast(context()); 4122c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // The labels are swapped for the recursive call. 4123c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org VisitForControl(expr->expression(), 4124c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org test->false_label(), 4125c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org test->true_label(), 4126c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org test->fall_through()); 4127c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org context()->Plug(test->true_label(), test->false_label()); 41283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } else { 4129c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // We handle value contexts explicitly rather than simply visiting 4130c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // for control and plugging the control flow into the context, 4131c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // because we need to prepare a pair of extra administrative AST ids 4132c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // for the optimizing compiler. 4133c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(context()->IsAccumulatorValue() || context()->IsStackValue()); 4134c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label materialize_true, materialize_false, done; 4135c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org VisitForControl(expr->expression(), 4136c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org &materialize_false, 4137c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org &materialize_true, 4138c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org &materialize_true); 4139c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&materialize_true); 4140c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 4141c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (context()->IsAccumulatorValue()) { 4142c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(rax, Heap::kTrueValueRootIndex); 4143c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 4144c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ PushRoot(Heap::kTrueValueRootIndex); 4145c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4146c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ jmp(&done, Label::kNear); 4147c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&materialize_false); 4148c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 4149c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (context()->IsAccumulatorValue()) { 4150c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ LoadRoot(rax, Heap::kFalseValueRootIndex); 4151c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } else { 4152c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ PushRoot(Heap::kFalseValueRootIndex); 4153c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 4154c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&done); 41553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 4156b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org break; 4157b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4158b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4159b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org case Token::TYPEOF: { 4160b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); 41614a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org { StackValueContext context(this); 41624a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForTypeofValue(expr->expression()); 41634a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 4164b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ CallRuntime(Runtime::kTypeof, 1); 41654a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 4166b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org break; 4167b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4168b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4169b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org default: 4170b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org UNREACHABLE(); 4171b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4172b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4173b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4174b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4175b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::VisitCountOperation(CountOperation* expr) { 41764edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org ASSERT(expr->expression()->IsValidReferenceExpression()); 41772904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org 4178b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Comment cmnt(masm_, "[ CountOperation"); 417965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org SetSourcePosition(expr->position()); 4180b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4181b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Expression can only be a property, a global or a (parameter or local) 41827b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org // slot. 4183b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 4184b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org LhsKind assign_type = VARIABLE; 4185b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Property* prop = expr->expression()->AsProperty(); 4186b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // In case of a property we use the uninitialized expression context 4187b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // of the key to detect a named property. 4188b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (prop != NULL) { 4189b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org assign_type = 4190b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; 4191b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4192b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4193b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Evaluate expression and get value. 4194b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (assign_type == VARIABLE) { 4195b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); 41964a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org AccumulatorValueContext context(this); 4197030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org EmitVariableLoad(expr->expression()->AsVariableProxy()); 41989dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } else { 4199b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Reserve space for result of postfix operation. 42004a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (expr->is_postfix() && !context()->IsEffect()) { 4201b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ Push(Smi::FromInt(0)); 4202b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4203b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (assign_type == NAMED_PROPERTY) { 42044a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(prop->obj()); 4205763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // Copy of receiver, needed for later store. 4206b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org EmitNamedPropertyLoad(prop); 4207b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 42087b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org VisitForStackValue(prop->obj()); 42097b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org VisitForAccumulatorValue(prop->key()); 421043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, Operand(rsp, 0)); // Leave receiver on stack 4211763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); // Copy of key, needed for later store. 4212b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org EmitKeyedPropertyLoad(prop); 4213b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4214b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4215b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4216d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // We need a second deoptimization point after loading the value 4217d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org // in case evaluating the property load my have a side effect. 4218c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (assign_type == VARIABLE) { 4219c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org PrepareForBailout(expr->expression(), TOS_REG); 4220c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } else { 4221471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org PrepareForBailoutForId(prop->LoadId(), TOS_REG); 4222c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } 4223d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 4224e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Inline smi case if we are in a loop. 4225e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label done, stub_call; 4226e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org JumpPatchSite patch_site(masm_); 4227ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if (ShouldInlineSmiCase(expr->op())) { 4228e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label slow; 4229e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org patch_site.EmitJumpIfNotSmi(rax, &slow, Label::kNear); 4230e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 4231e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Save result for postfix expressions. 4232e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (expr->is_postfix()) { 4233e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (!context()->IsEffect()) { 4234e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Save the result on the stack. If we have a named or keyed property 4235e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // we store the result under the receiver that is currently on top 4236e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // of the stack. 4237e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org switch (assign_type) { 4238e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org case VARIABLE: 4239763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 4240e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org break; 4241e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org case NAMED_PROPERTY: 424243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rsp, kPointerSize), rax); 4243e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org break; 4244e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org case KEYED_PROPERTY: 424543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rsp, 2 * kPointerSize), rax); 4246e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org break; 4247e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 4248e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 4249e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 4250e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 4251e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org SmiOperationExecutionMode mode; 4252e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org mode.Add(PRESERVE_SOURCE_REGISTER); 4253e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org mode.Add(BAILOUT_ON_NO_OVERFLOW); 4254e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (expr->op() == Token::INC) { 4255e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ SmiAddConstant(rax, rax, Smi::FromInt(1), mode, &done, Label::kNear); 4256e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else { 4257e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ SmiSubConstant(rax, rax, Smi::FromInt(1), mode, &done, Label::kNear); 4258e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 4259e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ jmp(&stub_call, Label::kNear); 4260e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ bind(&slow); 4261ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 4262e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 4263f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org ToNumberStub convert_stub(isolate()); 42647a392b3bfb39dbbc1ff22f0b53109aa5763fde57whesse@chromium.org __ CallStub(&convert_stub); 4265b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4266b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Save result for postfix expressions. 4267b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (expr->is_postfix()) { 42684a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (!context()->IsEffect()) { 42694a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // Save the result on the stack. If we have a named or keyed property 42704a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // we store the result under the receiver that is currently on top 42714a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // of the stack. 42724a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org switch (assign_type) { 42734a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org case VARIABLE: 4274763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 42754a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org break; 42764a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org case NAMED_PROPERTY: 427743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rsp, kPointerSize), rax); 42784a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org break; 42794a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org case KEYED_PROPERTY: 428043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rsp, 2 * kPointerSize), rax); 42814a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org break; 42824a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 4283b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4284b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4285b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Record position before stub call. 4287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org SetSourcePosition(expr->position()); 4288a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4289b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Call stub for +1/-1. 4290e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ bind(&stub_call); 429143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, rax); 4292fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ Move(rax, Smi::FromInt(1)); 4293f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org BinaryOpICStub stub(isolate(), expr->binary_op(), NO_OVERWRITE); 4294f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallIC(stub.GetCode(), expr->CountBinOpFeedbackId()); 42954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org patch_site.EmitPatchInfo(); 429683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org __ bind(&done); 4297d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 4298b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Store the value returned in rax. 4299b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org switch (assign_type) { 4300b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org case VARIABLE: 4301b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (expr->is_postfix()) { 43029dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Perform the assignment as if via '='. 43034a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org { EffectContext context(this); 43044a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 43054a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Token::ASSIGN); 4306d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 43075f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org context.Plug(rax); 43084a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 4309b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // For all contexts except kEffect: We have the result on 4310b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // top of the stack. 43114a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (!context()->IsEffect()) { 43124a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PlugTOS(); 4313b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4314b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 43159dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Perform the assignment as if via '='. 4316b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 43174a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Token::ASSIGN); 4318d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 43195f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org context()->Plug(rax); 4320b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4321b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org break; 4322b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org case NAMED_PROPERTY: { 43231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Move(rcx, prop->key()->AsLiteral()->value()); 4324763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rdx); 4325f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallStoreIC(expr->CountStoreFeedbackId()); 4326d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4327b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (expr->is_postfix()) { 43284a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (!context()->IsEffect()) { 43294a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PlugTOS(); 4330b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4331b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 43324a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 4333b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4334b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org break; 4335b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4336b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org case KEYED_PROPERTY: { 4337763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rcx); 4338763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rdx); 4339486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org Handle<Code> ic = strict_mode() == SLOPPY 43401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ? isolate()->builtins()->KeyedStoreIC_Initialize() 43411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4342f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallIC(ic, expr->CountStoreFeedbackId()); 4343d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4344b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (expr->is_postfix()) { 43454a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (!context()->IsEffect()) { 43464a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PlugTOS(); 4347b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4348b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 43494a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 4350b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4351b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org break; 4352b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4353b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4354b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4355b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4356b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 43574a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 435865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org VariableProxy* proxy = expr->AsVariableProxy(); 43594a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org ASSERT(!context()->IsEffect()); 43604a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org ASSERT(!context()->IsTest()); 43614a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 4362486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (proxy != NULL && proxy->var()->IsUnallocated()) { 4363f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Comment cmnt(masm_, "[ Global variable"); 436465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ Move(rcx, proxy->name()); 436543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, GlobalObjectOperand()); 436665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Use a regular load, not a contextual load, to avoid a reference 436765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // error. 43689cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org CallLoadIC(NOT_CONTEXTUAL); 4369d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org PrepareForBailout(expr, TOS_REG); 43704a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 4371486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { 4372f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Comment cmnt(masm_, "[ Lookup slot"); 43732ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org Label done, slow; 43742ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 43752ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // Generate code for loading from variables potentially shadowed 43762ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // by eval-introduced variables. 4377486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); 43782ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 43792ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org __ bind(&slow); 4380763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rsi); 438165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ Push(proxy->name()); 4382895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ CallRuntime(Runtime::kHiddenLoadContextSlotNoReferenceError, 2); 4383d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org PrepareForBailout(expr, TOS_REG); 43842ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org __ bind(&done); 43852ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 43864a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 43879dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } else { 438865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // This expression cannot throw a reference error at the top level. 4389c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org VisitInDuplicateContext(expr); 439065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } 439165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org} 439265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 439365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 439404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.orgvoid FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, 4395c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Expression* sub_expr, 4396c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Handle<String> check) { 4397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label materialize_true, materialize_false; 4398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* if_true = NULL; 4399c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* if_false = NULL; 4400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* fall_through = NULL; 4401c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com context()->PrepareTest(&materialize_true, &materialize_false, 4402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &if_true, &if_false, &fall_through); 4403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 44044a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org { AccumulatorValueContext context(this); 4405c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org VisitForTypeofValue(sub_expr); 44064a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 4407c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 44084a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 44092ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Factory* factory = isolate()->factory(); 44102ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (String::Equals(check, factory->number_string())) { 44118f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ JumpIfSmi(rax, if_true); 441243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, FieldOperand(rax, HeapObject::kMapOffset)); 441365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ CompareRoot(rax, Heap::kHeapNumberMapRootIndex); 441465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(equal, if_true, if_false, fall_through); 44152ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(check, factory->string_string())) { 44168f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ JumpIfSmi(rax, if_false); 441765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Check for undetectable objects => false. 44188f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx); 44198f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ j(above_equal, if_false); 442065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 442165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Immediate(1 << Map::kIsUndetectable)); 44228f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org Split(zero, if_true, if_false, fall_through); 44232ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(check, factory->symbol_string())) { 4424f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ JumpIfSmi(rax, if_false); 4425f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ CmpObjectType(rax, SYMBOL_TYPE, rdx); 4426f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Split(equal, if_true, if_false, fall_through); 44272ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(check, factory->boolean_string())) { 442865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ CompareRoot(rax, Heap::kTrueValueRootIndex); 44299dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ j(equal, if_true); 443065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ CompareRoot(rax, Heap::kFalseValueRootIndex); 443165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(equal, if_true, if_false, fall_through); 44324acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } else if (FLAG_harmony_typeof && 44332ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org String::Equals(check, factory->null_string())) { 44344acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ CompareRoot(rax, Heap::kNullValueRootIndex); 44354acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Split(equal, if_true, if_false, fall_through); 44362ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(check, factory->undefined_string())) { 443765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 44389dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com __ j(equal, if_true); 44398f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ JumpIfSmi(rax, if_false); 444065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Check for undetectable objects => true. 444143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, FieldOperand(rax, HeapObject::kMapOffset)); 444265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 44439dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Immediate(1 << Map::kIsUndetectable)); 444465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(not_zero, if_true, if_false, fall_through); 44452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(check, factory->function_string())) { 44468f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ JumpIfSmi(rax, if_false); 4447c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 4448c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CmpObjectType(rax, JS_FUNCTION_TYPE, rdx); 4449c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ j(equal, if_true); 4450c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CmpInstanceType(rdx, JS_FUNCTION_PROXY_TYPE); 4451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Split(equal, if_true, if_false, fall_through); 44522ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } else if (String::Equals(check, factory->object_string())) { 44538f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ JumpIfSmi(rax, if_false); 44544acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org if (!FLAG_harmony_typeof) { 44554acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ CompareRoot(rax, Heap::kNullValueRootIndex); 44564acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org __ j(equal, if_true); 44574acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 4458d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ CmpObjectType(rax, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, rdx); 44598f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org __ j(below, if_false); 4460d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ CmpInstanceType(rdx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 4461d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ j(above, if_false); 446265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Check for undetectable objects => false. 446365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 446465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Immediate(1 << Map::kIsUndetectable)); 44658f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org Split(zero, if_true, if_false, fall_through); 446665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } else { 446765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org if (if_false != fall_through) __ jmp(if_false); 44689dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 4469c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com context()->Plug(if_true, if_false); 44709dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 44719dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 44729dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 4473b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 4474b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Comment cmnt(masm_, "[ CompareOperation"); 447565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org SetSourcePosition(expr->position()); 4476b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4477c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // First we try a fast inlined version of the compare when one of 4478c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the operands is a literal. 4479c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (TryLiteralCompare(expr)) return; 4480c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4481b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Always perform the comparison for its control flow. Pack the result 4482b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // into the expression's context after the comparison is performed. 44839dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label materialize_true, materialize_false; 44849dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_true = NULL; 44859dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com Label* if_false = NULL; 448665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through = NULL; 44874a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 44884a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org &if_true, &if_false, &fall_through); 448965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 449004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org Token::Value op = expr->op(); 44914a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(expr->left()); 449265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org switch (op) { 4493b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org case Token::IN: 44944a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(expr->right()); 4495b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); 4496c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 4497b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ CompareRoot(rax, Heap::kTrueValueRootIndex); 449865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(equal, if_true, if_false, fall_through); 4499b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org break; 4500b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4501b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org case Token::INSTANCEOF: { 45024a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForStackValue(expr->right()); 4503f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org InstanceofStub stub(isolate(), InstanceofStub::kNoFlags); 4504b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ CallStub(&stub); 4505c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 45067a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rax, rax); 450765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // The stub returns 0 for true. 450865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(zero, if_true, if_false, fall_through); 4509b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org break; 4510b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4511b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4512b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org default: { 45134a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org VisitForAccumulatorValue(expr->right()); 4514fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Condition cc = CompareIC::ComputeCondition(op); 4515763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rdx); 4516b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4517d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com bool inline_smi_code = ShouldInlineSmiCase(op); 4518d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com JumpPatchSite patch_site(masm_); 4519d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com if (inline_smi_code) { 452083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label slow_case; 452143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, rdx); 4522895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ orp(rcx, rax); 452383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); 45247a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rdx, rax); 452565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(cc, if_true, if_false, NULL); 452665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org __ bind(&slow_case); 452765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } 4528b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4529d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // Record position and call the compare IC. 4530d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com SetSourcePosition(expr->position()); 45318432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 4532f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallIC(ic, expr->CompareOperationFeedbackId()); 45334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org patch_site.EmitPatchInfo(); 4534d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org 4535c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 45367a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rax, rax); 453765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(cc, if_true, if_false, fall_through); 4538b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4539b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4540b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4541b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Convert the result of the comparison into one expected for this 4542b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // expression's context. 45434a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(if_true, if_false); 4544b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4545b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4546b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4547c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, 4548c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Expression* sub_expr, 4549c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NilValue nil) { 455065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label materialize_true, materialize_false; 455165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* if_true = NULL; 455265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* if_false = NULL; 455365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* fall_through = NULL; 45544a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 45554a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org &if_true, &if_false, &fall_through); 455665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 4557c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VisitForAccumulatorValue(sub_expr); 4558c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4559837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org if (expr->op() == Token::EQ_STRICT) { 4560ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Heap::RootListIndex nil_value = nil == kNullValue ? 4561ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Heap::kNullValueRootIndex : 4562ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Heap::kUndefinedValueRootIndex; 4563ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org __ CompareRoot(rax, nil_value); 456465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(equal, if_true, if_false, fall_through); 456565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } else { 4566837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); 4567f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallIC(ic, expr->CompareOperationFeedbackId()); 45687a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rax, rax); 456965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Split(not_zero, if_true, if_false, fall_through); 457065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } 45714a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(if_true, if_false); 457265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org} 457365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 457465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 4575b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 457643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 45774a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org context()->Plug(rax); 4578b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4579b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4580b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4581c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.orgRegister FullCodeGenerator::result_register() { 4582c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org return rax; 4583c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org} 4584c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 4585c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 4586c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.orgRegister FullCodeGenerator::context_register() { 4587c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org return rsi; 4588c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org} 4589c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 4590b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4591b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 4592b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(IsAligned(frame_offset, kPointerSize)); 459343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rbp, frame_offset), value); 4594b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4595b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4596b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4597b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::LoadContextField(Register dst, int context_index) { 459843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(dst, ContextOperand(rsi, context_index)); 4599b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4600b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4601b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 46023cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgvoid FullCodeGenerator::PushFunctionArgumentForContextAllocation() { 46034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Scope* declaration_scope = scope()->DeclarationScope(); 4604ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if (declaration_scope->is_global_scope() || 4605ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com declaration_scope->is_module_scope()) { 460646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Contexts nested in the native context have a canonical empty function 46073cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // as their closure, not the anonymous closure containing the global 46083cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // code. Pass a smi sentinel and let the runtime look up the empty 46093cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // function. 46103cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org __ Push(Smi::FromInt(0)); 46114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } else if (declaration_scope->is_eval_scope()) { 46123cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Contexts created by a call to eval have the same closure as the 46133cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // context calling eval, not the anonymous closure containing the eval 46143cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // code. Fetch it from the context. 4615763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(ContextOperand(rsi, Context::CLOSURE_INDEX)); 46163cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } else { 46174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(declaration_scope->is_function_scope()); 4618763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 46193cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 46203cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org} 46213cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 46223cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 4623b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// ---------------------------------------------------------------------------- 4624b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Non-local control flow support. 4625b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4626b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4627b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::EnterFinallyBlock() { 4628b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(!result_register().is(rdx)); 4629b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(!result_register().is(rcx)); 4630b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Cook return address on top of stack (smi encoded Code* delta) 4631594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ PopReturnAddressTo(rdx); 4632b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ Move(rcx, masm_->CodeObject()); 4633fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rdx, rcx); 4634b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ Integer32ToSmi(rdx, rdx); 4635763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rdx); 46367028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 4637b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Store result register while executing finally block. 4638763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(result_register()); 46397028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 46407028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Store pending message while executing finally block. 46417028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ExternalReference pending_message_obj = 46427028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ExternalReference::address_of_pending_message_obj(isolate()); 46437028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ Load(rdx, pending_message_obj); 4644763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rdx); 46457028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 46467028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ExternalReference has_pending_message = 46477028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ExternalReference::address_of_has_pending_message(isolate()); 46487028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ Load(rdx, has_pending_message); 4649753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org __ Integer32ToSmi(rdx, rdx); 4650763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rdx); 46517028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 46527028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ExternalReference pending_message_script = 46537028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ExternalReference::address_of_pending_message_script(isolate()); 46547028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ Load(rdx, pending_message_script); 4655763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rdx); 4656b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4657b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4658b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4659b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid FullCodeGenerator::ExitFinallyBlock() { 4660b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(!result_register().is(rdx)); 4661b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(!result_register().is(rcx)); 46627028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Restore pending message from stack. 4663763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rdx); 46647028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ExternalReference pending_message_script = 46657028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ExternalReference::address_of_pending_message_script(isolate()); 46667028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ Store(pending_message_script, rdx); 46677028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 4668763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rdx); 4669753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org __ SmiToInteger32(rdx, rdx); 46707028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ExternalReference has_pending_message = 46717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ExternalReference::address_of_has_pending_message(isolate()); 46727028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ Store(has_pending_message, rdx); 46737028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 4674763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rdx); 46757028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ExternalReference pending_message_obj = 46767028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ExternalReference::address_of_pending_message_obj(isolate()); 46777028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ Store(pending_message_obj, rdx); 46787028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 46797028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Restore result register from stack. 4680763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(result_register()); 46817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 4682b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Uncook return address. 4683763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rdx); 4684b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ SmiToInteger32(rdx, rdx); 4685b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ Move(rcx, masm_->CodeObject()); 4686fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rdx, rcx); 46874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org __ jmp(rdx); 4688b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4689b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4690b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4691b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#undef __ 4692b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4693486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org#define __ ACCESS_MASM(masm()) 4694486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 4695486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.orgFullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit( 4696486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org int* stack_depth, 4697486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org int* context_length) { 4698486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // The macros used here must preserve the result register. 4699486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 4700486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Because the handler block contains the context of the finally 4701486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // code, we can restore it directly from there for the finally code 4702486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // rather than iteratively unwinding contexts via their previous 4703486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // links. 4704486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ Drop(*stack_depth); // Down to the handler block. 4705486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org if (*context_length > 0) { 4706486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org // Restore the context to its dedicated register and the stack. 470743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rsp, StackHandlerConstants::kContextOffset)); 470843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rsi); 4709486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org } 4710486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ PopTryHandler(); 4711486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org __ call(finally_entry_); 4712486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 4713486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org *stack_depth = 0; 4714486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org *context_length = 0; 4715486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org return previous_; 4716486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org} 4717486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 4718486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org 4719486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org#undef __ 4720b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4721528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 4722528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgstatic const byte kJnsInstruction = 0x79; 4723528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgstatic const byte kNopByteOne = 0x66; 4724528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgstatic const byte kNopByteTwo = 0x90; 4725afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org#ifdef DEBUG 4726afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.orgstatic const byte kCallInstruction = 0xe8; 4727afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org#endif 4728528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 4729528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 4730528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid BackEdgeTable::PatchAt(Code* unoptimized_code, 47318e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org Address pc, 47328e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org BackEdgeState target_state, 4733528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Code* replacement_code) { 47348e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org Address call_target_address = pc - kIntSize; 47358e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org Address jns_instr_address = call_target_address - 3; 47368e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org Address jns_offset_address = call_target_address - 2; 47378e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 47388e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org switch (target_state) { 47398e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org case INTERRUPT: 47408e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // sub <profiling_counter>, <delta> ;; Not changed 47418e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // jns ok 47428e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // call <interrupt stub> 47438e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // ok: 47448e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org *jns_instr_address = kJnsInstruction; 47458e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org *jns_offset_address = kJnsOffset; 47468e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org break; 47478e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org case ON_STACK_REPLACEMENT: 47488e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org case OSR_AFTER_STACK_CHECK: 47498e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // sub <profiling_counter>, <delta> ;; Not changed 47508e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // nop 47518e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // nop 47528e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // call <on-stack replacment> 47538e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // ok: 47548e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org *jns_instr_address = kNopByteOne; 47558e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org *jns_offset_address = kNopByteTwo; 47568e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org break; 47578e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org } 47588e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 4759528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Assembler::set_target_address_at(call_target_address, 476097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org unoptimized_code, 4761528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org replacement_code->entry()); 4762528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org unoptimized_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( 4763528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org unoptimized_code, call_target_address, replacement_code); 4764528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 4765528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 4766528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 4767528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgBackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState( 4768528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Isolate* isolate, 4769528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Code* unoptimized_code, 47708e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org Address pc) { 47718e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org Address call_target_address = pc - kIntSize; 47728e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org Address jns_instr_address = call_target_address - 3; 4773528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org ASSERT_EQ(kCallInstruction, *(call_target_address - 1)); 47748e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 47758e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org if (*jns_instr_address == kJnsInstruction) { 47768e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org ASSERT_EQ(kJnsOffset, *(call_target_address - 2)); 47778e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org ASSERT_EQ(isolate->builtins()->InterruptCheck()->entry(), 477897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org Assembler::target_address_at(call_target_address, 477997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org unoptimized_code)); 4780528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return INTERRUPT; 4781528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 47828e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 47838e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org ASSERT_EQ(kNopByteOne, *jns_instr_address); 47848e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org ASSERT_EQ(kNopByteTwo, *(call_target_address - 2)); 47858e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 478697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org if (Assembler::target_address_at(call_target_address, 478797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org unoptimized_code) == 47888e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org isolate->builtins()->OnStackReplacement()->entry()) { 47898e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org return ON_STACK_REPLACEMENT; 47908e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org } 47918e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 47928e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 479397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org Assembler::target_address_at(call_target_address, 479497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org unoptimized_code)); 47958e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org return OSR_AFTER_STACK_CHECK; 4796528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 4797528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 4798528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 4799b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} } // namespace v8::internal 48009dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 48019dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_X64 4802