1a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 89dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 9d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org#include "src/ic/ic.h" 10a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org#include "src/ic/ic-compiler.h" 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 1371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#define __ ACCESS_MASM(masm) 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 186474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgvoid PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm, 196474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org StrictMode strict_mode) { 206474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Return address is on the stack. 219aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org DCHECK(!ebx.is(StoreDescriptor::ReceiverRegister()) && 229aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org !ebx.is(StoreDescriptor::NameRegister()) && 239aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org !ebx.is(StoreDescriptor::ValueRegister())); 246474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ pop(ebx); 259aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org __ push(StoreDescriptor::ReceiverRegister()); 269aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org __ push(StoreDescriptor::NameRegister()); 279aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org __ push(StoreDescriptor::ValueRegister()); 286474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ push(Immediate(Smi::FromInt(strict_mode))); 296474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ push(ebx); // return address 30de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 316474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Do tail-call to runtime routine. 326474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ TailCallRuntime(Runtime::kSetProperty, 4, 1); 33de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org} 34de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 35de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 36de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org#undef __ 37de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org#define __ ACCESS_MASM(masm()) 38de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 39eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgHandle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, 40eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org CodeHandleList* handlers, 41eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org Handle<Name> name, 42eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org Code::StubType type, 43eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org IcCheckType check) { 44ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Label miss; 45a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 4643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org if (check == PROPERTY && 4743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) { 48dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org // In case we are compiling an IC for dictionary loads and stores, just 49dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org // check whether the name is unique. 50dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) { 5106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register tmp = scratch1(); 5206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ JumpIfSmi(this->name(), &miss); 5306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ mov(tmp, FieldOperand(this->name(), HeapObject::kMapOffset)); 5406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ movzx_b(tmp, FieldOperand(tmp, Map::kInstanceTypeOffset)); 5506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ JumpIfNotUniqueNameInstanceType(tmp, &miss); 56dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org } else { 57dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org __ cmp(this->name(), Immediate(name)); 58dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org __ j(not_equal, &miss); 59dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org } 604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } 614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 62b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Label number_case; 63af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; 64b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ JumpIfSmi(receiver(), smi_target); 65b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 66d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org // Polymorphic keyed stores may use the map register 674a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Register map_reg = scratch1(); 68e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kind() != Code::KEYED_STORE_IC || 699aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org map_reg.is(ElementTransitionAndStoreDescriptor::MapRegister())); 704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); 71af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org int receiver_count = types->length(); 72f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org int number_of_handled_maps = 0; 73ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org for (int current = 0; current < receiver_count; ++current) { 746d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Handle<HeapType> type = types->at(current); 75af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Handle<Map> map = IC::TypeToMap(*type, isolate()); 76f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (!map->is_deprecated()) { 77f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org number_of_handled_maps++; 78f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ cmp(map_reg, map); 796d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org if (type->Is(HeapType::Number())) { 80e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!number_case.is_unused()); 81b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ bind(&number_case); 82b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 83f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ j(equal, handlers->at(current)); 84f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 85ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 86e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(number_of_handled_maps != 0); 87a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 88a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&miss); 892bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 90a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 91a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Return the generated code. 924a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org InlineCacheState state = 93f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; 94eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org return GetCode(kind(), type, name, state); 95a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 96a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 97a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 986474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgHandle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic( 996474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org MapHandleList* receiver_maps, CodeHandleList* handler_stubs, 1006474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org MapHandleList* transitioned_maps) { 1016474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Label miss; 1026474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ JumpIfSmi(receiver(), &miss, Label::kNear); 1036474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset)); 1046474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org for (int i = 0; i < receiver_maps->length(); ++i) { 1056474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ cmp(scratch1(), receiver_maps->at(i)); 1066474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (transitioned_maps->at(i).is_null()) { 1076474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ j(equal, handler_stubs->at(i)); 1086474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } else { 1096474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Label next_map; 1106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ j(not_equal, &next_map, Label::kNear); 1116474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ mov(transition_map(), Immediate(transitioned_maps->at(i))); 1126474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); 1136474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ bind(&next_map); 1146474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 1156474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 116af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ bind(&miss); 1176474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 118a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 1196474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org // Return the generated code. 1206474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 121a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org} 122a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 12343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 124a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org#undef __ 125a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org} 126a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org} // namespace v8::internal 1279dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 1289dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_IA32 129