Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: src/stub-cache.cc

Issue 12340112: Polymorphism support for load IC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Added ARM port, introduced GenerateTailCall Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/stub-cache.h ('k') | src/type-info.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 93
94 // Update primary cache. 94 // Update primary cache.
95 primary->key = name; 95 primary->key = name;
96 primary->value = code; 96 primary->value = code;
97 primary->map = map; 97 primary->map = map;
98 isolate()->counters()->megamorphic_stub_cache_updates()->Increment(); 98 isolate()->counters()->megamorphic_stub_cache_updates()->Increment();
99 return code; 99 return code;
100 } 100 }
101 101
102 102
103 Handle<JSObject> StubCache::StubHolder(Handle<JSObject> receiver,
104 Handle<JSObject> holder) {
105 InlineCacheHolderFlag cache_holder =
106 IC::GetCodeCacheForObject(*receiver, *holder);
107 return Handle<JSObject>(IC::GetCodeCacheHolder(
108 isolate_, *receiver, cache_holder));
109 }
110
111
112 Handle<Code> StubCache::FindStub(Handle<String> name,
113 Handle<JSObject> stub_holder,
114 Code::Kind kind,
115 Code::StubType type,
116 Code::IcFragment fragment) {
117 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, fragment, type);
118 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
119 isolate_);
120 if (probe->IsCode()) return Handle<Code>::cast(probe);
121 return Handle<Code>::null();
122 }
123
124
125 Handle<Code> StubCache::FindHandler(Handle<String> name,
126 Handle<JSObject> handler_holder,
127 Code::Kind kind,
128 Code::StubType type) {
129 return FindStub(name, handler_holder, kind, type, Code::HANDLER_FRAGMENT);
130 }
131
132
133 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<JSObject> receiver,
134 Handle<Code> handler,
135 Handle<String> name) {
136 Handle<Code> ic = FindStub(name, receiver, Code::LOAD_IC,
137 handler->type(), Code::IC_FRAGMENT);
138 if (!ic.is_null()) return ic;
139
140 LoadStubCompiler ic_compiler(isolate());
141 ic = ic_compiler.CompileMonomorphicIC(
142 Handle<Map>(receiver->map()), handler, name);
143
144 JSObject::UpdateMapCodeCache(receiver, name, ic);
145 return ic;
146 }
147
148
149 Handle<Code> StubCache::ComputeKeyedMonomorphicIC(Handle<JSObject> receiver,
150 Handle<Code> handler,
151 Handle<String> name) {
152 Handle<Code> ic = FindStub(name, receiver, Code::KEYED_LOAD_IC,
153 handler->type(), Code::IC_FRAGMENT);
154 if (!ic.is_null()) return ic;
155
156 KeyedLoadStubCompiler ic_compiler(isolate());
157 ic = ic_compiler.CompileMonomorphicIC(
158 Handle<Map>(receiver->map()), handler, name);
159
160 JSObject::UpdateMapCodeCache(receiver, name, ic);
161 return ic;
162 }
163
164
103 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name, 165 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name,
104 Handle<JSObject> receiver) { 166 Handle<JSObject> receiver) {
105 // If no global objects are present in the prototype chain, the load 167 // If no global objects are present in the prototype chain, the load
106 // nonexistent IC stub can be shared for all names for a given map 168 // nonexistent IC stub can be shared for all names for a given map
107 // and we use the empty string for the map cache in that case. If 169 // and we use the empty string for the map cache in that case. If
108 // there are global objects involved, we need to check global 170 // there are global objects involved, we need to check global
109 // property cells in the stub and therefore the stub will be 171 // property cells in the stub and therefore the stub will be
110 // specific to the name. 172 // specific to the name.
111 Handle<String> cache_name = factory()->empty_string(); 173 Handle<String> cache_name = factory()->empty_string();
112 Handle<JSObject> current; 174 Handle<JSObject> current;
113 Handle<Object> next = receiver; 175 Handle<Object> next = receiver;
114 Handle<GlobalObject> global; 176 Handle<GlobalObject> global;
115 do { 177 do {
116 current = Handle<JSObject>::cast(next); 178 current = Handle<JSObject>::cast(next);
117 next = Handle<Object>(current->GetPrototype(), isolate_); 179 next = Handle<Object>(current->GetPrototype(), isolate_);
118 if (current->IsGlobalObject()) { 180 if (current->IsGlobalObject()) {
119 global = Handle<GlobalObject>::cast(current); 181 global = Handle<GlobalObject>::cast(current);
120 cache_name = name; 182 cache_name = name;
121 } else if (!current->HasFastProperties()) { 183 } else if (!current->HasFastProperties()) {
122 cache_name = name; 184 cache_name = name;
123 } 185 }
124 } while (!next->IsNull()); 186 } while (!next->IsNull());
125 187
126 // Compile the stub that is either shared for all names or 188 // Compile the stub that is either shared for all names or
127 // name specific if there are global objects involved. 189 // name specific if there are global objects involved.
128 Code::Flags flags = Code::ComputeMonomorphicFlags( 190 Handle<Code> handler = FindHandler(
129 Code::LOAD_IC, Code::kNoExtraICState, Code::NONEXISTENT); 191 cache_name, receiver, Code::LOAD_IC, Code::NONEXISTENT);
130 Handle<Object> probe(receiver->map()->FindInCodeCache(*cache_name, flags), 192 if (!handler.is_null()) return handler;
131 isolate_);
132 if (probe->IsCode()) return Handle<Code>::cast(probe);
133 193
134 LoadStubCompiler compiler(isolate_); 194 LoadStubCompiler compiler(isolate_);
135 Handle<Code> code = 195 handler =
136 compiler.CompileLoadNonexistent(receiver, current, cache_name, global); 196 compiler.CompileLoadNonexistent(receiver, current, cache_name, global);
137 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *cache_name)); 197 JSObject::UpdateMapCodeCache(receiver, cache_name, handler);
138 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *cache_name, *code)); 198 return handler;
139 JSObject::UpdateMapCodeCache(receiver, cache_name, code);
140 return code;
141 } 199 }
142 200
143 201
144 Handle<Code> StubCache::ComputeLoadField(Handle<String> name, 202 Handle<Code> StubCache::ComputeLoadField(Handle<String> name,
145 Handle<JSObject> receiver, 203 Handle<JSObject> receiver,
146 Handle<JSObject> holder, 204 Handle<JSObject> holder,
147 PropertyIndex field) { 205 PropertyIndex field) {
148 InlineCacheHolderFlag cache_holder = 206 if (receiver.is_identical_to(holder)) {
149 IC::GetCodeCacheForObject(*receiver, *holder); 207 LoadFieldStub stub(LoadStubCompiler::receiver(),
150 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 208 field.is_inobject(holder),
151 isolate_, *receiver, cache_holder)); 209 field.translate(holder));
152 Code::Flags flags = Code::ComputeMonomorphicFlags( 210 return stub.GetCode(isolate());
153 Code::LOAD_IC, Code::kNoExtraICState, Code::FIELD); 211 }
154 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), 212
155 isolate_); 213 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
156 if (probe->IsCode()) return Handle<Code>::cast(probe); 214 Handle<Code> stub = FindHandler(
215 name, stub_holder, Code::LOAD_IC, Code::FIELD);
216 if (!stub.is_null()) return stub;
157 217
158 LoadStubCompiler compiler(isolate_); 218 LoadStubCompiler compiler(isolate_);
159 Handle<Code> code = compiler.CompileLoadField(receiver, holder, name, field); 219 Handle<Code> handler =
160 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 220 compiler.CompileLoadField(receiver, holder, name, field);
161 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 221 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
162 JSObject::UpdateMapCodeCache(map_holder, name, code); 222 return handler;
163 return code;
164 } 223 }
165 224
166 225
167 Handle<Code> StubCache::ComputeLoadCallback( 226 Handle<Code> StubCache::ComputeLoadCallback(
168 Handle<String> name, 227 Handle<String> name,
169 Handle<JSObject> receiver, 228 Handle<JSObject> receiver,
170 Handle<JSObject> holder, 229 Handle<JSObject> holder,
171 Handle<ExecutableAccessorInfo> callback) { 230 Handle<ExecutableAccessorInfo> callback) {
172 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); 231 ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
173 InlineCacheHolderFlag cache_holder = 232 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
174 IC::GetCodeCacheForObject(*receiver, *holder); 233 Handle<Code> stub = FindHandler(
175 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 234 name, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
176 isolate_, *receiver, cache_holder)); 235 if (!stub.is_null()) return stub;
177 Code::Flags flags = Code::ComputeMonomorphicFlags(
178 Code::LOAD_IC, Code::kNoExtraICState, Code::CALLBACKS);
179 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
180 isolate_);
181 if (probe->IsCode()) return Handle<Code>::cast(probe);
182 236
183 LoadStubCompiler compiler(isolate_); 237 LoadStubCompiler compiler(isolate_);
184 Handle<Code> code = 238 Handle<Code> handler =
185 compiler.CompileLoadCallback(receiver, holder, name, callback); 239 compiler.CompileLoadCallback(receiver, holder, name, callback);
186 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 240 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
187 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 241 return handler;
188 JSObject::UpdateMapCodeCache(map_holder, name, code);
189 return code;
190 } 242 }
191 243
192 244
193 Handle<Code> StubCache::ComputeLoadViaGetter(Handle<String> name, 245 Handle<Code> StubCache::ComputeLoadViaGetter(Handle<String> name,
194 Handle<JSObject> receiver, 246 Handle<JSObject> receiver,
195 Handle<JSObject> holder, 247 Handle<JSObject> holder,
196 Handle<JSFunction> getter) { 248 Handle<JSFunction> getter) {
197 InlineCacheHolderFlag cache_holder = 249 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
198 IC::GetCodeCacheForObject(*receiver, *holder); 250 Handle<Code> stub = FindHandler(
199 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 251 name, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
200 isolate_, *receiver, cache_holder)); 252 if (!stub.is_null()) return stub;
201 Code::Flags flags = Code::ComputeMonomorphicFlags(
202 Code::LOAD_IC, Code::kNoExtraICState, Code::CALLBACKS);
203 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
204 isolate_);
205 if (probe->IsCode()) return Handle<Code>::cast(probe);
206 253
207 LoadStubCompiler compiler(isolate_); 254 LoadStubCompiler compiler(isolate_);
208 Handle<Code> code = 255 Handle<Code> handler =
209 compiler.CompileLoadViaGetter(receiver, holder, name, getter); 256 compiler.CompileLoadViaGetter(receiver, holder, name, getter);
210 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 257 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
211 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 258 return handler;
212 JSObject::UpdateMapCodeCache(map_holder, name, code);
213 return code;
214 } 259 }
215 260
216 261
217 Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name, 262 Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name,
218 Handle<JSObject> receiver, 263 Handle<JSObject> receiver,
219 Handle<JSObject> holder, 264 Handle<JSObject> holder,
220 Handle<JSFunction> value) { 265 Handle<JSFunction> value) {
221 InlineCacheHolderFlag cache_holder = 266 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
222 IC::GetCodeCacheForObject(*receiver, *holder); 267 Handle<Code> handler = FindHandler(
223 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 268 name, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION);
224 isolate_, *receiver, cache_holder)); 269 if (!handler.is_null()) return handler;
225 Code::Flags flags = Code::ComputeMonomorphicFlags(
226 Code::LOAD_IC, Code::kNoExtraICState, Code::CONSTANT_FUNCTION);
227 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
228 isolate_);
229 if (probe->IsCode()) return Handle<Code>::cast(probe);
230 270
231 LoadStubCompiler compiler(isolate_); 271 LoadStubCompiler compiler(isolate_);
232 Handle<Code> code = 272 handler = compiler.CompileLoadConstant(receiver, holder, name, value);
233 compiler.CompileLoadConstant(receiver, holder, name, value); 273 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
234 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 274
235 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 275 return handler;
236 JSObject::UpdateMapCodeCache(map_holder, name, code);
237 return code;
238 } 276 }
239 277
240 278
241 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name, 279 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name,
242 Handle<JSObject> receiver, 280 Handle<JSObject> receiver,
243 Handle<JSObject> holder) { 281 Handle<JSObject> holder) {
244 InlineCacheHolderFlag cache_holder = 282 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
245 IC::GetCodeCacheForObject(*receiver, *holder); 283 Handle<Code> stub = FindHandler(
246 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 284 name, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR);
247 isolate_, *receiver, cache_holder)); 285 if (!stub.is_null()) return stub;
248 Code::Flags flags = Code::ComputeMonomorphicFlags(
249 Code::LOAD_IC, Code::kNoExtraICState, Code::INTERCEPTOR);
250 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
251 isolate_);
252 if (probe->IsCode()) return Handle<Code>::cast(probe);
253 286
254 LoadStubCompiler compiler(isolate_); 287 LoadStubCompiler compiler(isolate_);
255 Handle<Code> code = 288 Handle<Code> handler =
256 compiler.CompileLoadInterceptor(receiver, holder, name); 289 compiler.CompileLoadInterceptor(receiver, holder, name);
257 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 290 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
258 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 291 return handler;
259 JSObject::UpdateMapCodeCache(map_holder, name, code);
260 return code;
261 } 292 }
262 293
263 294
264 Handle<Code> StubCache::ComputeLoadNormal() { 295 Handle<Code> StubCache::ComputeLoadNormal(Handle<String> name,
296 Handle<JSObject> receiver) {
265 return isolate_->builtins()->LoadIC_Normal(); 297 return isolate_->builtins()->LoadIC_Normal();
266 } 298 }
267 299
268 300
269 Handle<Code> StubCache::ComputeLoadGlobal(Handle<String> name, 301 Handle<Code> StubCache::ComputeLoadGlobal(Handle<String> name,
270 Handle<JSObject> receiver, 302 Handle<JSObject> receiver,
271 Handle<GlobalObject> holder, 303 Handle<GlobalObject> holder,
272 Handle<JSGlobalPropertyCell> cell, 304 Handle<JSGlobalPropertyCell> cell,
273 bool is_dont_delete) { 305 bool is_dont_delete) {
274 InlineCacheHolderFlag cache_holder = 306 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
275 IC::GetCodeCacheForObject(*receiver, *holder); 307 Handle<Code> stub = FindStub(
276 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 308 name, stub_holder, Code::LOAD_IC, Code::NORMAL, Code::IC_FRAGMENT);
277 isolate_, *receiver, cache_holder)); 309 if (!stub.is_null()) return stub;
278 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC);
279 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
280 isolate_);
281 if (probe->IsCode()) return Handle<Code>::cast(probe);
282 310
283 LoadStubCompiler compiler(isolate_); 311 LoadStubCompiler compiler(isolate_);
284 Handle<Code> code = 312 Handle<Code> ic =
285 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete); 313 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete);
286 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 314 JSObject::UpdateMapCodeCache(stub_holder, name, ic);
287 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 315 return ic;
288 JSObject::UpdateMapCodeCache(map_holder, name, code);
289 return code;
290 } 316 }
291 317
292 318
293 Handle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name, 319 Handle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name,
294 Handle<JSObject> receiver, 320 Handle<JSObject> receiver,
295 Handle<JSObject> holder, 321 Handle<JSObject> holder,
296 PropertyIndex field) { 322 PropertyIndex field) {
297 InlineCacheHolderFlag cache_holder = 323 if (receiver.is_identical_to(holder)) {
298 IC::GetCodeCacheForObject(*receiver, *holder); 324 LoadFieldStub stub(KeyedLoadStubCompiler::receiver(),
299 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 325 field.is_inobject(holder),
300 isolate_, *receiver, cache_holder)); 326 field.translate(holder));
301 Code::Flags flags = Code::ComputeMonomorphicFlags( 327 return stub.GetCode(isolate());
302 Code::KEYED_LOAD_IC, Code::kNoExtraICState, Code::FIELD); 328 }
303 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), 329
304 isolate_); 330 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
305 if (probe->IsCode()) return Handle<Code>::cast(probe); 331 Handle<Code> stub = FindHandler(
332 name, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD);
333 if (!stub.is_null()) return stub;
306 334
307 KeyedLoadStubCompiler compiler(isolate_); 335 KeyedLoadStubCompiler compiler(isolate_);
308 Handle<Code> code = compiler.CompileLoadField(receiver, holder, name, field); 336 Handle<Code> handler =
309 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); 337 compiler.CompileLoadField(receiver, holder, name, field);
310 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); 338 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
311 JSObject::UpdateMapCodeCache(map_holder, name, code); 339 return handler;
312 return code;
313 } 340 }
314 341
315 342
316 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name, 343 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name,
317 Handle<JSObject> receiver, 344 Handle<JSObject> receiver,
318 Handle<JSObject> holder, 345 Handle<JSObject> holder,
319 Handle<JSFunction> value) { 346 Handle<JSFunction> value) {
320 InlineCacheHolderFlag cache_holder = 347 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
321 IC::GetCodeCacheForObject(*receiver, *holder); 348 Handle<Code> handler = FindHandler(
322 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 349 name, stub_holder, Code::KEYED_LOAD_IC, Code::CONSTANT_FUNCTION);
323 isolate_, *receiver, cache_holder)); 350 if (!handler.is_null()) return handler;
324 Code::Flags flags = Code::ComputeMonomorphicFlags(
325 Code::KEYED_LOAD_IC, Code::kNoExtraICState, Code::CONSTANT_FUNCTION);
326 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
327 isolate_);
328 if (probe->IsCode()) return Handle<Code>::cast(probe);
329 351
330 KeyedLoadStubCompiler compiler(isolate_); 352 KeyedLoadStubCompiler compiler(isolate_);
331 Handle<Code> code = 353 handler = compiler.CompileLoadConstant(receiver, holder, name, value);
332 compiler.CompileLoadConstant(receiver, holder, name, value); 354 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
333 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); 355 return handler;
334 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
335 JSObject::UpdateMapCodeCache(map_holder, name, code);
336 return code;
337 } 356 }
338 357
339 358
340 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name, 359 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name,
341 Handle<JSObject> receiver, 360 Handle<JSObject> receiver,
342 Handle<JSObject> holder) { 361 Handle<JSObject> holder) {
343 InlineCacheHolderFlag cache_holder = 362 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
344 IC::GetCodeCacheForObject(*receiver, *holder); 363 Handle<Code> stub = FindHandler(
345 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 364 name, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR);
346 isolate_, *receiver, cache_holder)); 365 if (!stub.is_null()) return stub;
347 Code::Flags flags = Code::ComputeMonomorphicFlags(
348 Code::KEYED_LOAD_IC, Code::kNoExtraICState, Code::INTERCEPTOR);
349 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
350 isolate_);
351 if (probe->IsCode()) return Handle<Code>::cast(probe);
352 366
353 KeyedLoadStubCompiler compiler(isolate_); 367 KeyedLoadStubCompiler compiler(isolate_);
354 Handle<Code> code = compiler.CompileLoadInterceptor(receiver, holder, name); 368 Handle<Code> handler =
355 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); 369 compiler.CompileLoadInterceptor(receiver, holder, name);
356 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); 370 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
357 JSObject::UpdateMapCodeCache(map_holder, name, code); 371 return handler;
358 return code;
359 } 372 }
360 373
361 374
362 Handle<Code> StubCache::ComputeKeyedLoadCallback( 375 Handle<Code> StubCache::ComputeKeyedLoadCallback(
363 Handle<String> name, 376 Handle<String> name,
364 Handle<JSObject> receiver, 377 Handle<JSObject> receiver,
365 Handle<JSObject> holder, 378 Handle<JSObject> holder,
366 Handle<ExecutableAccessorInfo> callback) { 379 Handle<ExecutableAccessorInfo> callback) {
367 InlineCacheHolderFlag cache_holder = 380 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
368 IC::GetCodeCacheForObject(*receiver, *holder); 381 Handle<Code> stub = FindHandler(
369 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 382 name, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS);
370 isolate_, *receiver, cache_holder)); 383 if (!stub.is_null()) return stub;
371 Code::Flags flags = Code::ComputeMonomorphicFlags(
372 Code::KEYED_LOAD_IC, Code::kNoExtraICState, Code::CALLBACKS);
373 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
374 isolate_);
375 if (probe->IsCode()) return Handle<Code>::cast(probe);
376 384
377 KeyedLoadStubCompiler compiler(isolate_); 385 KeyedLoadStubCompiler compiler(isolate_);
378 Handle<Code> code = 386 Handle<Code> handler =
379 compiler.CompileLoadCallback(receiver, holder, name, callback); 387 compiler.CompileLoadCallback(receiver, holder, name, callback);
380 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); 388 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
381 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); 389 return handler;
382 JSObject::UpdateMapCodeCache(map_holder, name, code);
383 return code;
384 } 390 }
385 391
386 392
387 Handle<Code> StubCache::ComputeStoreField(Handle<String> name, 393 Handle<Code> StubCache::ComputeStoreField(Handle<String> name,
388 Handle<JSObject> receiver, 394 Handle<JSObject> receiver,
389 int field_index, 395 int field_index,
390 Handle<Map> transition, 396 Handle<Map> transition,
391 StrictModeFlag strict_mode) { 397 StrictModeFlag strict_mode) {
392 Code::StubType type = 398 Code::StubType type =
393 (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION; 399 (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION;
394 Code::Flags flags = Code::ComputeMonomorphicFlags( 400 Code::Flags flags = Code::ComputeMonomorphicFlags(
395 Code::STORE_IC, strict_mode, type); 401 Code::STORE_IC, strict_mode, type);
396 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), 402 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
397 isolate_); 403 isolate_);
398 if (probe->IsCode()) return Handle<Code>::cast(probe); 404 if (probe->IsCode()) return Handle<Code>::cast(probe);
399 405
400 StoreStubCompiler compiler(isolate_, strict_mode); 406 StoreStubCompiler compiler(isolate_, strict_mode);
401 Handle<Code> code = 407 Handle<Code> code =
402 compiler.CompileStoreField(receiver, field_index, transition, name); 408 compiler.CompileStoreField(receiver, field_index, transition, name);
403 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
404 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
405 JSObject::UpdateMapCodeCache(receiver, name, code); 409 JSObject::UpdateMapCodeCache(receiver, name, code);
406 return code; 410 return code;
407 } 411 }
408 412
409 413
410 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { 414 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) {
411 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); 415 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
412 Handle<String> name = 416 Handle<String> name =
413 isolate()->factory()->KeyedLoadElementMonomorphic_string(); 417 isolate()->factory()->KeyedLoadElementMonomorphic_string();
414 418
415 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); 419 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_);
416 if (probe->IsCode()) return Handle<Code>::cast(probe); 420 if (probe->IsCode()) return Handle<Code>::cast(probe);
417 421
418 KeyedLoadStubCompiler compiler(isolate()); 422 KeyedLoadStubCompiler compiler(isolate());
419 Handle<Code> code = compiler.CompileLoadElement(receiver_map); 423 Handle<Code> code = compiler.CompileLoadElement(receiver_map);
420 424
421 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, 0));
422 Map::UpdateCodeCache(receiver_map, name, code); 425 Map::UpdateCodeCache(receiver_map, name, code);
423 return code; 426 return code;
424 } 427 }
425 428
426 429
427 Handle<Code> StubCache::ComputeKeyedStoreElement( 430 Handle<Code> StubCache::ComputeKeyedStoreElement(
428 Handle<Map> receiver_map, 431 Handle<Map> receiver_map,
429 KeyedStoreIC::StubKind stub_kind, 432 KeyedStoreIC::StubKind stub_kind,
430 StrictModeFlag strict_mode, 433 StrictModeFlag strict_mode,
431 KeyedAccessGrowMode grow_mode) { 434 KeyedAccessGrowMode grow_mode) {
432 Code::ExtraICState extra_state = 435 Code::ExtraICState extra_state =
433 Code::ComputeExtraICState(grow_mode, strict_mode); 436 Code::ComputeExtraICState(grow_mode, strict_mode);
434 Code::Flags flags = Code::ComputeMonomorphicFlags( 437 Code::Flags flags = Code::ComputeMonomorphicFlags(
435 Code::KEYED_STORE_IC, extra_state); 438 Code::KEYED_STORE_IC, extra_state);
436 439
437 ASSERT(stub_kind == KeyedStoreIC::STORE_NO_TRANSITION || 440 ASSERT(stub_kind == KeyedStoreIC::STORE_NO_TRANSITION ||
438 stub_kind == KeyedStoreIC::STORE_AND_GROW_NO_TRANSITION); 441 stub_kind == KeyedStoreIC::STORE_AND_GROW_NO_TRANSITION);
439 442
440 Handle<String> name = stub_kind == KeyedStoreIC::STORE_NO_TRANSITION 443 Handle<String> name = stub_kind == KeyedStoreIC::STORE_NO_TRANSITION
441 ? isolate()->factory()->KeyedStoreElementMonomorphic_string() 444 ? isolate()->factory()->KeyedStoreElementMonomorphic_string()
442 : isolate()->factory()->KeyedStoreAndGrowElementMonomorphic_string(); 445 : isolate()->factory()->KeyedStoreAndGrowElementMonomorphic_string();
443 446
444 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); 447 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_);
445 if (probe->IsCode()) return Handle<Code>::cast(probe); 448 if (probe->IsCode()) return Handle<Code>::cast(probe);
446 449
447 KeyedStoreStubCompiler compiler(isolate(), strict_mode, grow_mode); 450 KeyedStoreStubCompiler compiler(isolate(), strict_mode, grow_mode);
448 Handle<Code> code = compiler.CompileStoreElement(receiver_map); 451 Handle<Code> code = compiler.CompileStoreElement(receiver_map);
449 452
450 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, 0));
451 Map::UpdateCodeCache(receiver_map, name, code); 453 Map::UpdateCodeCache(receiver_map, name, code);
452 return code; 454 return code;
453 } 455 }
454 456
455 457
456 Handle<Code> StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) { 458 Handle<Code> StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) {
457 return (strict_mode == kStrictMode) 459 return (strict_mode == kStrictMode)
458 ? isolate_->builtins()->Builtins::StoreIC_Normal_Strict() 460 ? isolate_->builtins()->Builtins::StoreIC_Normal_Strict()
459 : isolate_->builtins()->Builtins::StoreIC_Normal(); 461 : isolate_->builtins()->Builtins::StoreIC_Normal();
460 } 462 }
461 463
462 464
463 Handle<Code> StubCache::ComputeStoreGlobal(Handle<String> name, 465 Handle<Code> StubCache::ComputeStoreGlobal(Handle<String> name,
464 Handle<GlobalObject> receiver, 466 Handle<GlobalObject> receiver,
465 Handle<JSGlobalPropertyCell> cell, 467 Handle<JSGlobalPropertyCell> cell,
466 StrictModeFlag strict_mode) { 468 StrictModeFlag strict_mode) {
467 Code::Flags flags = Code::ComputeMonomorphicFlags( 469 Code::Flags flags = Code::ComputeMonomorphicFlags(
468 Code::STORE_IC, strict_mode); 470 Code::STORE_IC, strict_mode);
469 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), 471 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
470 isolate_); 472 isolate_);
471 if (probe->IsCode()) return Handle<Code>::cast(probe); 473 if (probe->IsCode()) return Handle<Code>::cast(probe);
472 474
473 StoreStubCompiler compiler(isolate_, strict_mode); 475 StoreStubCompiler compiler(isolate_, strict_mode);
474 Handle<Code> code = compiler.CompileStoreGlobal(receiver, cell, name); 476 Handle<Code> code = compiler.CompileStoreGlobal(receiver, cell, name);
475 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
476 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
477 JSObject::UpdateMapCodeCache(receiver, name, code); 477 JSObject::UpdateMapCodeCache(receiver, name, code);
478 return code; 478 return code;
479 } 479 }
480 480
481 481
482 Handle<Code> StubCache::ComputeStoreCallback( 482 Handle<Code> StubCache::ComputeStoreCallback(
483 Handle<String> name, 483 Handle<String> name,
484 Handle<JSObject> receiver, 484 Handle<JSObject> receiver,
485 Handle<JSObject> holder, 485 Handle<JSObject> holder,
486 Handle<ExecutableAccessorInfo> callback, 486 Handle<ExecutableAccessorInfo> callback,
487 StrictModeFlag strict_mode) { 487 StrictModeFlag strict_mode) {
488 ASSERT(v8::ToCData<Address>(callback->setter()) != 0); 488 ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
489 Code::Flags flags = Code::ComputeMonomorphicFlags( 489 Code::Flags flags = Code::ComputeMonomorphicFlags(
490 Code::STORE_IC, strict_mode, Code::CALLBACKS); 490 Code::STORE_IC, strict_mode, Code::CALLBACKS);
491 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), 491 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
492 isolate_); 492 isolate_);
493 if (probe->IsCode()) return Handle<Code>::cast(probe); 493 if (probe->IsCode()) return Handle<Code>::cast(probe);
494 494
495 StoreStubCompiler compiler(isolate_, strict_mode); 495 StoreStubCompiler compiler(isolate_, strict_mode);
496 Handle<Code> code = 496 Handle<Code> code =
497 compiler.CompileStoreCallback(name, receiver, holder, callback); 497 compiler.CompileStoreCallback(name, receiver, holder, callback);
498 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
499 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
500 JSObject::UpdateMapCodeCache(receiver, name, code); 498 JSObject::UpdateMapCodeCache(receiver, name, code);
501 return code; 499 return code;
502 } 500 }
503 501
504 502
505 Handle<Code> StubCache::ComputeStoreViaSetter(Handle<String> name, 503 Handle<Code> StubCache::ComputeStoreViaSetter(Handle<String> name,
506 Handle<JSObject> receiver, 504 Handle<JSObject> receiver,
507 Handle<JSObject> holder, 505 Handle<JSObject> holder,
508 Handle<JSFunction> setter, 506 Handle<JSFunction> setter,
509 StrictModeFlag strict_mode) { 507 StrictModeFlag strict_mode) {
510 Code::Flags flags = Code::ComputeMonomorphicFlags( 508 Code::Flags flags = Code::ComputeMonomorphicFlags(
511 Code::STORE_IC, strict_mode, Code::CALLBACKS); 509 Code::STORE_IC, strict_mode, Code::CALLBACKS);
512 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), 510 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
513 isolate_); 511 isolate_);
514 if (probe->IsCode()) return Handle<Code>::cast(probe); 512 if (probe->IsCode()) return Handle<Code>::cast(probe);
515 513
516 StoreStubCompiler compiler(isolate_, strict_mode); 514 StoreStubCompiler compiler(isolate_, strict_mode);
517 Handle<Code> code = 515 Handle<Code> code =
518 compiler.CompileStoreViaSetter(name, receiver, holder, setter); 516 compiler.CompileStoreViaSetter(name, receiver, holder, setter);
519 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
520 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
521 JSObject::UpdateMapCodeCache(receiver, name, code); 517 JSObject::UpdateMapCodeCache(receiver, name, code);
522 return code; 518 return code;
523 } 519 }
524 520
525 521
526 Handle<Code> StubCache::ComputeStoreInterceptor(Handle<String> name, 522 Handle<Code> StubCache::ComputeStoreInterceptor(Handle<String> name,
527 Handle<JSObject> receiver, 523 Handle<JSObject> receiver,
528 StrictModeFlag strict_mode) { 524 StrictModeFlag strict_mode) {
529 Code::Flags flags = Code::ComputeMonomorphicFlags( 525 Code::Flags flags = Code::ComputeMonomorphicFlags(
530 Code::STORE_IC, strict_mode, Code::INTERCEPTOR); 526 Code::STORE_IC, strict_mode, Code::INTERCEPTOR);
531 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), 527 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
532 isolate_); 528 isolate_);
533 if (probe->IsCode()) return Handle<Code>::cast(probe); 529 if (probe->IsCode()) return Handle<Code>::cast(probe);
534 530
535 StoreStubCompiler compiler(isolate_, strict_mode); 531 StoreStubCompiler compiler(isolate_, strict_mode);
536 Handle<Code> code = compiler.CompileStoreInterceptor(receiver, name); 532 Handle<Code> code = compiler.CompileStoreInterceptor(receiver, name);
537 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
538 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
539 JSObject::UpdateMapCodeCache(receiver, name, code); 533 JSObject::UpdateMapCodeCache(receiver, name, code);
540 return code; 534 return code;
541 } 535 }
542 536
543 Handle<Code> StubCache::ComputeKeyedStoreField(Handle<String> name, 537 Handle<Code> StubCache::ComputeKeyedStoreField(Handle<String> name,
544 Handle<JSObject> receiver, 538 Handle<JSObject> receiver,
545 int field_index, 539 int field_index,
546 Handle<Map> transition, 540 Handle<Map> transition,
547 StrictModeFlag strict_mode) { 541 StrictModeFlag strict_mode) {
548 Code::StubType type = 542 Code::StubType type =
549 (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION; 543 (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION;
550 Code::Flags flags = Code::ComputeMonomorphicFlags( 544 Code::Flags flags = Code::ComputeMonomorphicFlags(
551 Code::KEYED_STORE_IC, strict_mode, type); 545 Code::KEYED_STORE_IC, strict_mode, type);
552 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), 546 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
553 isolate_); 547 isolate_);
554 if (probe->IsCode()) return Handle<Code>::cast(probe); 548 if (probe->IsCode()) return Handle<Code>::cast(probe);
555 549
556 KeyedStoreStubCompiler compiler(isolate(), strict_mode, 550 KeyedStoreStubCompiler compiler(isolate(), strict_mode,
557 DO_NOT_ALLOW_JSARRAY_GROWTH); 551 DO_NOT_ALLOW_JSARRAY_GROWTH);
558 Handle<Code> code = 552 Handle<Code> code =
559 compiler.CompileStoreField(receiver, field_index, transition, name); 553 compiler.CompileStoreField(receiver, field_index, transition, name);
560 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name));
561 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
562 JSObject::UpdateMapCodeCache(receiver, name, code); 554 JSObject::UpdateMapCodeCache(receiver, name, code);
563 return code; 555 return code;
564 } 556 }
565 557
566 558
567 #define CALL_LOGGER_TAG(kind, type) \ 559 #define CALL_LOGGER_TAG(kind, type) \
568 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) 560 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
569 561
570 Handle<Code> StubCache::ComputeCallConstant(int argc, 562 Handle<Code> StubCache::ComputeCallConstant(int argc,
571 Code::Kind kind, 563 Code::Kind kind,
572 Code::ExtraICState extra_state, 564 Code::ExtraICState extra_state,
573 Handle<String> name, 565 Handle<String> name,
574 Handle<Object> object, 566 Handle<Object> object,
575 Handle<JSObject> holder, 567 Handle<JSObject> holder,
576 Handle<JSFunction> function) { 568 Handle<JSFunction> function) {
577 // Compute the check type and the map. 569 // Compute the check type and the map.
578 InlineCacheHolderFlag cache_holder = 570 InlineCacheHolderFlag cache_holder =
579 IC::GetCodeCacheForObject(*object, *holder); 571 IC::GetCodeCacheForObject(*object, *holder);
580 Handle<JSObject> map_holder( 572 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
581 IC::GetCodeCacheHolder(isolate_, *object, cache_holder)); 573 isolate_, *object, cache_holder));
582 574
583 // Compute check type based on receiver/holder. 575 // Compute check type based on receiver/holder.
584 CheckType check = RECEIVER_MAP_CHECK; 576 CheckType check = RECEIVER_MAP_CHECK;
585 if (object->IsString()) { 577 if (object->IsString()) {
586 check = STRING_CHECK; 578 check = STRING_CHECK;
587 } else if (object->IsSymbol()) { 579 } else if (object->IsSymbol()) {
588 check = SYMBOL_CHECK; 580 check = SYMBOL_CHECK;
589 } else if (object->IsNumber()) { 581 } else if (object->IsNumber()) {
590 check = NUMBER_CHECK; 582 check = NUMBER_CHECK;
591 } else if (object->IsBoolean()) { 583 } else if (object->IsBoolean()) {
592 check = BOOLEAN_CHECK; 584 check = BOOLEAN_CHECK;
593 } 585 }
594 586
595 if (check != RECEIVER_MAP_CHECK && 587 if (check != RECEIVER_MAP_CHECK &&
596 !function->IsBuiltin() && 588 !function->IsBuiltin() &&
597 function->shared()->is_classic_mode()) { 589 function->shared()->is_classic_mode()) {
598 // Calling non-strict non-builtins with a value as the receiver 590 // Calling non-strict non-builtins with a value as the receiver
599 // requires boxing. 591 // requires boxing.
600 return Handle<Code>::null(); 592 return Handle<Code>::null();
601 } 593 }
602 594
603 Code::Flags flags = Code::ComputeMonomorphicFlags( 595 Code::Flags flags = Code::ComputeMonomorphicFlags(
604 kind, extra_state, Code::CONSTANT_FUNCTION, argc, cache_holder); 596 kind, extra_state, Code::CONSTANT_FUNCTION, argc, cache_holder);
605 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), 597 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
606 isolate_); 598 isolate_);
607 if (probe->IsCode()) return Handle<Code>::cast(probe); 599 if (probe->IsCode()) return Handle<Code>::cast(probe);
608 600
609 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); 601 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
610 Handle<Code> code = 602 Handle<Code> code =
611 compiler.CompileCallConstant(object, holder, name, check, function); 603 compiler.CompileCallConstant(object, holder, name, check, function);
612 code->set_check_type(check); 604 code->set_check_type(check);
613 ASSERT_EQ(flags, code->flags()); 605 ASSERT_EQ(flags, code->flags());
614 PROFILE(isolate_, 606 PROFILE(isolate_,
615 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 607 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
616 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 608 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
617 JSObject::UpdateMapCodeCache(map_holder, name, code); 609 JSObject::UpdateMapCodeCache(stub_holder, name, code);
618 return code; 610 return code;
619 } 611 }
620 612
621 613
622 Handle<Code> StubCache::ComputeCallField(int argc, 614 Handle<Code> StubCache::ComputeCallField(int argc,
623 Code::Kind kind, 615 Code::Kind kind,
624 Code::ExtraICState extra_state, 616 Code::ExtraICState extra_state,
625 Handle<String> name, 617 Handle<String> name,
626 Handle<Object> object, 618 Handle<Object> object,
627 Handle<JSObject> holder, 619 Handle<JSObject> holder,
628 PropertyIndex index) { 620 PropertyIndex index) {
629 // Compute the check type and the map. 621 // Compute the check type and the map.
630 InlineCacheHolderFlag cache_holder = 622 InlineCacheHolderFlag cache_holder =
631 IC::GetCodeCacheForObject(*object, *holder); 623 IC::GetCodeCacheForObject(*object, *holder);
632 Handle<JSObject> map_holder( 624 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
633 IC::GetCodeCacheHolder(isolate_, *object, cache_holder)); 625 isolate_, *object, cache_holder));
634 626
635 // TODO(1233596): We cannot do receiver map check for non-JS objects 627 // TODO(1233596): We cannot do receiver map check for non-JS objects
636 // because they may be represented as immediates without a 628 // because they may be represented as immediates without a
637 // map. Instead, we check against the map in the holder. 629 // map. Instead, we check against the map in the holder.
638 if (object->IsNumber() || object->IsSymbol() || 630 if (object->IsNumber() || object->IsSymbol() ||
639 object->IsBoolean() || object->IsString()) { 631 object->IsBoolean() || object->IsString()) {
640 object = holder; 632 object = holder;
641 } 633 }
642 634
643 Code::Flags flags = Code::ComputeMonomorphicFlags( 635 Code::Flags flags = Code::ComputeMonomorphicFlags(
644 kind, extra_state, Code::FIELD, argc, cache_holder); 636 kind, extra_state, Code::FIELD, argc, cache_holder);
645 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), 637 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
646 isolate_); 638 isolate_);
647 if (probe->IsCode()) return Handle<Code>::cast(probe); 639 if (probe->IsCode()) return Handle<Code>::cast(probe);
648 640
649 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); 641 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
650 Handle<Code> code = 642 Handle<Code> code =
651 compiler.CompileCallField(Handle<JSObject>::cast(object), 643 compiler.CompileCallField(Handle<JSObject>::cast(object),
652 holder, index, name); 644 holder, index, name);
653 ASSERT_EQ(flags, code->flags()); 645 ASSERT_EQ(flags, code->flags());
654 PROFILE(isolate_, 646 PROFILE(isolate_,
655 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 647 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
656 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 648 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
657 JSObject::UpdateMapCodeCache(map_holder, name, code); 649 JSObject::UpdateMapCodeCache(stub_holder, name, code);
658 return code; 650 return code;
659 } 651 }
660 652
661 653
662 Handle<Code> StubCache::ComputeCallInterceptor(int argc, 654 Handle<Code> StubCache::ComputeCallInterceptor(int argc,
663 Code::Kind kind, 655 Code::Kind kind,
664 Code::ExtraICState extra_state, 656 Code::ExtraICState extra_state,
665 Handle<String> name, 657 Handle<String> name,
666 Handle<Object> object, 658 Handle<Object> object,
667 Handle<JSObject> holder) { 659 Handle<JSObject> holder) {
668 // Compute the check type and the map. 660 // Compute the check type and the map.
669 InlineCacheHolderFlag cache_holder = 661 InlineCacheHolderFlag cache_holder =
670 IC::GetCodeCacheForObject(*object, *holder); 662 IC::GetCodeCacheForObject(*object, *holder);
671 Handle<JSObject> map_holder( 663 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
672 IC::GetCodeCacheHolder(isolate_, *object, cache_holder)); 664 isolate_, *object, cache_holder));
673 665
674 // TODO(1233596): We cannot do receiver map check for non-JS objects 666 // TODO(1233596): We cannot do receiver map check for non-JS objects
675 // because they may be represented as immediates without a 667 // because they may be represented as immediates without a
676 // map. Instead, we check against the map in the holder. 668 // map. Instead, we check against the map in the holder.
677 if (object->IsNumber() || object->IsSymbol() || 669 if (object->IsNumber() || object->IsSymbol() ||
678 object->IsBoolean() || object->IsString()) { 670 object->IsBoolean() || object->IsString()) {
679 object = holder; 671 object = holder;
680 } 672 }
681 673
682 Code::Flags flags = Code::ComputeMonomorphicFlags( 674 Code::Flags flags = Code::ComputeMonomorphicFlags(
683 kind, extra_state, Code::INTERCEPTOR, argc, cache_holder); 675 kind, extra_state, Code::INTERCEPTOR, argc, cache_holder);
684 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), 676 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
685 isolate_); 677 isolate_);
686 if (probe->IsCode()) return Handle<Code>::cast(probe); 678 if (probe->IsCode()) return Handle<Code>::cast(probe);
687 679
688 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder); 680 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
689 Handle<Code> code = 681 Handle<Code> code =
690 compiler.CompileCallInterceptor(Handle<JSObject>::cast(object), 682 compiler.CompileCallInterceptor(Handle<JSObject>::cast(object),
691 holder, name); 683 holder, name);
692 ASSERT_EQ(flags, code->flags()); 684 ASSERT_EQ(flags, code->flags());
693 PROFILE(isolate(), 685 PROFILE(isolate(),
694 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 686 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
695 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 687 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
696 JSObject::UpdateMapCodeCache(map_holder, name, code); 688 JSObject::UpdateMapCodeCache(stub_holder, name, code);
697 return code; 689 return code;
698 } 690 }
699 691
700 692
701 Handle<Code> StubCache::ComputeCallGlobal(int argc, 693 Handle<Code> StubCache::ComputeCallGlobal(int argc,
702 Code::Kind kind, 694 Code::Kind kind,
703 Code::ExtraICState extra_state, 695 Code::ExtraICState extra_state,
704 Handle<String> name, 696 Handle<String> name,
705 Handle<JSObject> receiver, 697 Handle<JSObject> receiver,
706 Handle<GlobalObject> holder, 698 Handle<GlobalObject> holder,
707 Handle<JSGlobalPropertyCell> cell, 699 Handle<JSGlobalPropertyCell> cell,
708 Handle<JSFunction> function) { 700 Handle<JSFunction> function) {
709 InlineCacheHolderFlag cache_holder = 701 InlineCacheHolderFlag cache_holder =
710 IC::GetCodeCacheForObject(*receiver, *holder); 702 IC::GetCodeCacheForObject(*receiver, *holder);
711 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 703 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
712 isolate_, *receiver, cache_holder)); 704 isolate_, *receiver, cache_holder));
713 Code::Flags flags = Code::ComputeMonomorphicFlags( 705 Code::Flags flags = Code::ComputeMonomorphicFlags(
714 kind, extra_state, Code::NORMAL, argc, cache_holder); 706 kind, extra_state, Code::NORMAL, argc, cache_holder);
715 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), 707 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
716 isolate_); 708 isolate_);
717 if (probe->IsCode()) return Handle<Code>::cast(probe); 709 if (probe->IsCode()) return Handle<Code>::cast(probe);
718 710
719 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder); 711 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
720 Handle<Code> code = 712 Handle<Code> code =
721 compiler.CompileCallGlobal(receiver, holder, cell, function, name); 713 compiler.CompileCallGlobal(receiver, holder, cell, function, name);
722 ASSERT_EQ(flags, code->flags()); 714 ASSERT_EQ(flags, code->flags());
723 PROFILE(isolate(), 715 PROFILE(isolate(),
724 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 716 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
725 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 717 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
726 JSObject::UpdateMapCodeCache(map_holder, name, code); 718 JSObject::UpdateMapCodeCache(stub_holder, name, code);
727 return code; 719 return code;
728 } 720 }
729 721
730 722
731 static void FillCache(Isolate* isolate, Handle<Code> code) { 723 static void FillCache(Isolate* isolate, Handle<Code> code) {
732 Handle<UnseededNumberDictionary> dictionary = 724 Handle<UnseededNumberDictionary> dictionary =
733 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(), 725 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(),
734 code->flags(), 726 code->flags(),
735 code); 727 code);
736 isolate->heap()->public_set_non_monomorphic_cache(*dictionary); 728 isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 870
879 871
880 Handle<Code> StubCache::ComputeLoadElementPolymorphic( 872 Handle<Code> StubCache::ComputeLoadElementPolymorphic(
881 MapHandleList* receiver_maps) { 873 MapHandleList* receiver_maps) {
882 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC); 874 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC);
883 Handle<PolymorphicCodeCache> cache = 875 Handle<PolymorphicCodeCache> cache =
884 isolate_->factory()->polymorphic_code_cache(); 876 isolate_->factory()->polymorphic_code_cache();
885 Handle<Object> probe = cache->Lookup(receiver_maps, flags); 877 Handle<Object> probe = cache->Lookup(receiver_maps, flags);
886 if (probe->IsCode()) return Handle<Code>::cast(probe); 878 if (probe->IsCode()) return Handle<Code>::cast(probe);
887 879
880 CodeHandleList handlers(receiver_maps->length());
888 KeyedLoadStubCompiler compiler(isolate_); 881 KeyedLoadStubCompiler compiler(isolate_);
889 Handle<Code> code = compiler.CompileLoadElementPolymorphic(receiver_maps); 882 compiler.CompileElementHandlers(receiver_maps, &handlers);
883 Handle<Code> code = compiler.CompilePolymorphicIC(
884 receiver_maps, &handlers, factory()->empty_string(),
885 Code::NORMAL, ELEMENT);
886
887 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment();
888
890 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); 889 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
891 return code; 890 return code;
892 } 891 }
893 892
894 893
894 Handle<Code> StubCache::ComputePolymorphicIC(MapHandleList* receiver_maps,
895 CodeHandleList* handlers,
896 Handle<String> name) {
897 LoadStubCompiler ic_compiler(isolate_);
898 Handle<Code> ic = ic_compiler.CompilePolymorphicIC(
899 receiver_maps, handlers, name, Code::NORMAL, PROPERTY);
900 return ic;
901 }
902
903
895 Handle<Code> StubCache::ComputeStoreElementPolymorphic( 904 Handle<Code> StubCache::ComputeStoreElementPolymorphic(
896 MapHandleList* receiver_maps, 905 MapHandleList* receiver_maps,
897 KeyedAccessGrowMode grow_mode, 906 KeyedAccessGrowMode grow_mode,
898 StrictModeFlag strict_mode) { 907 StrictModeFlag strict_mode) {
899 Handle<PolymorphicCodeCache> cache = 908 Handle<PolymorphicCodeCache> cache =
900 isolate_->factory()->polymorphic_code_cache(); 909 isolate_->factory()->polymorphic_code_cache();
901 Code::ExtraICState extra_state = Code::ComputeExtraICState(grow_mode, 910 Code::ExtraICState extra_state = Code::ComputeExtraICState(grow_mode,
902 strict_mode); 911 strict_mode);
903 Code::Flags flags = 912 Code::Flags flags =
904 Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state); 913 Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state);
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 } 1388 }
1380 1389
1381 1390
1382 #define __ ACCESS_MASM(masm()) 1391 #define __ ACCESS_MASM(masm())
1383 1392
1384 1393
1385 Register BaseLoadStubCompiler::HandlerFrontendHeader(Handle<JSObject> object, 1394 Register BaseLoadStubCompiler::HandlerFrontendHeader(Handle<JSObject> object,
1386 Register object_reg, 1395 Register object_reg,
1387 Handle<JSObject> holder, 1396 Handle<JSObject> holder,
1388 Handle<String> name, 1397 Handle<String> name,
1389 Label* miss, 1398 Label* miss) {
1390 FrontendCheckType check) {
1391 if (check == PERFORM_INITIAL_CHECKS) {
1392 GenerateNameCheck(name, this->name(), miss);
1393 // Check that the receiver isn't a smi.
1394 __ JumpIfSmi(object_reg, miss);
1395 }
1396
1397 // Check the prototype chain. 1399 // Check the prototype chain.
1398 return CheckPrototypes(object, object_reg, holder, 1400 return CheckPrototypes(object, object_reg, holder,
1399 scratch1(), scratch2(), scratch3(), 1401 scratch1(), scratch2(), scratch3(),
1400 name, miss); 1402 name, miss, SKIP_RECEIVER);
1401 } 1403 }
1402 1404
1403 1405
1404 Register BaseLoadStubCompiler::HandlerFrontend(Handle<JSObject> object, 1406 Register BaseLoadStubCompiler::HandlerFrontend(Handle<JSObject> object,
1405 Register object_reg, 1407 Register object_reg,
1406 Handle<JSObject> holder, 1408 Handle<JSObject> holder,
1407 Handle<String> name, 1409 Handle<String> name,
1408 Label* success, 1410 Label* success) {
1409 FrontendCheckType check) {
1410 Label miss; 1411 Label miss;
1411 1412
1412 Register reg = HandlerFrontendHeader( 1413 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
1413 object, object_reg, holder, name, &miss, check);
1414 1414
1415 HandlerFrontendFooter(success, &miss); 1415 HandlerFrontendFooter(success, &miss);
1416 return reg; 1416 return reg;
1417 } 1417 }
1418 1418
1419 1419
1420 Handle<Code> BaseLoadStubCompiler::CompileLoadField(Handle<JSObject> object, 1420 Handle<Code> BaseLoadStubCompiler::CompileLoadField(Handle<JSObject> object,
1421 Handle<JSObject> holder, 1421 Handle<JSObject> holder,
1422 Handle<String> name, 1422 Handle<String> name,
1423 PropertyIndex index) { 1423 PropertyIndex field) {
1424 Label success; 1424 Label miss;
1425 Register reg = HandlerFrontend(object, receiver(), holder, name, 1425
1426 &success, PERFORM_INITIAL_CHECKS); 1426 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss);
1427 __ bind(&success); 1427
1428 GenerateLoadField(reg, holder, index); 1428 LoadFieldStub stub(reg, field.is_inobject(holder), field.translate(holder));
1429 GenerateTailCall(stub.GetCode(isolate()));
1430
1431 __ bind(&miss);
1432 GenerateLoadMiss(masm(), kind());
1429 1433
1430 // Return the generated code. 1434 // Return the generated code.
1431 return GetCode(Code::FIELD, name); 1435 return GetCode(Code::HANDLER_FRAGMENT, Code::FIELD, name);
1432 } 1436 }
1433 1437
1434 1438
1435 Handle<Code> BaseLoadStubCompiler::CompileLoadConstant( 1439 Handle<Code> BaseLoadStubCompiler::CompileLoadConstant(
1436 Handle<JSObject> object, 1440 Handle<JSObject> object,
1437 Handle<JSObject> holder, 1441 Handle<JSObject> holder,
1438 Handle<String> name, 1442 Handle<String> name,
1439 Handle<JSFunction> value) { 1443 Handle<JSFunction> value) {
1440 Label success; 1444 Label success;
1441 HandlerFrontend(object, receiver(), holder, name, 1445 HandlerFrontend(object, receiver(), holder, name, &success);
1442 &success, PERFORM_INITIAL_CHECKS);
1443 __ bind(&success); 1446 __ bind(&success);
1444 GenerateLoadConstant(value); 1447 GenerateLoadConstant(value);
1445 1448
1446 // Return the generated code. 1449 // Return the generated code.
1447 return GetCode(Code::CONSTANT_FUNCTION, name); 1450 return GetCode(Code::HANDLER_FRAGMENT, Code::CONSTANT_FUNCTION, name);
1448 } 1451 }
1449 1452
1450 1453
1451 Handle<Code> BaseLoadStubCompiler::CompileLoadCallback( 1454 Handle<Code> BaseLoadStubCompiler::CompileLoadCallback(
1452 Handle<JSObject> object, 1455 Handle<JSObject> object,
1453 Handle<JSObject> holder, 1456 Handle<JSObject> holder,
1454 Handle<String> name, 1457 Handle<String> name,
1455 Handle<ExecutableAccessorInfo> callback) { 1458 Handle<ExecutableAccessorInfo> callback) {
1456 Label success; 1459 Label success;
1457 1460
1458 Register reg = CallbackHandlerFrontend( 1461 Register reg = CallbackHandlerFrontend(
1459 object, receiver(), holder, name, &success, 1462 object, receiver(), holder, name, &success, callback);
1460 PERFORM_INITIAL_CHECKS, callback);
1461 __ bind(&success); 1463 __ bind(&success);
1462 GenerateLoadCallback(reg, callback); 1464 GenerateLoadCallback(reg, callback);
1463 1465
1464 // Return the generated code. 1466 // Return the generated code.
1465 return GetCode(Code::CALLBACKS, name); 1467 return GetCode(Code::HANDLER_FRAGMENT, Code::CALLBACKS, name);
1466 } 1468 }
1467 1469
1468 1470
1469 Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor( 1471 Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor(
1470 Handle<JSObject> object, 1472 Handle<JSObject> object,
1471 Handle<JSObject> holder, 1473 Handle<JSObject> holder,
1472 Handle<String> name) { 1474 Handle<String> name) {
1473 Label success; 1475 Label success;
1474 1476
1475 LookupResult lookup(isolate()); 1477 LookupResult lookup(isolate());
1476 LookupPostInterceptor(holder, name, &lookup); 1478 LookupPostInterceptor(holder, name, &lookup);
1477 1479
1478 Register reg = HandlerFrontend(object, receiver(), holder, name, 1480 Register reg = HandlerFrontend(object, receiver(), holder, name, &success);
1479 &success, PERFORM_INITIAL_CHECKS);
1480 __ bind(&success); 1481 __ bind(&success);
1481 // TODO(368): Compile in the whole chain: all the interceptors in 1482 // TODO(368): Compile in the whole chain: all the interceptors in
1482 // prototypes and ultimate answer. 1483 // prototypes and ultimate answer.
1483 GenerateLoadInterceptor(reg, object, holder, &lookup, name); 1484 GenerateLoadInterceptor(reg, object, holder, &lookup, name);
1484 1485
1485 // Return the generated code. 1486 // Return the generated code.
1486 return GetCode(Code::INTERCEPTOR, name); 1487 return GetCode(Code::HANDLER_FRAGMENT, Code::INTERCEPTOR, name);
1487 } 1488 }
1488 1489
1489 1490
1490 void BaseLoadStubCompiler::GenerateLoadPostInterceptor( 1491 void BaseLoadStubCompiler::GenerateLoadPostInterceptor(
1491 Register interceptor_reg, 1492 Register interceptor_reg,
1492 Handle<JSObject> interceptor_holder, 1493 Handle<JSObject> interceptor_holder,
1493 Handle<String> name, 1494 Handle<String> name,
1494 LookupResult* lookup) { 1495 LookupResult* lookup) {
1495 Label success; 1496 Label success;
1496 Handle<JSObject> holder(lookup->holder()); 1497 Handle<JSObject> holder(lookup->holder());
1497 if (lookup->IsField()) { 1498 if (lookup->IsField()) {
1498 // We found FIELD property in prototype chain of interceptor's holder. 1499 PropertyIndex field = lookup->GetFieldIndex();
1499 // Retrieve a field from field's holder. 1500 if (interceptor_holder.is_identical_to(holder)) {
1500 Register reg = HandlerFrontend(interceptor_holder, interceptor_reg, holder, 1501 LoadFieldStub stub(interceptor_reg,
1501 name, &success, SKIP_INITIAL_CHECKS); 1502 field.is_inobject(holder),
1502 __ bind(&success); 1503 field.translate(holder));
1503 GenerateLoadField(reg, holder, lookup->GetFieldIndex()); 1504 GenerateTailCall(stub.GetCode(isolate()));
1505 } else {
1506 // We found FIELD property in prototype chain of interceptor's holder.
1507 // Retrieve a field from field's holder.
1508 Register reg = HandlerFrontend(
1509 interceptor_holder, interceptor_reg, holder, name, &success);
1510 __ bind(&success);
1511 GenerateLoadField(reg, holder, field);
1512 }
1504 } else { 1513 } else {
1505 // We found CALLBACKS property in prototype chain of interceptor's 1514 // We found CALLBACKS property in prototype chain of interceptor's
1506 // holder. 1515 // holder.
1507 ASSERT(lookup->type() == CALLBACKS); 1516 ASSERT(lookup->type() == CALLBACKS);
1508 Handle<ExecutableAccessorInfo> callback( 1517 Handle<ExecutableAccessorInfo> callback(
1509 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); 1518 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
1510 ASSERT(callback->getter() != NULL); 1519 ASSERT(callback->getter() != NULL);
1511 1520
1512 Register reg = CallbackHandlerFrontend( 1521 Register reg = CallbackHandlerFrontend(
1513 interceptor_holder, interceptor_reg, holder, 1522 interceptor_holder, interceptor_reg, holder, name, &success, callback);
1514 name, &success, SKIP_INITIAL_CHECKS, callback);
1515 __ bind(&success); 1523 __ bind(&success);
1516 GenerateLoadCallback(reg, callback); 1524 GenerateLoadCallback(reg, callback);
1517 } 1525 }
1518 } 1526 }
1519 1527
1520 1528
1529 Handle<Code> BaseLoadStubCompiler::CompileMonomorphicIC(
1530 Handle<Map> receiver_map,
1531 Handle<Code> handler,
1532 Handle<String> name) {
1533 MapHandleList receiver_maps(1);
1534 receiver_maps.Add(receiver_map);
1535 CodeHandleList handlers(1);
1536 handlers.Add(handler);
1537 Code::StubType type = handler->type();
1538 return CompilePolymorphicIC(&receiver_maps, &handlers, name, type, PROPERTY);
1539 }
1540
1541
1521 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( 1542 Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
1522 Handle<JSObject> object, 1543 Handle<JSObject> object,
1523 Handle<JSObject> holder, 1544 Handle<JSObject> holder,
1524 Handle<String> name, 1545 Handle<String> name,
1525 Handle<JSFunction> getter) { 1546 Handle<JSFunction> getter) {
1526 Label success; 1547 Label success;
1527 HandlerFrontend(object, receiver(), holder, name, 1548 HandlerFrontend(object, receiver(), holder, name, &success);
1528 &success, PERFORM_INITIAL_CHECKS);
1529 1549
1530 __ bind(&success); 1550 __ bind(&success);
1531 GenerateLoadViaGetter(masm(), getter); 1551 GenerateLoadViaGetter(masm(), getter);
1532 1552
1533 // Return the generated code. 1553 // Return the generated code.
1534 return GetCode(Code::CALLBACKS, name); 1554 return GetCode(Code::HANDLER_FRAGMENT, Code::CALLBACKS, name);
1535 } 1555 }
1536 1556
1537 1557
1538 #undef __ 1558 #undef __
1539 1559
1540 1560
1541 Handle<Code> LoadStubCompiler::GetCode(Code::StubType type, 1561 void LoadStubCompiler::JitEvent(Handle<String> name, Handle<Code> code) {
1542 Handle<String> name, 1562 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
1543 InlineCacheState state) { 1563 }
1544 Code::Flags flags = Code::ComputeMonomorphicFlags( 1564
1545 Code::LOAD_IC, Code::kNoExtraICState, type); 1565
1566 void KeyedLoadStubCompiler::JitEvent(Handle<String> name, Handle<Code> code) {
1567 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
1568 }
1569
1570
1571 Handle<Code> BaseLoadStubCompiler::GetCode(Code::IcFragment fragment,
1572 Code::StubType type,
1573 Handle<String> name,
1574 InlineCacheState state) {
1575 Code::Flags flags = Code::ComputeFlags(kind(), state, fragment, type);
1546 Handle<Code> code = GetCodeWithFlags(flags, name); 1576 Handle<Code> code = GetCodeWithFlags(flags, name);
1547 PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 1577 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
1548 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 1578 JitEvent(name, code);
1549 return code; 1579 return code;
1550 } 1580 }
1551 1581
1552 1582
1553 Handle<Code> KeyedLoadStubCompiler::GetCode(Code::StubType type, 1583 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps,
1554 Handle<String> name, 1584 CodeHandleList* handlers) {
1555 InlineCacheState state) {
1556 Code::Flags flags = Code::ComputeFlags(
1557 Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type);
1558 Handle<Code> code = GetCodeWithFlags(flags, name);
1559 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
1560 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
1561 return code;
1562 }
1563
1564
1565 Handle<Code> KeyedLoadStubCompiler::CompileLoadElementPolymorphic(
1566 MapHandleList* receiver_maps) {
1567 CodeHandleList handler_ics(receiver_maps->length());
1568 for (int i = 0; i < receiver_maps->length(); ++i) { 1585 for (int i = 0; i < receiver_maps->length(); ++i) {
1569 Handle<Map> receiver_map = receiver_maps->at(i); 1586 Handle<Map> receiver_map = receiver_maps->at(i);
1570 Handle<Code> cached_stub; 1587 Handle<Code> cached_stub;
1571 1588
1572 if ((receiver_map->instance_type() & kNotStringTag) == 0) { 1589 if ((receiver_map->instance_type() & kNotStringTag) == 0) {
1573 cached_stub = isolate()->builtins()->KeyedLoadIC_String(); 1590 cached_stub = isolate()->builtins()->KeyedLoadIC_String();
1574 } else { 1591 } else {
1575 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 1592 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
1576 ElementsKind elements_kind = receiver_map->elements_kind(); 1593 ElementsKind elements_kind = receiver_map->elements_kind();
1577 1594
1578 if (IsFastElementsKind(elements_kind) || 1595 if (IsFastElementsKind(elements_kind) ||
1579 IsExternalArrayElementsKind(elements_kind)) { 1596 IsExternalArrayElementsKind(elements_kind)) {
1580 cached_stub = 1597 cached_stub =
1581 KeyedLoadFastElementStub(is_js_array, 1598 KeyedLoadFastElementStub(is_js_array,
1582 elements_kind).GetCode(isolate()); 1599 elements_kind).GetCode(isolate());
1583 } else { 1600 } else {
1584 ASSERT(elements_kind == DICTIONARY_ELEMENTS); 1601 ASSERT(elements_kind == DICTIONARY_ELEMENTS);
1585 cached_stub = KeyedLoadDictionaryElementStub().GetCode(isolate()); 1602 cached_stub = KeyedLoadDictionaryElementStub().GetCode(isolate());
1586 } 1603 }
1587 } 1604 }
1588 1605
1589 handler_ics.Add(cached_stub); 1606 handlers->Add(cached_stub);
1590 } 1607 }
1591 Handle<Code> code = CompileLoadPolymorphic(receiver_maps, &handler_ics);
1592 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment();
1593 PROFILE(isolate(),
1594 CodeCreateEvent(Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG, *code, 0));
1595 return code;
1596 } 1608 }
1597 1609
1598 1610
1599
1600 Handle<Code> StoreStubCompiler::GetCode(Code::StubType type, 1611 Handle<Code> StoreStubCompiler::GetCode(Code::StubType type,
1601 Handle<String> name) { 1612 Handle<String> name) {
1602 Code::Flags flags = Code::ComputeMonomorphicFlags( 1613 Code::Flags flags = Code::ComputeMonomorphicFlags(
1603 Code::STORE_IC, strict_mode_, type); 1614 Code::STORE_IC, strict_mode_, type);
1604 Handle<Code> code = GetCodeWithFlags(flags, name); 1615 Handle<Code> code = GetCodeWithFlags(flags, name);
1605 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); 1616 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
1606 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); 1617 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
1607 return code; 1618 return code;
1608 } 1619 }
1609 1620
1610 1621
1611 Handle<Code> KeyedStoreStubCompiler::GetCode(Code::StubType type, 1622 Handle<Code> KeyedStoreStubCompiler::GetCode(Code::StubType type,
1612 Handle<String> name, 1623 Handle<String> name,
1613 InlineCacheState state) { 1624 InlineCacheState state) {
1614 Code::ExtraICState extra_state = 1625 Code::ExtraICState extra_state =
1615 Code::ComputeExtraICState(grow_mode_, strict_mode_); 1626 Code::ComputeExtraICState(grow_mode_, strict_mode_);
1616 Code::Flags flags = 1627 Code::Flags flags =
1617 Code::ComputeFlags(Code::KEYED_STORE_IC, state, extra_state, type); 1628 Code::ComputeFlags(Code::KEYED_STORE_IC, state, extra_state, type);
1618 Handle<Code> code = GetCodeWithFlags(flags, name); 1629 Handle<Code> code = GetCodeWithFlags(flags, name);
1619 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name)); 1630 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name));
1620 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code)); 1631 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
1621 return code; 1632 return code;
1622 } 1633 }
1623 1634
1624 1635
1625 Handle<Code> KeyedStoreStubCompiler::CompileStoreElementPolymorphic( 1636 Handle<Code> KeyedStoreStubCompiler::CompileStoreElementPolymorphic(
1626 MapHandleList* receiver_maps) { 1637 MapHandleList* receiver_maps) {
1627 // Collect MONOMORPHIC stubs for all |receiver_maps|. 1638 // Collect MONOMORPHIC stubs for all |receiver_maps|.
1628 CodeHandleList handler_ics(receiver_maps->length()); 1639 CodeHandleList handlers(receiver_maps->length());
1629 MapHandleList transitioned_maps(receiver_maps->length()); 1640 MapHandleList transitioned_maps(receiver_maps->length());
1630 for (int i = 0; i < receiver_maps->length(); ++i) { 1641 for (int i = 0; i < receiver_maps->length(); ++i) {
1631 Handle<Map> receiver_map(receiver_maps->at(i)); 1642 Handle<Map> receiver_map(receiver_maps->at(i));
1632 Handle<Code> cached_stub; 1643 Handle<Code> cached_stub;
1633 Handle<Map> transitioned_map = 1644 Handle<Map> transitioned_map =
1634 receiver_map->FindTransitionedMap(receiver_maps); 1645 receiver_map->FindTransitionedMap(receiver_maps);
1635 1646
1636 // TODO(mvstanton): The code below is doing pessimistic elements 1647 // TODO(mvstanton): The code below is doing pessimistic elements
1637 // transitions. I would like to stop doing that and rely on Allocation Site 1648 // transitions. I would like to stop doing that and rely on Allocation Site
1638 // Tracking to do a better job of ensuring the data types are what they need 1649 // Tracking to do a better job of ensuring the data types are what they need
1639 // to be. Not all the elements are in place yet, pessimistic elements 1650 // to be. Not all the elements are in place yet, pessimistic elements
1640 // transitions are still important for performance. 1651 // transitions are still important for performance.
1641 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 1652 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
1642 ElementsKind elements_kind = receiver_map->elements_kind(); 1653 ElementsKind elements_kind = receiver_map->elements_kind();
1643 if (!transitioned_map.is_null()) { 1654 if (!transitioned_map.is_null()) {
1644 cached_stub = ElementsTransitionAndStoreStub( 1655 cached_stub = ElementsTransitionAndStoreStub(
1645 elements_kind, 1656 elements_kind,
1646 transitioned_map->elements_kind(), 1657 transitioned_map->elements_kind(),
1647 is_js_array, 1658 is_js_array,
1648 strict_mode_, 1659 strict_mode_,
1649 grow_mode_).GetCode(isolate()); 1660 grow_mode_).GetCode(isolate());
1650 } else { 1661 } else {
1651 cached_stub = KeyedStoreElementStub( 1662 cached_stub = KeyedStoreElementStub(
1652 is_js_array, 1663 is_js_array,
1653 elements_kind, 1664 elements_kind,
1654 grow_mode_).GetCode(isolate()); 1665 grow_mode_).GetCode(isolate());
1655 } 1666 }
1656 ASSERT(!cached_stub.is_null()); 1667 ASSERT(!cached_stub.is_null());
1657 handler_ics.Add(cached_stub); 1668 handlers.Add(cached_stub);
1658 transitioned_maps.Add(transitioned_map); 1669 transitioned_maps.Add(transitioned_map);
1659 } 1670 }
1660 Handle<Code> code = 1671 Handle<Code> code =
1661 CompileStorePolymorphic(receiver_maps, &handler_ics, &transitioned_maps); 1672 CompileStorePolymorphic(receiver_maps, &handlers, &transitioned_maps);
1662 isolate()->counters()->keyed_store_polymorphic_stubs()->Increment(); 1673 isolate()->counters()->keyed_store_polymorphic_stubs()->Increment();
1663 PROFILE(isolate(), 1674 PROFILE(isolate(),
1664 CodeCreateEvent(Logger::KEYED_STORE_POLYMORPHIC_IC_TAG, *code, 0)); 1675 CodeCreateEvent(Logger::KEYED_STORE_POLYMORPHIC_IC_TAG, *code, 0));
1665 return code; 1676 return code;
1666 } 1677 }
1667 1678
1668 1679
1669 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement( 1680 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement(
1670 MacroAssembler* masm) { 1681 MacroAssembler* masm) {
1671 KeyedStoreIC::GenerateSlow(masm); 1682 KeyedStoreIC::GenerateSlow(masm);
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1826 Handle<FunctionTemplateInfo>( 1837 Handle<FunctionTemplateInfo>(
1827 FunctionTemplateInfo::cast(signature->receiver())); 1838 FunctionTemplateInfo::cast(signature->receiver()));
1828 } 1839 }
1829 } 1840 }
1830 1841
1831 is_simple_api_call_ = true; 1842 is_simple_api_call_ = true;
1832 } 1843 }
1833 1844
1834 1845
1835 } } // namespace v8::internal 1846 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | src/type-info.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698