15d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// Redistribution and use in source and binary forms, with or without 365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// modification, are permitted provided that the following conditions are 465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// met: 565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// 665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// * Redistributions of source code must retain the above copyright 765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// notice, this list of conditions and the following disclaimer. 865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// * Redistributions in binary form must reproduce the above 965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// copyright notice, this list of conditions and the following 1065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// disclaimer in the documentation and/or other materials provided 1165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// with the distribution. 1265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// * Neither the name of Google Inc. nor the names of its 1365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// contributors may be used to endorse or promote products derived 1465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// from this software without specific prior written permission. 1565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// 1665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 2865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#ifndef V8_X64_CODE_STUBS_X64_H_ 2965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#define V8_X64_CODE_STUBS_X64_H_ 3065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 3165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "ic-inl.h" 32d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org#include "type-info.h" 3365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 3465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgnamespace v8 { 3565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgnamespace internal { 3665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 3765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 38ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvoid ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code); 39ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 4065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// Compute a transcendental math function natively, or call the 4165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// TranscendentalCache runtime function. 42a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass TranscendentalCacheStub: public PlatformCodeStub { 4365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org public: 445d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org enum ArgumentType { 455d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org TAGGED = 0, 465d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits 475d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org }; 485d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 495d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org explicit TranscendentalCacheStub(TranscendentalCache::Type type, 505d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org ArgumentType argument_type) 515d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org : type_(type), argument_type_(argument_type) {} 5265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org void Generate(MacroAssembler* masm); 539a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org static void GenerateOperation(MacroAssembler* masm, 549a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org TranscendentalCache::Type type); 5565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org private: 5665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org TranscendentalCache::Type type_; 575d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org ArgumentType argument_type_; 585d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 5965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Major MajorKey() { return TranscendentalCache; } 605d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org int MinorKey() { return type_ | argument_type_; } 6165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Runtime::FunctionId RuntimeFunction(); 6265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}; 6365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 6465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 65a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass StoreBufferOverflowStub: public PlatformCodeStub { 66c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 67c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp) 68c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : save_doubles_(save_fp) { } 69c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 70c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Generate(MacroAssembler* masm); 71c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 728432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate); 73c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual bool SometimesSetsUpAFrame() { return false; } 74c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 75c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 76c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_doubles_; 77c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 78c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Major MajorKey() { return StoreBufferOverflow; } 79c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; } 80c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 81c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 82c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 8365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgclass StringHelper : public AllStatic { 8465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org public: 8565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Generate code for copying characters using a simple loop. This should only 8665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // be used in places where the number of characters is small and the 8765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // additional setup and checking in GenerateCopyCharactersREP adds too much 8865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // overhead. Copying of overlapping regions is not supported. 8965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org static void GenerateCopyCharacters(MacroAssembler* masm, 9065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register dest, 9165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register src, 9265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register count, 9365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org bool ascii); 9465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 9565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Generate code for copying characters using the rep movs instruction. 9665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Copies rcx characters from rsi to rdi. Copying of overlapping regions is 9765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // not supported. 9865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org static void GenerateCopyCharactersREP(MacroAssembler* masm, 9965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register dest, // Must be rdi. 10065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register src, // Must be rsi. 10165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register count, // Must be rcx. 10265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org bool ascii); 10365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 10465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 1054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Probe the string table for a two character string. If the string is 10665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // not found by probing a jump to the label not_found is performed. This jump 1074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // does not guarantee that the string is not in the string table. If the 10865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // string is found the code falls through with the string in register rax. 1094a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org static void GenerateTwoCharacterStringTableProbe(MacroAssembler* masm, 11065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register c1, 11165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register c2, 11265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register scratch1, 11365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register scratch2, 11465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register scratch3, 11565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register scratch4, 11665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label* not_found); 11765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 11865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Generate string hash. 11965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org static void GenerateHashInit(MacroAssembler* masm, 12065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register hash, 12165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register character, 12265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register scratch); 12365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org static void GenerateHashAddCharacter(MacroAssembler* masm, 12465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register hash, 12565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register character, 12665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register scratch); 12765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org static void GenerateHashGetHash(MacroAssembler* masm, 12865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register hash, 12965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register scratch); 13065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 13165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org private: 13265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper); 13365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}; 13465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 13565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 136a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass StringAddStub: public PlatformCodeStub { 13765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org public: 1383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org explicit StringAddStub(StringAddFlags flags) : flags_(flags) {} 13965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 14065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org private: 14165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Major MajorKey() { return StringAdd; } 1423a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int MinorKey() { return flags_; } 14365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 14465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org void Generate(MacroAssembler* masm); 14565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 1463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org void GenerateConvertArgument(MacroAssembler* masm, 1473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int stack_offset, 1483a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register arg, 1493a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register scratch1, 1503a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register scratch2, 1513a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Register scratch3, 1523a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Label* slow); 1533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1544e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org void GenerateRegisterArgsPush(MacroAssembler* masm); 1554e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org void GenerateRegisterArgsPop(MacroAssembler* masm, Register temp); 1564e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 1573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org const StringAddFlags flags_; 15865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}; 15965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 16065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 161a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass SubStringStub: public PlatformCodeStub { 16265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org public: 16365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org SubStringStub() {} 16465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 16565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org private: 16665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Major MajorKey() { return SubString; } 16765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org int MinorKey() { return 0; } 16865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 16965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org void Generate(MacroAssembler* masm); 17065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}; 17165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 17265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 173a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass StringCompareStub: public PlatformCodeStub { 17465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org public: 1751c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org StringCompareStub() {} 17665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 1771c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org // Compares two flat ASCII strings and returns result in rax. 17865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm, 17965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register left, 18065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register right, 18165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register scratch1, 18265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register scratch2, 18365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register scratch3, 18465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register scratch4); 18565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 1861c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org // Compares two flat ASCII strings for equality and returns result 1871c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org // in rax. 1881c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org static void GenerateFlatAsciiStringEquals(MacroAssembler* masm, 1891c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Register left, 1901c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Register right, 1911c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Register scratch1, 1921c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Register scratch2); 19365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 1941c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org private: 1951c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org virtual Major MajorKey() { return StringCompare; } 1961c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org virtual int MinorKey() { return 0; } 1971c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org virtual void Generate(MacroAssembler* masm); 1981c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 19983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static void GenerateAsciiCharsCompareLoop( 20083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org MacroAssembler* masm, 20183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register left, 20283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register right, 20383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register length, 20483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register scratch, 20583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* chars_not_equal, 20683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 20765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}; 20865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 20965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 210750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgclass NameDictionaryLookupStub: public PlatformCodeStub { 2111c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org public: 2121c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP }; 2131c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 214750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org NameDictionaryLookupStub(Register dictionary, 215750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Register result, 216750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Register index, 217750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org LookupMode mode) 2181c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org : dictionary_(dictionary), result_(result), index_(index), mode_(mode) { } 2191c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 2201c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org void Generate(MacroAssembler* masm); 2211c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 222394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com static void GenerateNegativeLookup(MacroAssembler* masm, 223394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label* miss, 224394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label* done, 225394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register properties, 226750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Name> name, 227394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register r0); 228394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2291c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org static void GeneratePositiveLookup(MacroAssembler* masm, 2301c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Label* miss, 2311c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Label* done, 2321c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Register elements, 2331c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Register name, 2341c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Register r0, 2351c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Register r1); 2361c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual bool SometimesSetsUpAFrame() { return false; } 238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2391c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org private: 2401c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org static const int kInlinedProbes = 4; 2411c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org static const int kTotalProbes = 20; 2421c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 2431c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org static const int kCapacityOffset = 244750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org NameDictionary::kHeaderSize + 245750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org NameDictionary::kCapacityIndex * kPointerSize; 2461c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 2471c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org static const int kElementsStartOffset = 248750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org NameDictionary::kHeaderSize + 249750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org NameDictionary::kElementsStartIndex * kPointerSize; 2501c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 251750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Major MajorKey() { return NameDictionaryLookup; } 2521c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 2531c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org int MinorKey() { 2541c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org return DictionaryBits::encode(dictionary_.code()) | 2551c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org ResultBits::encode(result_.code()) | 2561c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org IndexBits::encode(index_.code()) | 2571c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org LookupModeBits::encode(mode_); 2581c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org } 2591c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 2601c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org class DictionaryBits: public BitField<int, 0, 4> {}; 2611c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org class ResultBits: public BitField<int, 4, 4> {}; 2621c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org class IndexBits: public BitField<int, 8, 4> {}; 2631c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org class LookupModeBits: public BitField<LookupMode, 12, 1> {}; 2641c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 2651c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Register dictionary_; 2661c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Register result_; 2671c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Register index_; 2681c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org LookupMode mode_; 2691c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org}; 2701c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 2711c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 272a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass RecordWriteStub: public PlatformCodeStub { 273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RecordWriteStub(Register object, 275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register address, 277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action, 278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode fp_mode) 279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : object_(object), 280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com value_(value), 281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address_(address), 282c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com remembered_set_action_(remembered_set_action), 283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com save_fp_regs_mode_(fp_mode), 284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com regs_(object, // An input reg. 285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address, // An input reg. 286c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com value) { // One scratch reg. 287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 288c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 289c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com enum Mode { 290c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STORE_BUFFER_ONLY, 291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com INCREMENTAL, 292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com INCREMENTAL_COMPACTION 293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }; 294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual bool SometimesSetsUpAFrame() { return false; } 296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 297c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const byte kTwoByteNopInstruction = 0x3c; // Cmpb al, #imm8. 298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const byte kTwoByteJumpInstruction = 0xeb; // Jmp #imm8. 299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const byte kFiveByteNopInstruction = 0x3d; // Cmpl eax, #imm32. 301c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const byte kFiveByteJumpInstruction = 0xe9; // Jmp #imm32. 302c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 303c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static Mode GetMode(Code* stub) { 304c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com byte first_instruction = stub->instruction_start()[0]; 305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com byte second_instruction = stub->instruction_start()[2]; 306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (first_instruction == kTwoByteJumpInstruction) { 308c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return INCREMENTAL; 309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 311c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(first_instruction == kTwoByteNopInstruction); 312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (second_instruction == kFiveByteJumpInstruction) { 314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return INCREMENTAL_COMPACTION; 315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 317c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(second_instruction == kFiveByteNopInstruction); 318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 319c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return STORE_BUFFER_ONLY; 320c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 321c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static void Patch(Code* stub, Mode mode) { 323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com switch (mode) { 324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case STORE_BUFFER_ONLY: 325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(GetMode(stub) == INCREMENTAL || 326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com GetMode(stub) == INCREMENTAL_COMPACTION); 327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com stub->instruction_start()[0] = kTwoByteNopInstruction; 328c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com stub->instruction_start()[2] = kFiveByteNopInstruction; 329c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case INCREMENTAL: 331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(GetMode(stub) == STORE_BUFFER_ONLY); 332c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com stub->instruction_start()[0] = kTwoByteJumpInstruction; 333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 334c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case INCREMENTAL_COMPACTION: 335c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(GetMode(stub) == STORE_BUFFER_ONLY); 336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com stub->instruction_start()[0] = kTwoByteNopInstruction; 337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com stub->instruction_start()[2] = kFiveByteJumpInstruction; 338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(GetMode(stub) == mode); 341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CPU::FlushICache(stub->instruction_start(), 7); 342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // This is a helper class for freeing up 3 scratch registers, where the third 346c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // is always rcx (needed for shift operations). The input is two registers 347c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // that must be preserved and one scratch register provided by the caller. 348c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com class RegisterAllocation { 349c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 350c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RegisterAllocation(Register object, 351c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register address, 352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch0) 353c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : object_orig_(object), 354c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address_orig_(address), 355c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com scratch0_orig_(scratch0), 356c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com object_(object), 357c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address_(address), 358c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com scratch0_(scratch0) { 359c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(scratch0, object, address, no_reg)); 360c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com scratch1_ = GetRegThatIsNotRcxOr(object_, address_, scratch0_); 361c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (scratch0.is(rcx)) { 362c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com scratch0_ = GetRegThatIsNotRcxOr(object_, address_, scratch1_); 363c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 364c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (object.is(rcx)) { 365c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com object_ = GetRegThatIsNotRcxOr(address_, scratch0_, scratch1_); 366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (address.is(rcx)) { 368c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address_ = GetRegThatIsNotRcxOr(object_, scratch0_, scratch1_); 369c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(scratch0_, object_, address_, rcx)); 371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Save(MacroAssembler* masm) { 374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!address_orig_.is(object_)); 375c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(object_.is(object_orig_) || address_.is(address_orig_)); 376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(object_, address_, scratch1_, scratch0_)); 377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(object_orig_, address_, scratch1_, scratch0_)); 378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(object_, address_orig_, scratch1_, scratch0_)); 379c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // We don't have to save scratch0_orig_ because it was given to us as 380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a scratch register. But if we had to switch to a different reg then 381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // we should save the new scratch0_. 382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!scratch0_.is(scratch0_orig_)) masm->push(scratch0_); 383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!rcx.is(scratch0_orig_) && 384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com !rcx.is(object_orig_) && 385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com !rcx.is(address_orig_)) { 386c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->push(rcx); 387c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->push(scratch1_); 389c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!address_.is(address_orig_)) { 390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->push(address_); 391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->movq(address_, address_orig_); 392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!object_.is(object_orig_)) { 394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->push(object_); 395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->movq(object_, object_orig_); 396c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 399c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Restore(MacroAssembler* masm) { 400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // These will have been preserved the entire time, so we just need to move 401c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // them back. Only in one case is the orig_ reg different from the plain 402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // one, since only one of them can alias with rcx. 403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!object_.is(object_orig_)) { 404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->movq(object_orig_, object_); 405c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->pop(object_); 406c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 407c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!address_.is(address_orig_)) { 408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->movq(address_orig_, address_); 409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->pop(address_); 410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->pop(scratch1_); 412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!rcx.is(scratch0_orig_) && 413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com !rcx.is(object_orig_) && 414c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com !rcx.is(address_orig_)) { 415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->pop(rcx); 416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!scratch0_.is(scratch0_orig_)) masm->pop(scratch0_); 418c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 419c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If we have to call into C then we need to save and restore all caller- 421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // saved registers that were not already preserved. 422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 423c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The three scratch registers (incl. rcx) will be restored by other means 424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // so we don't bother pushing them here. Rbx, rbp and r12-15 are callee 425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // save and don't need to be preserved. 426c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) { 427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->PushCallerSaved(mode, scratch0_, scratch1_, rcx); 428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 430c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline void RestoreCallerSaveRegisters(MacroAssembler*masm, 431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode mode) { 432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->PopCallerSaved(mode, scratch0_, scratch1_, rcx); 433c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 434c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 435c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline Register object() { return object_; } 436c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline Register address() { return address_; } 437c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline Register scratch0() { return scratch0_; } 438c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline Register scratch1() { return scratch1_; } 439c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 440c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 441c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object_orig_; 442c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register address_orig_; 443c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch0_orig_; 444c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object_; 445c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register address_; 446c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch0_; 447c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch1_; 448c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Third scratch register is always rcx. 449c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 450c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register GetRegThatIsNotRcxOr(Register r1, 451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register r2, 452c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register r3) { 453a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org for (int i = 0; i < Register::NumAllocatableRegisters(); i++) { 454c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register candidate = Register::FromAllocationIndex(i); 455c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (candidate.is(rcx)) continue; 456c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (candidate.is(r1)) continue; 457c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (candidate.is(r2)) continue; 458c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (candidate.is(r3)) continue; 459c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return candidate; 460c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 461c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com UNREACHABLE(); 462c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return no_reg; 463c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 464c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com friend class RecordWriteStub; 465c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }; 466c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 467c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com enum OnNoNeedToInformIncrementalMarker { 468c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kReturnOnNoNeedToInformIncrementalMarker, 469c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kUpdateRememberedSetOnNoNeedToInformIncrementalMarker 470c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }; 471c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 472c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Generate(MacroAssembler* masm); 473c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void GenerateIncremental(MacroAssembler* masm, Mode mode); 474c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void CheckNeedsToInformIncrementalMarker( 475c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MacroAssembler* masm, 476c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com OnNoNeedToInformIncrementalMarker on_no_need, 477c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Mode mode); 478c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void InformIncrementalMarker(MacroAssembler* masm, Mode mode); 479c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 480c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Major MajorKey() { return RecordWrite; } 481c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 482c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int MinorKey() { 483c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return ObjectBits::encode(object_.code()) | 484c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ValueBits::encode(value_.code()) | 485c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com AddressBits::encode(address_.code()) | 486c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetActionBits::encode(remembered_set_action_) | 487c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsModeBits::encode(save_fp_regs_mode_); 488c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 489c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 490c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Activate(Code* code) { 491c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code); 492c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 493c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 494c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com class ObjectBits: public BitField<int, 0, 4> {}; 495c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com class ValueBits: public BitField<int, 4, 4> {}; 496c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com class AddressBits: public BitField<int, 8, 4> {}; 497c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com class RememberedSetActionBits: public BitField<RememberedSetAction, 12, 1> {}; 498c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com class SaveFPRegsModeBits: public BitField<SaveFPRegsMode, 13, 1> {}; 499c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 500c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object_; 501c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value_; 502c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register address_; 503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action_; 504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp_regs_mode_; 505c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label slow_; 506c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RegisterAllocation regs_; 507c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 509c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 51065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org} } // namespace v8::internal 51165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 51265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#endif // V8_X64_CODE_STUBS_X64_H_ 513