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