stub-cache.h revision 59151504615d929945dc59db37bf1166937748c6
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_STUB_CACHE_H_ 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_STUB_CACHE_H_ 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "macro-assembler.h" 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The stub cache is used for megamorphic calls and property accesses. 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// It maps (map, name, type)->Code* 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The design of the table uses the inline cache stubs used for 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// mono-morphic calls. The beauty of this, we do not have to 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// invalidate the cache whenever a prototype map is changed. The stub 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// validates the map chain as in the mono-morphic case. 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SCTableReference; 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StubCache : public AllStatic { 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block struct Entry { 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* key; 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code* value; 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void Initialize(bool create_heap_objects); 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Computes the right stub matching. Inserts the result in the 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // cache before returning. This might compile a stub if needed. 5980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeLoadNonexistent(String* name, 6080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* receiver); 616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 6280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeLoadField(String* name, 6380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* receiver, 6480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* holder, 6580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int field_index); 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeLoadCallback(String* name, 6880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* receiver, 6980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* holder, 7080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen AccessorInfo* callback); 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeLoadConstant(String* name, 7380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* receiver, 7480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* holder, 7580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Object* value); 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeLoadInterceptor(String* name, 7880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* receiver, 7980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* holder); 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeLoadNormal(); 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeLoadGlobal(String* name, 8580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* receiver, 8680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen GlobalObject* holder, 8780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSGlobalPropertyCell* cell, 8880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen bool is_dont_delete); 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --- 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeKeyedLoadField(String* name, 9480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* receiver, 9580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* holder, 9680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int field_index); 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeKeyedLoadCallback( 9980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen String* name, 10080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* receiver, 10180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* holder, 10280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen AccessorInfo* callback); 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeKeyedLoadConstant(String* name, 10580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* receiver, 10680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* holder, 10780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Object* value); 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeKeyedLoadInterceptor(String* name, 11080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* receiver, 11180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* holder); 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeKeyedLoadArrayLength(String* name, 11480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSArray* receiver); 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeKeyedLoadStringLength(String* name, 11780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen String* receiver); 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeKeyedLoadFunctionPrototype( 12080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen String* name, 12180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSFunction* receiver); 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --- 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeStoreField(String* name, 12680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* receiver, 12780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int field_index, 12880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Map* transition = NULL); 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeStoreNormal(); 1318defd9ff6930b4e24729971a61cf7469daf119beSteve Block 13280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeStoreGlobal(String* name, 13380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen GlobalObject* receiver, 13480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSGlobalPropertyCell* cell); 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeStoreCallback(String* name, 13780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* receiver, 13880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen AccessorInfo* callback); 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeStoreInterceptor(String* name, 14180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* receiver); 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --- 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeKeyedStoreField(String* name, 14680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* receiver, 14780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int field_index, 14880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Map* transition = NULL); 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --- 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 15280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeCallField(int argc, 15380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen InLoopFlag in_loop, 15480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code::Kind, 15580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen String* name, 15680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Object* object, 15780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* holder, 15880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int index); 15980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 16080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeCallConstant(int argc, 16180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen InLoopFlag in_loop, 16280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code::Kind, 16380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen String* name, 16480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Object* object, 16580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* holder, 16680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSFunction* function); 16780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 16880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeCallNormal(int argc, 16980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen InLoopFlag in_loop, 17080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code::Kind, 17180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen String* name, 17280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* receiver); 17380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 17480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeCallInterceptor(int argc, 17580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code::Kind, 17680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen String* name, 17780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Object* object, 17880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* holder); 17980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 18080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeCallGlobal(int argc, 18180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen InLoopFlag in_loop, 18280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code::Kind, 18380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen String* name, 18480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSObject* receiver, 18580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen GlobalObject* holder, 18680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSGlobalPropertyCell* cell, 18780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSFunction* function); 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --- 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 19180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeCallInitialize(int argc, 19280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen InLoopFlag in_loop, 19380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code::Kind kind); 1947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 19580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeCallPreMonomorphic(int argc, 19680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen InLoopFlag in_loop, 19780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code::Kind kind); 1987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 19980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeCallNormal(int argc, 20080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen InLoopFlag in_loop, 20180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code::Kind kind); 2027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 20380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeCallMegamorphic(int argc, 20480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen InLoopFlag in_loop, 20580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code::Kind kind); 2067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 20780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeCallMiss(int argc, Code::Kind kind); 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Finds the Code object stored in the Heap::non_monomorphic_cache(). 21080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Code* FindCallInitialize(int argc, 21180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen InLoopFlag in_loop, 21280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code::Kind kind); 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 21580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeCallDebugBreak(int argc, 21680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code::Kind kind); 2177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 21880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen MUST_USE_RESULT static Object* ComputeCallDebugPrepareStepIn(int argc, 21980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code::Kind kind); 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update cache for entry hash(name, map). 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Code* Set(String* name, Map* map, Code* code); 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the lookup table (@ mark compact collection). 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void Clear(); 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Generate code for probing the stub cache table. 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If extra != no_reg it might be used as am extra scratch register. 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateProbe(MacroAssembler* masm, 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::Flags flags, 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register receiver, 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register name, 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register extra); 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum Table { 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block kPrimary, 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block kSecondary 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class SCTableReference; 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kPrimaryTableSize = 2048; 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kSecondaryTableSize = 512; 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Entry primary_[]; 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Entry secondary_[]; 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Computes the hashed offsets for primary and secondary caches. 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static int PrimaryOffset(String* name, Code::Flags flags, Map* map) { 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This works well because the heap object tag size and the hash 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // shift are equal. Shifting down the length field to get the 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // hash code would effectively throw away two bits of the hash 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // code. 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(kHeapObjectTagSize == String::kHashShift); 256d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Compute the hash of the name (use entire hash field). 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(name->HasHashCode()); 258d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block uint32_t field = name->hash_field(); 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Using only the low bits in 64-bit mode is unlikely to increase the 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // risk of collision even if the heap is spread over an area larger than 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 4Gb (and not at all if it isn't). 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t map_low32bits = 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map)); 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We always set the in_loop bit to zero when generating the lookup code 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // so do it here too so the hash codes match. 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t iflags = 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup); 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Base the offset on a simple combination of name, flags, and map. 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t key = (map_low32bits + field) ^ iflags; 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return key & ((kPrimaryTableSize - 1) << kHeapObjectTagSize); 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static int SecondaryOffset(String* name, Code::Flags flags, int seed) { 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Use the seed from the primary cache in the secondary cache. 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t string_low32bits = 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name)); 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We always set the in_loop bit to zero when generating the lookup code 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // so do it here too so the hash codes match. 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t iflags = 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (static_cast<uint32_t>(flags) & ~Code::kFlagsICInLoopMask); 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t key = seed - string_low32bits + iflags; 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return key & ((kSecondaryTableSize - 1) << kHeapObjectTagSize); 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the entry for a given offset in exactly the same way as 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // we do in generated code. We generate an hash code that already 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ends in String::kHashShift 0s. Then we shift it so it is a multiple 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // of sizeof(Entry). This makes it easier to avoid making mistakes 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in the hashed offset computations. 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Entry* entry(Entry* table, int offset) { 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int shift_amount = kPointerSizeLog2 + 1 - String::kHashShift; 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<Entry*>( 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reinterpret_cast<Address>(table) + (offset << shift_amount)); 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SCTableReference { 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static SCTableReference keyReference(StubCache::Table table) { 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return SCTableReference( 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reinterpret_cast<Address>(&first_entry(table)->key)); 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static SCTableReference valueReference(StubCache::Table table) { 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return SCTableReference( 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reinterpret_cast<Address>(&first_entry(table)->value)); 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address address() const { return address_; } 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit SCTableReference(Address address) : address_(address) {} 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static StubCache::Entry* first_entry(StubCache::Table table) { 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (table) { 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case StubCache::kPrimary: return StubCache::primary_; 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case StubCache::kSecondary: return StubCache::secondary_; 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNREACHABLE(); 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return NULL; 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address address_; 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------------ 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Support functions for IC stubs for callbacks. 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* LoadCallbackProperty(Arguments args); 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* StoreCallbackProperty(Arguments args); 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Support functions for IC stubs for interceptors. 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* LoadPropertyWithInterceptorOnly(Arguments args); 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* LoadPropertyWithInterceptorForLoad(Arguments args); 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* LoadPropertyWithInterceptorForCall(Arguments args); 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* StoreInterceptorProperty(Arguments args); 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* CallInterceptorProperty(Arguments args); 342402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuObject* KeyedLoadPropertyWithInterceptor(Arguments args); 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The stub compiler compiles stubs for the stub cache. 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StubCompiler BASE_EMBEDDED { 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum CheckType { 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RECEIVER_MAP_CHECK, 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block STRING_CHECK, 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NUMBER_CHECK, 3526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block BOOLEAN_CHECK 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StubCompiler() : scope_(), masm_(NULL, 256), failure_(NULL) { } 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileCallInitialize(Code::Flags flags); 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileCallPreMonomorphic(Code::Flags flags); 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileCallNormal(Code::Flags flags); 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileCallMegamorphic(Code::Flags flags); 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileCallMiss(Code::Flags flags); 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileCallDebugBreak(Code::Flags flags); 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileCallDebugPrepareStepIn(Code::Flags flags); 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Static functions for generating parts of stubs. 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index, 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register prototype); 371402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 3727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Generates prototype loading code that uses the objects from the 3737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // context we were in when this function was called. This ties the 3747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // generated code to a particular context and so must not be used in 3757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // cases where the generated code is not allowed to have references 3767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // to objects from a context. 3777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch static void GenerateDirectLoadGlobalFunctionPrototype(MacroAssembler* masm, 3787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch int index, 3797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Register prototype); 3807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateFastPropertyLoad(MacroAssembler* masm, 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register dst, Register src, 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, int index); 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateLoadArrayLength(MacroAssembler* masm, 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register receiver, 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* miss_label); 389402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateLoadStringLength(MacroAssembler* masm, 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register receiver, 392402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu Register scratch1, 393402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu Register scratch2, 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* miss_label); 395402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateLoadFunctionPrototype(MacroAssembler* masm, 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register receiver, 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch1, 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch2, 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* miss_label); 401402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateStoreField(MacroAssembler* masm, 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* object, 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index, 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Map* transition, 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register receiver_reg, 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register name_reg, 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* miss_label); 410402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind); 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4138defd9ff6930b4e24729971a61cf7469daf119beSteve Block // Generates code that verifies that the property holder has not changed 4148defd9ff6930b4e24729971a61cf7469daf119beSteve Block // (checking maps of objects in the prototype chain for fast and global 4158defd9ff6930b4e24729971a61cf7469daf119beSteve Block // objects or doing negative lookup for slow objects, ensures that the 4168defd9ff6930b4e24729971a61cf7469daf119beSteve Block // property cells for global objects are still empty) and checks that the map 4178defd9ff6930b4e24729971a61cf7469daf119beSteve Block // of the holder has not changed. If necessary the function also generates 4188defd9ff6930b4e24729971a61cf7469daf119beSteve Block // code for security check in case of global object holders. Helps to make 4198defd9ff6930b4e24729971a61cf7469daf119beSteve Block // sure that the current IC is still valid. 4208defd9ff6930b4e24729971a61cf7469daf119beSteve Block // 4218defd9ff6930b4e24729971a61cf7469daf119beSteve Block // The scratch and holder registers are always clobbered, but the object 4228defd9ff6930b4e24729971a61cf7469daf119beSteve Block // register is only clobbered if it the same as the holder register. The 4238defd9ff6930b4e24729971a61cf7469daf119beSteve Block // function returns a register containing the holder - either object_reg or 4248defd9ff6930b4e24729971a61cf7469daf119beSteve Block // holder_reg. 4258defd9ff6930b4e24729971a61cf7469daf119beSteve Block // The function can optionally (when save_at_depth != 4268defd9ff6930b4e24729971a61cf7469daf119beSteve Block // kInvalidProtoDepth) save the object at the given depth by moving 4278defd9ff6930b4e24729971a61cf7469daf119beSteve Block // it to [esp + kPointerSize]. 428402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 429402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu Register CheckPrototypes(JSObject* object, 430402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu Register object_reg, 431402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu JSObject* holder, 432402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu Register holder_reg, 4333bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Register scratch1, 4343bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Register scratch2, 435402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu String* name, 4363bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Label* miss) { 4373bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch return CheckPrototypes(object, object_reg, holder, holder_reg, scratch1, 4383bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch scratch2, name, kInvalidProtoDepth, miss); 439402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 440402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register CheckPrototypes(JSObject* object, 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register object_reg, 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register holder_reg, 4453bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Register scratch1, 4463bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Register scratch2, 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name, 448402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu int save_at_depth, 4493bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Label* miss); 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* GetCodeWithFlags(Code::Flags flags, const char* name); 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* GetCodeWithFlags(Code::Flags flags, String* name); 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MacroAssembler* masm() { return &masm_; } 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_failure(Failure* failure) { failure_ = failure; } 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void GenerateLoadField(JSObject* object, 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register receiver, 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch1, 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch2, 4633bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Register scratch3, 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index, 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name, 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* miss); 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 468e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool GenerateLoadCallback(JSObject* object, 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register receiver, 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register name_reg, 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch1, 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch2, 4743bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Register scratch3, 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AccessorInfo* callback, 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name, 477e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Label* miss, 478e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Failure** failure); 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void GenerateLoadConstant(JSObject* object, 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register receiver, 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch1, 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch2, 4853bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Register scratch3, 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* value, 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name, 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* miss); 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void GenerateLoadInterceptor(JSObject* object, 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LookupResult* lookup, 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register receiver, 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register name_reg, 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch1, 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch2, 4973bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Register scratch3, 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name, 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* miss); 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5014515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke static void LookupPostInterceptor(JSObject* holder, 5024515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke String* name, 5034515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke LookupResult* lookup); 5044515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope_; 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MacroAssembler masm_; 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Failure* failure_; 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass LoadStubCompiler: public StubCompiler { 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 5146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Object* CompileLoadNonexistent(String* name, 5156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block JSObject* object, 5166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block JSObject* last); 5176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileLoadField(JSObject* object, 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index, 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name); 5226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 523e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Object* CompileLoadCallback(String* name, 524e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke JSObject* object, 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 526e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke AccessorInfo* callback); 5276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileLoadConstant(JSObject* object, 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* value, 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name); 5326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileLoadInterceptor(JSObject* object, 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name); 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileLoadGlobal(JSObject* object, 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block GlobalObject* holder, 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSGlobalPropertyCell* cell, 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name, 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_dont_delete); 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* GetCode(PropertyType type, String* name); 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass KeyedLoadStubCompiler: public StubCompiler { 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileLoadField(String* name, 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* object, 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index); 5546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileLoadCallback(String* name, 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* object, 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AccessorInfo* callback); 5596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileLoadConstant(String* name, 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* object, 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* value); 5646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileLoadInterceptor(JSObject* object, 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name); 5686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileLoadArrayLength(String* name); 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileLoadStringLength(String* name); 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileLoadFunctionPrototype(String* name); 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* GetCode(PropertyType type, String* name); 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StoreStubCompiler: public StubCompiler { 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileStoreField(JSObject* object, 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index, 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Map* transition, 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name); 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileStoreCallback(JSObject* object, 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AccessorInfo* callbacks, 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name); 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileStoreInterceptor(JSObject* object, String* name); 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileStoreGlobal(GlobalObject* object, 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSGlobalPropertyCell* holder, 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name); 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* GetCode(PropertyType type, String* name); 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass KeyedStoreStubCompiler: public StubCompiler { 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileStoreField(JSObject* object, 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index, 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Map* transition, 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name); 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* GetCode(PropertyType type, String* name); 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 61025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen// List of functions with custom constant call IC stubs. 61125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen// 61225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen// Installation of custom call generators for the selected builtins is 61325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen// handled by the bootstrapper. 61425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen// 61559151504615d929945dc59db37bf1166937748c6Steve Block// Each entry has a name of a global function (lowercased), a flag 61659151504615d929945dc59db37bf1166937748c6Steve Block// controlling whether the generator is set on the function itself or 61759151504615d929945dc59db37bf1166937748c6Steve Block// on its instance prototype, a name of a builtin function on the 61859151504615d929945dc59db37bf1166937748c6Steve Block// function or its instance prototype (the one the generator is set 61959151504615d929945dc59db37bf1166937748c6Steve Block// for), and a name of a generator itself (used to build ids and 62059151504615d929945dc59db37bf1166937748c6Steve Block// generator function names). 62159151504615d929945dc59db37bf1166937748c6Steve Block#define CUSTOM_CALL_IC_GENERATORS(V) \ 62259151504615d929945dc59db37bf1166937748c6Steve Block V(array, INSTANCE_PROTOTYPE, push, ArrayPush) \ 62359151504615d929945dc59db37bf1166937748c6Steve Block V(array, INSTANCE_PROTOTYPE, pop, ArrayPop) \ 62459151504615d929945dc59db37bf1166937748c6Steve Block V(string, INSTANCE_PROTOTYPE, charCodeAt, StringCharCodeAt) \ 62559151504615d929945dc59db37bf1166937748c6Steve Block V(string, INSTANCE_PROTOTYPE, charAt, StringCharAt) \ 62659151504615d929945dc59db37bf1166937748c6Steve Block V(string, FUNCTION, fromCharCode, StringFromCharCode) 62725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 62825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CallStubCompiler: public StubCompiler { 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 63159151504615d929945dc59db37bf1166937748c6Steve Block enum CustomGeneratorOwner { 63259151504615d929945dc59db37bf1166937748c6Steve Block FUNCTION, 63359151504615d929945dc59db37bf1166937748c6Steve Block INSTANCE_PROTOTYPE 63459151504615d929945dc59db37bf1166937748c6Steve Block }; 63559151504615d929945dc59db37bf1166937748c6Steve Block 63625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen enum { 63759151504615d929945dc59db37bf1166937748c6Steve Block#define DECLARE_CALL_GENERATOR_ID(ignored1, ignore2, ignored3, name) \ 63825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen k##name##CallGenerator, 63925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen CUSTOM_CALL_IC_GENERATORS(DECLARE_CALL_GENERATOR_ID) 64025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen#undef DECLARE_CALL_GENERATOR_ID 64125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen kNumCallGenerators 64225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen }; 64325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 6448defd9ff6930b4e24729971a61cf7469daf119beSteve Block CallStubCompiler(int argc, 6458defd9ff6930b4e24729971a61cf7469daf119beSteve Block InLoopFlag in_loop, 6468defd9ff6930b4e24729971a61cf7469daf119beSteve Block Code::Kind kind, 6478defd9ff6930b4e24729971a61cf7469daf119beSteve Block InlineCacheHolderFlag cache_holder); 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 649402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu Object* CompileCallField(JSObject* object, 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index, 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name); 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileCallConstant(Object* object, 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSFunction* function, 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name, 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckType check); 658402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu Object* CompileCallInterceptor(JSObject* object, 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* holder, 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name); 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileCallGlobal(JSObject* object, 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block GlobalObject* holder, 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSGlobalPropertyCell* cell, 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSFunction* function, 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name); 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 66759151504615d929945dc59db37bf1166937748c6Steve Block // Compiles a custom call constant/global IC using the generator 66859151504615d929945dc59db37bf1166937748c6Steve Block // with given id. For constant calls cell is NULL. 66925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen Object* CompileCustomCall(int generator_id, 67025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen Object* object, 67125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen JSObject* holder, 67259151504615d929945dc59db37bf1166937748c6Steve Block JSGlobalPropertyCell* cell, 67325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen JSFunction* function, 67459151504615d929945dc59db37bf1166937748c6Steve Block String* name); 6756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 67659151504615d929945dc59db37bf1166937748c6Steve Block#define DECLARE_CALL_GENERATOR(ignored1, ignored2, ignored3, name) \ 67759151504615d929945dc59db37bf1166937748c6Steve Block Object* Compile##name##Call(Object* object, \ 67859151504615d929945dc59db37bf1166937748c6Steve Block JSObject* holder, \ 67959151504615d929945dc59db37bf1166937748c6Steve Block JSGlobalPropertyCell* cell, \ 68059151504615d929945dc59db37bf1166937748c6Steve Block JSFunction* function, \ 68159151504615d929945dc59db37bf1166937748c6Steve Block String* fname); 68225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen CUSTOM_CALL_IC_GENERATORS(DECLARE_CALL_GENERATOR) 68325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen#undef DECLARE_CALL_GENERATOR 6846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const ParameterCount arguments_; 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const InLoopFlag in_loop_; 6887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const Code::Kind kind_; 6898defd9ff6930b4e24729971a61cf7469daf119beSteve Block const InlineCacheHolderFlag cache_holder_; 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const ParameterCount& arguments() { return arguments_; } 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* GetCode(PropertyType type, String* name); 69425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 69525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // Convenience function. Calls GetCode above passing 69625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // CONSTANT_FUNCTION type and the name of the given function. 69725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen Object* GetCode(JSFunction* function); 6987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch void GenerateNameCheck(String* name, Label* miss); 7007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 70159151504615d929945dc59db37bf1166937748c6Steve Block void GenerateGlobalReceiverCheck(JSObject* object, 70259151504615d929945dc59db37bf1166937748c6Steve Block JSObject* holder, 70359151504615d929945dc59db37bf1166937748c6Steve Block String* name, 70459151504615d929945dc59db37bf1166937748c6Steve Block Label* miss); 70559151504615d929945dc59db37bf1166937748c6Steve Block 70659151504615d929945dc59db37bf1166937748c6Steve Block // Generates code to load the function from the cell checking that 70759151504615d929945dc59db37bf1166937748c6Steve Block // it still contains the same function. 70859151504615d929945dc59db37bf1166937748c6Steve Block void GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell, 70959151504615d929945dc59db37bf1166937748c6Steve Block JSFunction* function, 71059151504615d929945dc59db37bf1166937748c6Steve Block Label* miss); 71159151504615d929945dc59db37bf1166937748c6Steve Block 712bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // Generates a jump to CallIC miss stub. Returns Failure if the jump cannot 713bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // be generated. 714bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Object* GenerateMissBranch(); 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ConstructStubCompiler: public StubCompiler { 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ConstructStubCompiler() {} 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* CompileConstructStub(SharedFunctionInfo* shared); 723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* GetCode(); 726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Holds information about possible function call optimizations. 7306ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CallOptimization BASE_EMBEDDED { 7316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 7326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block explicit CallOptimization(LookupResult* lookup); 7336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 7346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block explicit CallOptimization(JSFunction* function); 7356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 7366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bool is_constant_call() const { 7376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return constant_function_ != NULL; 7386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 7396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 7406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block JSFunction* constant_function() const { 7416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(constant_function_ != NULL); 7426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return constant_function_; 7436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 7446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 7456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bool is_simple_api_call() const { 7466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return is_simple_api_call_; 7476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 7486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 7496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block FunctionTemplateInfo* expected_receiver_type() const { 7506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(is_simple_api_call_); 7516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return expected_receiver_type_; 7526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 7536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 7546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CallHandlerInfo* api_call_info() const { 7556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(is_simple_api_call_); 7566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return api_call_info_; 7576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 7586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 7596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Returns the depth of the object having the expected type in the 7606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // prototype chain between the two arguments. 7616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int GetPrototypeDepthOfExpectedType(JSObject* object, 7626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block JSObject* holder) const; 7636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 7646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 7656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void Initialize(JSFunction* function); 7666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 7676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Determines whether the given function can be called using the 7686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // fast api call builtin. 7696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void AnalyzePossibleApiFunction(JSFunction* function); 7706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 7716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block JSFunction* constant_function_; 7726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bool is_simple_api_call_; 7736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block FunctionTemplateInfo* expected_receiver_type_; 7746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CallHandlerInfo* api_call_info_; 7756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 7766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_STUB_CACHE_H_ 780