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

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

Issue 12451003: Make IC patching resilient to flushing of the original target() ic. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments 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/x64/ic-x64.cc » ('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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 102
103 Handle<JSObject> StubCache::StubHolder(Handle<JSObject> receiver, 103 Handle<JSObject> StubCache::StubHolder(Handle<JSObject> receiver,
104 Handle<JSObject> holder) { 104 Handle<JSObject> holder) {
105 InlineCacheHolderFlag cache_holder = 105 InlineCacheHolderFlag cache_holder =
106 IC::GetCodeCacheForObject(*receiver, *holder); 106 IC::GetCodeCacheForObject(*receiver, *holder);
107 return Handle<JSObject>(IC::GetCodeCacheHolder( 107 return Handle<JSObject>(IC::GetCodeCacheHolder(
108 isolate_, *receiver, cache_holder)); 108 isolate_, *receiver, cache_holder));
109 } 109 }
110 110
111 111
112 Handle<Code> StubCache::FindStub(Handle<Name> name, 112 Handle<Code> StubCache::FindIC(Handle<Name> name,
113 Handle<JSObject> stub_holder, 113 Handle<JSObject> stub_holder,
114 Code::Kind kind, 114 Code::Kind kind,
115 Code::StubType type, 115 Code::StubType type) {
116 Code::IcFragment fragment) { 116 Code::Flags flags = Code::ComputeMonomorphicFlags(
117 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, fragment, type); 117 kind, Code::kNoExtraICState, type);
118 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), 118 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
119 isolate_); 119 isolate_);
120 if (probe->IsCode()) return Handle<Code>::cast(probe); 120 if (probe->IsCode()) return Handle<Code>::cast(probe);
121 return Handle<Code>::null(); 121 return Handle<Code>::null();
122 } 122 }
123 123
124 124
125 Handle<Code> StubCache::FindHandler(Handle<Name> name, 125 Handle<Code> StubCache::FindStub(Handle<Name> name,
126 Handle<JSObject> handler_holder, 126 Handle<JSObject> stub_holder,
127 Code::Kind kind, 127 Code::Kind kind,
128 Code::StubType type) { 128 Code::StubType type) {
129 return FindStub(name, handler_holder, kind, type, Code::HANDLER_FRAGMENT); 129 ASSERT(type != Code::NORMAL);
130 int extra_flags = -1;
131 if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC) {
132 extra_flags = kind;
133 kind = Code::STUB;
134 }
135 Code::Flags flags = Code::ComputeMonomorphicFlags(
136 kind, Code::kNoExtraICState, type, extra_flags);
137 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
138 isolate_);
139 if (probe->IsCode()) return Handle<Code>::cast(probe);
140 return Handle<Code>::null();
130 } 141 }
131 142
132 143
133 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<JSObject> receiver, 144 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<JSObject> receiver,
134 Handle<Code> handler, 145 Handle<Code> handler,
135 Handle<Name> name) { 146 Handle<Name> name) {
136 Handle<Code> ic = FindStub(name, receiver, Code::LOAD_IC, 147 Handle<Code> ic = FindIC(name, receiver, Code::LOAD_IC, handler->type());
137 handler->type(), Code::IC_FRAGMENT);
138 if (!ic.is_null()) return ic; 148 if (!ic.is_null()) return ic;
139 149
140 LoadStubCompiler ic_compiler(isolate()); 150 LoadStubCompiler ic_compiler(isolate());
141 ic = ic_compiler.CompileMonomorphicIC( 151 ic = ic_compiler.CompileMonomorphicIC(
142 Handle<Map>(receiver->map()), handler, name); 152 Handle<Map>(receiver->map()), handler, name);
143 153
144 JSObject::UpdateMapCodeCache(receiver, name, ic); 154 JSObject::UpdateMapCodeCache(receiver, name, ic);
145 return ic; 155 return ic;
146 } 156 }
147 157
148 158
149 Handle<Code> StubCache::ComputeKeyedMonomorphicIC(Handle<JSObject> receiver, 159 Handle<Code> StubCache::ComputeKeyedMonomorphicIC(Handle<JSObject> receiver,
150 Handle<Code> handler, 160 Handle<Code> handler,
151 Handle<Name> name) { 161 Handle<Name> name) {
152 Handle<Code> ic = FindStub(name, receiver, Code::KEYED_LOAD_IC, 162 Handle<Code> ic = FindIC(
153 handler->type(), Code::IC_FRAGMENT); 163 name, receiver, Code::KEYED_LOAD_IC, handler->type());
154 if (!ic.is_null()) return ic; 164 if (!ic.is_null()) return ic;
155 165
156 KeyedLoadStubCompiler ic_compiler(isolate()); 166 KeyedLoadStubCompiler ic_compiler(isolate());
157 ic = ic_compiler.CompileMonomorphicIC( 167 ic = ic_compiler.CompileMonomorphicIC(
158 Handle<Map>(receiver->map()), handler, name); 168 Handle<Map>(receiver->map()), handler, name);
159 169
160 JSObject::UpdateMapCodeCache(receiver, name, ic); 170 JSObject::UpdateMapCodeCache(receiver, name, ic);
161 return ic; 171 return ic;
162 } 172 }
163 173
(...skipping 16 matching lines...) Expand all
180 if (current->IsGlobalObject()) { 190 if (current->IsGlobalObject()) {
181 global = Handle<GlobalObject>::cast(current); 191 global = Handle<GlobalObject>::cast(current);
182 cache_name = name; 192 cache_name = name;
183 } else if (!current->HasFastProperties()) { 193 } else if (!current->HasFastProperties()) {
184 cache_name = name; 194 cache_name = name;
185 } 195 }
186 } while (!next->IsNull()); 196 } while (!next->IsNull());
187 197
188 // Compile the stub that is either shared for all names or 198 // Compile the stub that is either shared for all names or
189 // name specific if there are global objects involved. 199 // name specific if there are global objects involved.
190 Handle<Code> handler = FindHandler( 200 Handle<Code> handler = FindStub(
191 cache_name, receiver, Code::LOAD_IC, Code::NONEXISTENT); 201 cache_name, receiver, Code::LOAD_IC, Code::NONEXISTENT);
192 if (!handler.is_null()) return handler; 202 if (!handler.is_null()) return handler;
193 203
194 LoadStubCompiler compiler(isolate_); 204 LoadStubCompiler compiler(isolate_);
195 handler = 205 handler =
196 compiler.CompileLoadNonexistent(receiver, current, cache_name, global); 206 compiler.CompileLoadNonexistent(receiver, current, cache_name, global);
197 JSObject::UpdateMapCodeCache(receiver, cache_name, handler); 207 JSObject::UpdateMapCodeCache(receiver, cache_name, handler);
198 return handler; 208 return handler;
199 } 209 }
200 210
201 211
202 Handle<Code> StubCache::ComputeLoadField(Handle<Name> name, 212 Handle<Code> StubCache::ComputeLoadField(Handle<Name> name,
203 Handle<JSObject> receiver, 213 Handle<JSObject> receiver,
204 Handle<JSObject> holder, 214 Handle<JSObject> holder,
205 PropertyIndex field) { 215 PropertyIndex field) {
206 if (receiver.is_identical_to(holder)) { 216 if (receiver.is_identical_to(holder)) {
207 LoadFieldStub stub(LoadStubCompiler::receiver(), 217 LoadFieldStub stub(LoadStubCompiler::receiver(),
208 field.is_inobject(holder), 218 field.is_inobject(holder),
209 field.translate(holder)); 219 field.translate(holder));
210 return stub.GetCode(isolate()); 220 return stub.GetCode(isolate());
211 } 221 }
212 222
213 Handle<JSObject> stub_holder = StubHolder(receiver, holder); 223 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
214 Handle<Code> stub = FindHandler( 224 Handle<Code> stub = FindStub(
215 name, stub_holder, Code::LOAD_IC, Code::FIELD); 225 name, stub_holder, Code::LOAD_IC, Code::FIELD);
216 if (!stub.is_null()) return stub; 226 if (!stub.is_null()) return stub;
217 227
218 LoadStubCompiler compiler(isolate_); 228 LoadStubCompiler compiler(isolate_);
219 Handle<Code> handler = 229 Handle<Code> handler =
220 compiler.CompileLoadField(receiver, holder, name, field); 230 compiler.CompileLoadField(receiver, holder, name, field);
221 JSObject::UpdateMapCodeCache(stub_holder, name, handler); 231 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
222 return handler; 232 return handler;
223 } 233 }
224 234
225 235
226 Handle<Code> StubCache::ComputeLoadCallback( 236 Handle<Code> StubCache::ComputeLoadCallback(
227 Handle<Name> name, 237 Handle<Name> name,
228 Handle<JSObject> receiver, 238 Handle<JSObject> receiver,
229 Handle<JSObject> holder, 239 Handle<JSObject> holder,
230 Handle<ExecutableAccessorInfo> callback) { 240 Handle<ExecutableAccessorInfo> callback) {
231 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); 241 ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
232 Handle<JSObject> stub_holder = StubHolder(receiver, holder); 242 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
233 Handle<Code> stub = FindHandler( 243 Handle<Code> stub = FindStub(
234 name, stub_holder, Code::LOAD_IC, Code::CALLBACKS); 244 name, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
235 if (!stub.is_null()) return stub; 245 if (!stub.is_null()) return stub;
236 246
237 LoadStubCompiler compiler(isolate_); 247 LoadStubCompiler compiler(isolate_);
238 Handle<Code> handler = 248 Handle<Code> handler =
239 compiler.CompileLoadCallback(receiver, holder, name, callback); 249 compiler.CompileLoadCallback(receiver, holder, name, callback);
240 JSObject::UpdateMapCodeCache(stub_holder, name, handler); 250 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
241 return handler; 251 return handler;
242 } 252 }
243 253
244 254
245 Handle<Code> StubCache::ComputeLoadViaGetter(Handle<Name> name, 255 Handle<Code> StubCache::ComputeLoadViaGetter(Handle<Name> name,
246 Handle<JSObject> receiver, 256 Handle<JSObject> receiver,
247 Handle<JSObject> holder, 257 Handle<JSObject> holder,
248 Handle<JSFunction> getter) { 258 Handle<JSFunction> getter) {
249 Handle<JSObject> stub_holder = StubHolder(receiver, holder); 259 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
250 Handle<Code> stub = FindHandler( 260 Handle<Code> stub = FindStub(
251 name, stub_holder, Code::LOAD_IC, Code::CALLBACKS); 261 name, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
252 if (!stub.is_null()) return stub; 262 if (!stub.is_null()) return stub;
253 263
254 LoadStubCompiler compiler(isolate_); 264 LoadStubCompiler compiler(isolate_);
255 Handle<Code> handler = 265 Handle<Code> handler =
256 compiler.CompileLoadViaGetter(receiver, holder, name, getter); 266 compiler.CompileLoadViaGetter(receiver, holder, name, getter);
257 JSObject::UpdateMapCodeCache(stub_holder, name, handler); 267 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
258 return handler; 268 return handler;
259 } 269 }
260 270
261 271
262 Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name, 272 Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name,
263 Handle<JSObject> receiver, 273 Handle<JSObject> receiver,
264 Handle<JSObject> holder, 274 Handle<JSObject> holder,
265 Handle<JSFunction> value) { 275 Handle<JSFunction> value) {
266 Handle<JSObject> stub_holder = StubHolder(receiver, holder); 276 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
267 Handle<Code> handler = FindHandler( 277 Handle<Code> handler = FindStub(
268 name, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION); 278 name, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION);
269 if (!handler.is_null()) return handler; 279 if (!handler.is_null()) return handler;
270 280
271 LoadStubCompiler compiler(isolate_); 281 LoadStubCompiler compiler(isolate_);
272 handler = compiler.CompileLoadConstant(receiver, holder, name, value); 282 handler = compiler.CompileLoadConstant(receiver, holder, name, value);
273 JSObject::UpdateMapCodeCache(stub_holder, name, handler); 283 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
274 284
275 return handler; 285 return handler;
276 } 286 }
277 287
278 288
279 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<Name> name, 289 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<Name> name,
280 Handle<JSObject> receiver, 290 Handle<JSObject> receiver,
281 Handle<JSObject> holder) { 291 Handle<JSObject> holder) {
282 Handle<JSObject> stub_holder = StubHolder(receiver, holder); 292 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
283 Handle<Code> stub = FindHandler( 293 Handle<Code> stub = FindStub(
284 name, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR); 294 name, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR);
285 if (!stub.is_null()) return stub; 295 if (!stub.is_null()) return stub;
286 296
287 LoadStubCompiler compiler(isolate_); 297 LoadStubCompiler compiler(isolate_);
288 Handle<Code> handler = 298 Handle<Code> handler =
289 compiler.CompileLoadInterceptor(receiver, holder, name); 299 compiler.CompileLoadInterceptor(receiver, holder, name);
290 JSObject::UpdateMapCodeCache(stub_holder, name, handler); 300 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
291 return handler; 301 return handler;
292 } 302 }
293 303
294 304
295 Handle<Code> StubCache::ComputeLoadNormal(Handle<Name> name, 305 Handle<Code> StubCache::ComputeLoadNormal(Handle<Name> name,
296 Handle<JSObject> receiver) { 306 Handle<JSObject> receiver) {
297 return isolate_->builtins()->LoadIC_Normal(); 307 return isolate_->builtins()->LoadIC_Normal();
298 } 308 }
299 309
300 310
301 Handle<Code> StubCache::ComputeLoadGlobal(Handle<Name> name, 311 Handle<Code> StubCache::ComputeLoadGlobal(Handle<Name> name,
302 Handle<JSObject> receiver, 312 Handle<JSObject> receiver,
303 Handle<GlobalObject> holder, 313 Handle<GlobalObject> holder,
304 Handle<JSGlobalPropertyCell> cell, 314 Handle<JSGlobalPropertyCell> cell,
305 bool is_dont_delete) { 315 bool is_dont_delete) {
306 Handle<JSObject> stub_holder = StubHolder(receiver, holder); 316 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
307 Handle<Code> stub = FindStub( 317 Handle<Code> stub = FindIC(name, stub_holder, Code::LOAD_IC, Code::NORMAL);
308 name, stub_holder, Code::LOAD_IC, Code::NORMAL, Code::IC_FRAGMENT);
309 if (!stub.is_null()) return stub; 318 if (!stub.is_null()) return stub;
310 319
311 LoadStubCompiler compiler(isolate_); 320 LoadStubCompiler compiler(isolate_);
312 Handle<Code> ic = 321 Handle<Code> ic =
313 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete); 322 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete);
314 JSObject::UpdateMapCodeCache(stub_holder, name, ic); 323 JSObject::UpdateMapCodeCache(stub_holder, name, ic);
315 return ic; 324 return ic;
316 } 325 }
317 326
318 327
319 Handle<Code> StubCache::ComputeKeyedLoadField(Handle<Name> name, 328 Handle<Code> StubCache::ComputeKeyedLoadField(Handle<Name> name,
320 Handle<JSObject> receiver, 329 Handle<JSObject> receiver,
321 Handle<JSObject> holder, 330 Handle<JSObject> holder,
322 PropertyIndex field) { 331 PropertyIndex field) {
323 if (receiver.is_identical_to(holder)) { 332 if (receiver.is_identical_to(holder)) {
324 LoadFieldStub stub(KeyedLoadStubCompiler::receiver(), 333 LoadFieldStub stub(KeyedLoadStubCompiler::receiver(),
325 field.is_inobject(holder), 334 field.is_inobject(holder),
326 field.translate(holder)); 335 field.translate(holder));
327 return stub.GetCode(isolate()); 336 return stub.GetCode(isolate());
328 } 337 }
329 338
330 Handle<JSObject> stub_holder = StubHolder(receiver, holder); 339 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
331 Handle<Code> stub = FindHandler( 340 Handle<Code> stub = FindStub(
332 name, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD); 341 name, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD);
333 if (!stub.is_null()) return stub; 342 if (!stub.is_null()) return stub;
334 343
335 KeyedLoadStubCompiler compiler(isolate_); 344 KeyedLoadStubCompiler compiler(isolate_);
336 Handle<Code> handler = 345 Handle<Code> handler =
337 compiler.CompileLoadField(receiver, holder, name, field); 346 compiler.CompileLoadField(receiver, holder, name, field);
338 JSObject::UpdateMapCodeCache(stub_holder, name, handler); 347 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
339 return handler; 348 return handler;
340 } 349 }
341 350
342 351
343 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<Name> name, 352 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<Name> name,
344 Handle<JSObject> receiver, 353 Handle<JSObject> receiver,
345 Handle<JSObject> holder, 354 Handle<JSObject> holder,
346 Handle<JSFunction> value) { 355 Handle<JSFunction> value) {
347 Handle<JSObject> stub_holder = StubHolder(receiver, holder); 356 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
348 Handle<Code> handler = FindHandler( 357 Handle<Code> handler = FindStub(
349 name, stub_holder, Code::KEYED_LOAD_IC, Code::CONSTANT_FUNCTION); 358 name, stub_holder, Code::KEYED_LOAD_IC, Code::CONSTANT_FUNCTION);
350 if (!handler.is_null()) return handler; 359 if (!handler.is_null()) return handler;
351 360
352 KeyedLoadStubCompiler compiler(isolate_); 361 KeyedLoadStubCompiler compiler(isolate_);
353 handler = compiler.CompileLoadConstant(receiver, holder, name, value); 362 handler = compiler.CompileLoadConstant(receiver, holder, name, value);
354 JSObject::UpdateMapCodeCache(stub_holder, name, handler); 363 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
355 return handler; 364 return handler;
356 } 365 }
357 366
358 367
359 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name, 368 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name,
360 Handle<JSObject> receiver, 369 Handle<JSObject> receiver,
361 Handle<JSObject> holder) { 370 Handle<JSObject> holder) {
362 Handle<JSObject> stub_holder = StubHolder(receiver, holder); 371 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
363 Handle<Code> stub = FindHandler( 372 Handle<Code> stub = FindStub(
364 name, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR); 373 name, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR);
365 if (!stub.is_null()) return stub; 374 if (!stub.is_null()) return stub;
366 375
367 KeyedLoadStubCompiler compiler(isolate_); 376 KeyedLoadStubCompiler compiler(isolate_);
368 Handle<Code> handler = 377 Handle<Code> handler =
369 compiler.CompileLoadInterceptor(receiver, holder, name); 378 compiler.CompileLoadInterceptor(receiver, holder, name);
370 JSObject::UpdateMapCodeCache(stub_holder, name, handler); 379 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
371 return handler; 380 return handler;
372 } 381 }
373 382
374 383
375 Handle<Code> StubCache::ComputeKeyedLoadCallback( 384 Handle<Code> StubCache::ComputeKeyedLoadCallback(
376 Handle<Name> name, 385 Handle<Name> name,
377 Handle<JSObject> receiver, 386 Handle<JSObject> receiver,
378 Handle<JSObject> holder, 387 Handle<JSObject> holder,
379 Handle<ExecutableAccessorInfo> callback) { 388 Handle<ExecutableAccessorInfo> callback) {
380 Handle<JSObject> stub_holder = StubHolder(receiver, holder); 389 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
381 Handle<Code> stub = FindHandler( 390 Handle<Code> stub = FindStub(
382 name, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS); 391 name, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS);
383 if (!stub.is_null()) return stub; 392 if (!stub.is_null()) return stub;
384 393
385 KeyedLoadStubCompiler compiler(isolate_); 394 KeyedLoadStubCompiler compiler(isolate_);
386 Handle<Code> handler = 395 Handle<Code> handler =
387 compiler.CompileLoadCallback(receiver, holder, name, callback); 396 compiler.CompileLoadCallback(receiver, holder, name, callback);
388 JSObject::UpdateMapCodeCache(stub_holder, name, handler); 397 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
389 return handler; 398 return handler;
390 } 399 }
391 400
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after
888 897
889 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); 898 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
890 return code; 899 return code;
891 } 900 }
892 901
893 902
894 Handle<Code> StubCache::ComputePolymorphicIC(MapHandleList* receiver_maps, 903 Handle<Code> StubCache::ComputePolymorphicIC(MapHandleList* receiver_maps,
895 CodeHandleList* handlers, 904 CodeHandleList* handlers,
896 Handle<Name> name) { 905 Handle<Name> name) {
897 LoadStubCompiler ic_compiler(isolate_); 906 LoadStubCompiler ic_compiler(isolate_);
907 Code::StubType type = handlers->length() == 1 ? handlers->at(0)->type()
908 : Code::NORMAL;
898 Handle<Code> ic = ic_compiler.CompilePolymorphicIC( 909 Handle<Code> ic = ic_compiler.CompilePolymorphicIC(
899 receiver_maps, handlers, name, Code::NORMAL, PROPERTY); 910 receiver_maps, handlers, name, type, PROPERTY);
900 return ic; 911 return ic;
901 } 912 }
902 913
903 914
904 Handle<Code> StubCache::ComputeStoreElementPolymorphic( 915 Handle<Code> StubCache::ComputeStoreElementPolymorphic(
905 MapHandleList* receiver_maps, 916 MapHandleList* receiver_maps,
906 KeyedAccessGrowMode grow_mode, 917 KeyedAccessGrowMode grow_mode,
907 StrictModeFlag strict_mode) { 918 StrictModeFlag strict_mode) {
908 Handle<PolymorphicCodeCache> cache = 919 Handle<PolymorphicCodeCache> cache =
909 isolate_->factory()->polymorphic_code_cache(); 920 isolate_->factory()->polymorphic_code_cache();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 } 985 }
975 986
976 987
977 void StubCache::CollectMatchingMaps(SmallMapList* types, 988 void StubCache::CollectMatchingMaps(SmallMapList* types,
978 Name* name, 989 Name* name,
979 Code::Flags flags, 990 Code::Flags flags,
980 Handle<Context> native_context, 991 Handle<Context> native_context,
981 Zone* zone) { 992 Zone* zone) {
982 for (int i = 0; i < kPrimaryTableSize; i++) { 993 for (int i = 0; i < kPrimaryTableSize; i++) {
983 if (primary_[i].key == name) { 994 if (primary_[i].key == name) {
984 Map* map = primary_[i].value->FindFirstMap(); 995 Map* map = primary_[i].map;
985 // Map can be NULL, if the stub is constant function call 996 // Map can be NULL, if the stub is constant function call
986 // with a primitive receiver. 997 // with a primitive receiver.
987 if (map == NULL) continue; 998 if (map == NULL) continue;
988 999
989 int offset = PrimaryOffset(name, flags, map); 1000 int offset = PrimaryOffset(name, flags, map);
990 if (entry(primary_, offset) == &primary_[i] && 1001 if (entry(primary_, offset) == &primary_[i] &&
991 !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) { 1002 !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) {
992 types->Add(Handle<Map>(map), zone); 1003 types->Add(Handle<Map>(map), zone);
993 } 1004 }
994 } 1005 }
995 } 1006 }
996 1007
997 for (int i = 0; i < kSecondaryTableSize; i++) { 1008 for (int i = 0; i < kSecondaryTableSize; i++) {
998 if (secondary_[i].key == name) { 1009 if (secondary_[i].key == name) {
999 Map* map = secondary_[i].value->FindFirstMap(); 1010 Map* map = secondary_[i].map;
1000 // Map can be NULL, if the stub is constant function call 1011 // Map can be NULL, if the stub is constant function call
1001 // with a primitive receiver. 1012 // with a primitive receiver.
1002 if (map == NULL) continue; 1013 if (map == NULL) continue;
1003 1014
1004 // Lookup in primary table and skip duplicates. 1015 // Lookup in primary table and skip duplicates.
1005 int primary_offset = PrimaryOffset(name, flags, map); 1016 int primary_offset = PrimaryOffset(name, flags, map);
1006 Entry* primary_entry = entry(primary_, primary_offset); 1017 Entry* primary_entry = entry(primary_, primary_offset);
1007 if (primary_entry->key == name) { 1018 if (primary_entry->key == name) {
1008 Map* primary_map = primary_entry->value->FindFirstMap(); 1019 Map* primary_map = primary_entry->map;
1009 if (map == primary_map) continue; 1020 if (map == primary_map) continue;
1010 } 1021 }
1011 1022
1012 // Lookup in secondary table and add matches. 1023 // Lookup in secondary table and add matches.
1013 int offset = SecondaryOffset(name, flags, primary_offset); 1024 int offset = SecondaryOffset(name, flags, primary_offset);
1014 if (entry(secondary_, offset) == &secondary_[i] && 1025 if (entry(secondary_, offset) == &secondary_[i] &&
1015 !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) { 1026 !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) {
1016 types->Add(Handle<Map>(map), zone); 1027 types->Add(Handle<Map>(map), zone);
1017 } 1028 }
1018 } 1029 }
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1441 1452
1442 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss); 1453 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss);
1443 1454
1444 LoadFieldStub stub(reg, field.is_inobject(holder), field.translate(holder)); 1455 LoadFieldStub stub(reg, field.is_inobject(holder), field.translate(holder));
1445 GenerateTailCall(stub.GetCode(isolate())); 1456 GenerateTailCall(stub.GetCode(isolate()));
1446 1457
1447 __ bind(&miss); 1458 __ bind(&miss);
1448 GenerateLoadMiss(masm(), kind()); 1459 GenerateLoadMiss(masm(), kind());
1449 1460
1450 // Return the generated code. 1461 // Return the generated code.
1451 return GetCode(Code::HANDLER_FRAGMENT, Code::FIELD, name); 1462 return GetCode(kind(), Code::FIELD, name);
1452 } 1463 }
1453 1464
1454 1465
1455 Handle<Code> BaseLoadStubCompiler::CompileLoadConstant( 1466 Handle<Code> BaseLoadStubCompiler::CompileLoadConstant(
1456 Handle<JSObject> object, 1467 Handle<JSObject> object,
1457 Handle<JSObject> holder, 1468 Handle<JSObject> holder,
1458 Handle<Name> name, 1469 Handle<Name> name,
1459 Handle<JSFunction> value) { 1470 Handle<JSFunction> value) {
1460 Label success; 1471 Label success;
1461 HandlerFrontend(object, receiver(), holder, name, &success); 1472 HandlerFrontend(object, receiver(), holder, name, &success);
1462 __ bind(&success); 1473 __ bind(&success);
1463 GenerateLoadConstant(value); 1474 GenerateLoadConstant(value);
1464 1475
1465 // Return the generated code. 1476 // Return the generated code.
1466 return GetCode(Code::HANDLER_FRAGMENT, Code::CONSTANT_FUNCTION, name); 1477 return GetCode(kind(), Code::CONSTANT_FUNCTION, name);
1467 } 1478 }
1468 1479
1469 1480
1470 Handle<Code> BaseLoadStubCompiler::CompileLoadCallback( 1481 Handle<Code> BaseLoadStubCompiler::CompileLoadCallback(
1471 Handle<JSObject> object, 1482 Handle<JSObject> object,
1472 Handle<JSObject> holder, 1483 Handle<JSObject> holder,
1473 Handle<Name> name, 1484 Handle<Name> name,
1474 Handle<ExecutableAccessorInfo> callback) { 1485 Handle<ExecutableAccessorInfo> callback) {
1475 Label success; 1486 Label success;
1476 1487
1477 Register reg = CallbackHandlerFrontend( 1488 Register reg = CallbackHandlerFrontend(
1478 object, receiver(), holder, name, &success, callback); 1489 object, receiver(), holder, name, &success, callback);
1479 __ bind(&success); 1490 __ bind(&success);
1480 GenerateLoadCallback(reg, callback); 1491 GenerateLoadCallback(reg, callback);
1481 1492
1482 // Return the generated code. 1493 // Return the generated code.
1483 return GetCode(Code::HANDLER_FRAGMENT, Code::CALLBACKS, name); 1494 return GetCode(kind(), Code::CALLBACKS, name);
1484 } 1495 }
1485 1496
1486 1497
1487 Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor( 1498 Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor(
1488 Handle<JSObject> object, 1499 Handle<JSObject> object,
1489 Handle<JSObject> holder, 1500 Handle<JSObject> holder,
1490 Handle<Name> name) { 1501 Handle<Name> name) {
1491 Label success; 1502 Label success;
1492 1503
1493 LookupResult lookup(isolate()); 1504 LookupResult lookup(isolate());
1494 LookupPostInterceptor(holder, name, &lookup); 1505 LookupPostInterceptor(holder, name, &lookup);
1495 1506
1496 Register reg = HandlerFrontend(object, receiver(), holder, name, &success); 1507 Register reg = HandlerFrontend(object, receiver(), holder, name, &success);
1497 __ bind(&success); 1508 __ bind(&success);
1498 // TODO(368): Compile in the whole chain: all the interceptors in 1509 // TODO(368): Compile in the whole chain: all the interceptors in
1499 // prototypes and ultimate answer. 1510 // prototypes and ultimate answer.
1500 GenerateLoadInterceptor(reg, object, holder, &lookup, name); 1511 GenerateLoadInterceptor(reg, object, holder, &lookup, name);
1501 1512
1502 // Return the generated code. 1513 // Return the generated code.
1503 return GetCode(Code::HANDLER_FRAGMENT, Code::INTERCEPTOR, name); 1514 return GetCode(kind(), Code::INTERCEPTOR, name);
1504 } 1515 }
1505 1516
1506 1517
1507 void BaseLoadStubCompiler::GenerateLoadPostInterceptor( 1518 void BaseLoadStubCompiler::GenerateLoadPostInterceptor(
1508 Register interceptor_reg, 1519 Register interceptor_reg,
1509 Handle<JSObject> interceptor_holder, 1520 Handle<JSObject> interceptor_holder,
1510 Handle<Name> name, 1521 Handle<Name> name,
1511 LookupResult* lookup) { 1522 LookupResult* lookup) {
1512 Label success; 1523 Label success;
1513 Handle<JSObject> holder(lookup->holder()); 1524 Handle<JSObject> holder(lookup->holder());
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1560 Handle<JSObject> holder, 1571 Handle<JSObject> holder,
1561 Handle<Name> name, 1572 Handle<Name> name,
1562 Handle<JSFunction> getter) { 1573 Handle<JSFunction> getter) {
1563 Label success; 1574 Label success;
1564 HandlerFrontend(object, receiver(), holder, name, &success); 1575 HandlerFrontend(object, receiver(), holder, name, &success);
1565 1576
1566 __ bind(&success); 1577 __ bind(&success);
1567 GenerateLoadViaGetter(masm(), getter); 1578 GenerateLoadViaGetter(masm(), getter);
1568 1579
1569 // Return the generated code. 1580 // Return the generated code.
1570 return GetCode(Code::HANDLER_FRAGMENT, Code::CALLBACKS, name); 1581 return GetCode(kind(), Code::CALLBACKS, name);
1571 } 1582 }
1572 1583
1573 1584
1574 #undef __ 1585 #undef __
1575 1586
1576 1587
1577 void LoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { 1588 void LoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
1578 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 1589 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
1579 } 1590 }
1580 1591
1581 1592
1582 void KeyedLoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { 1593 void KeyedLoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
1583 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); 1594 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
1584 } 1595 }
1585 1596
1586 1597
1587 Handle<Code> BaseLoadStubCompiler::GetCode(Code::IcFragment fragment, 1598 Handle<Code> BaseLoadStubCompiler::GetICCode(Code::Kind kind,
1588 Code::StubType type, 1599 Code::StubType type,
1589 Handle<Name> name, 1600 Handle<Name> name,
1590 InlineCacheState state) { 1601 InlineCacheState state) {
1591 Code::Flags flags = Code::ComputeFlags(kind(), state, fragment, type); 1602 Code::Flags flags = Code::ComputeFlags(
1603 kind, state, Code::kNoExtraICState, type);
1592 Handle<Code> code = GetCodeWithFlags(flags, name); 1604 Handle<Code> code = GetCodeWithFlags(flags, name);
1593 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); 1605 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
1594 JitEvent(name, code); 1606 JitEvent(name, code);
1607 return code;
1608 }
1609
1610
1611 Handle<Code> BaseLoadStubCompiler::GetCode(Code::Kind kind,
1612 Code::StubType type,
1613 Handle<Name> name) {
1614 ASSERT(type != Code::NORMAL);
1615 Code::Flags flags = Code::ComputeFlags(
1616 Code::STUB, MONOMORPHIC, Code::kNoExtraICState, type, kind);
1617 Handle<Code> code = GetCodeWithFlags(flags, name);
1618 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
1619 JitEvent(name, code);
1595 return code; 1620 return code;
1596 } 1621 }
1597 1622
1598 1623
1599 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps, 1624 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps,
1600 CodeHandleList* handlers) { 1625 CodeHandleList* handlers) {
1601 for (int i = 0; i < receiver_maps->length(); ++i) { 1626 for (int i = 0; i < receiver_maps->length(); ++i) {
1602 Handle<Map> receiver_map = receiver_maps->at(i); 1627 Handle<Map> receiver_map = receiver_maps->at(i);
1603 Handle<Code> cached_stub; 1628 Handle<Code> cached_stub;
1604 1629
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
1853 Handle<FunctionTemplateInfo>( 1878 Handle<FunctionTemplateInfo>(
1854 FunctionTemplateInfo::cast(signature->receiver())); 1879 FunctionTemplateInfo::cast(signature->receiver()));
1855 } 1880 }
1856 } 1881 }
1857 1882
1858 is_simple_api_call_ = true; 1883 is_simple_api_call_ = true;
1859 } 1884 }
1860 1885
1861 1886
1862 } } // namespace v8::internal 1887 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698