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

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

Issue 2801018: This change allows generating call-stubs for objects with normal (non-fast) o... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 5 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/v8-counters.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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 } 87 }
88 88
89 // Update primary cache. 89 // Update primary cache.
90 primary->key = name; 90 primary->key = name;
91 primary->value = code; 91 primary->value = code;
92 return code; 92 return code;
93 } 93 }
94 94
95 95
96 Object* StubCache::ComputeLoadNonexistent(String* name, JSObject* receiver) { 96 Object* StubCache::ComputeLoadNonexistent(String* name, JSObject* receiver) {
97 ASSERT(receiver->IsGlobalObject() || receiver->HasFastProperties());
97 // If no global objects are present in the prototype chain, the load 98 // If no global objects are present in the prototype chain, the load
98 // nonexistent IC stub can be shared for all names for a given map 99 // nonexistent IC stub can be shared for all names for a given map
99 // and we use the empty string for the map cache in that case. If 100 // and we use the empty string for the map cache in that case. If
100 // there are global objects involved, we need to check global 101 // there are global objects involved, we need to check global
101 // property cells in the stub and therefore the stub will be 102 // property cells in the stub and therefore the stub will be
102 // specific to the name. 103 // specific to the name.
103 String* cache_name = Heap::empty_string(); 104 String* cache_name = Heap::empty_string();
104 if (receiver->IsGlobalObject()) cache_name = name; 105 if (receiver->IsGlobalObject()) cache_name = name;
105 JSObject* last = receiver; 106 JSObject* last = receiver;
106 while (last->GetPrototype() != Heap::null_value()) { 107 while (last->GetPrototype() != Heap::null_value()) {
(...skipping 15 matching lines...) Expand all
122 if (result->IsFailure()) return result; 123 if (result->IsFailure()) return result;
123 } 124 }
124 return code; 125 return code;
125 } 126 }
126 127
127 128
128 Object* StubCache::ComputeLoadField(String* name, 129 Object* StubCache::ComputeLoadField(String* name,
129 JSObject* receiver, 130 JSObject* receiver,
130 JSObject* holder, 131 JSObject* holder,
131 int field_index) { 132 int field_index) {
133 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
134 Map* map = receiver->map();
132 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD); 135 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD);
133 Object* code = receiver->map()->FindInCodeCache(name, flags); 136 Object* code = map->FindInCodeCache(name, flags);
134 if (code->IsUndefined()) { 137 if (code->IsUndefined()) {
135 LoadStubCompiler compiler; 138 LoadStubCompiler compiler;
136 code = compiler.CompileLoadField(receiver, holder, field_index, name); 139 code = compiler.CompileLoadField(receiver, holder, field_index, name);
137 if (code->IsFailure()) return code; 140 if (code->IsFailure()) return code;
138 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); 141 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
139 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 142 Object* result = map->UpdateCodeCache(name, Code::cast(code));
140 if (result->IsFailure()) return result; 143 if (result->IsFailure()) return result;
141 } 144 }
142 return code; 145 return code;
143 } 146 }
144 147
145 148
146 Object* StubCache::ComputeLoadCallback(String* name, 149 Object* StubCache::ComputeLoadCallback(String* name,
147 JSObject* receiver, 150 JSObject* receiver,
148 JSObject* holder, 151 JSObject* holder,
149 AccessorInfo* callback) { 152 AccessorInfo* callback) {
150 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); 153 ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
154 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
155 Map* map = receiver->map();
151 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS); 156 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS);
152 Object* code = receiver->map()->FindInCodeCache(name, flags); 157 Object* code = map->FindInCodeCache(name, flags);
153 if (code->IsUndefined()) { 158 if (code->IsUndefined()) {
154 LoadStubCompiler compiler; 159 LoadStubCompiler compiler;
155 code = compiler.CompileLoadCallback(name, receiver, holder, callback); 160 code = compiler.CompileLoadCallback(name, receiver, holder, callback);
156 if (code->IsFailure()) return code; 161 if (code->IsFailure()) return code;
157 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); 162 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
158 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 163 Object* result = map->UpdateCodeCache(name, Code::cast(code));
159 if (result->IsFailure()) return result; 164 if (result->IsFailure()) return result;
160 } 165 }
161 return code; 166 return code;
162 } 167 }
163 168
164 169
165 Object* StubCache::ComputeLoadConstant(String* name, 170 Object* StubCache::ComputeLoadConstant(String* name,
166 JSObject* receiver, 171 JSObject* receiver,
167 JSObject* holder, 172 JSObject* holder,
168 Object* value) { 173 Object* value) {
174 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
175 Map* map = receiver->map();
169 Code::Flags flags = 176 Code::Flags flags =
170 Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION); 177 Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION);
171 Object* code = receiver->map()->FindInCodeCache(name, flags); 178 Object* code = map->FindInCodeCache(name, flags);
172 if (code->IsUndefined()) { 179 if (code->IsUndefined()) {
173 LoadStubCompiler compiler; 180 LoadStubCompiler compiler;
174 code = compiler.CompileLoadConstant(receiver, holder, value, name); 181 code = compiler.CompileLoadConstant(receiver, holder, value, name);
175 if (code->IsFailure()) return code; 182 if (code->IsFailure()) return code;
176 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); 183 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
177 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 184 Object* result = map->UpdateCodeCache(name, Code::cast(code));
178 if (result->IsFailure()) return result; 185 if (result->IsFailure()) return result;
179 } 186 }
180 return code; 187 return code;
181 } 188 }
182 189
183 190
184 Object* StubCache::ComputeLoadInterceptor(String* name, 191 Object* StubCache::ComputeLoadInterceptor(String* name,
185 JSObject* receiver, 192 JSObject* receiver,
186 JSObject* holder) { 193 JSObject* holder) {
194 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
195 Map* map = receiver->map();
187 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR); 196 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR);
188 Object* code = receiver->map()->FindInCodeCache(name, flags); 197 Object* code = map->FindInCodeCache(name, flags);
189 if (code->IsUndefined()) { 198 if (code->IsUndefined()) {
190 LoadStubCompiler compiler; 199 LoadStubCompiler compiler;
191 code = compiler.CompileLoadInterceptor(receiver, holder, name); 200 code = compiler.CompileLoadInterceptor(receiver, holder, name);
192 if (code->IsFailure()) return code; 201 if (code->IsFailure()) return code;
193 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); 202 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
194 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 203 Object* result = map->UpdateCodeCache(name, Code::cast(code));
195 if (result->IsFailure()) return result; 204 if (result->IsFailure()) return result;
196 } 205 }
197 return code; 206 return code;
198 } 207 }
199 208
200 209
201 Object* StubCache::ComputeLoadNormal() { 210 Object* StubCache::ComputeLoadNormal() {
202 return Builtins::builtin(Builtins::LoadIC_Normal); 211 return Builtins::builtin(Builtins::LoadIC_Normal);
203 } 212 }
204 213
205 214
206 Object* StubCache::ComputeLoadGlobal(String* name, 215 Object* StubCache::ComputeLoadGlobal(String* name,
207 JSObject* receiver, 216 JSObject* receiver,
208 GlobalObject* holder, 217 GlobalObject* holder,
209 JSGlobalPropertyCell* cell, 218 JSGlobalPropertyCell* cell,
210 bool is_dont_delete) { 219 bool is_dont_delete) {
220 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
221 Map* map = receiver->map();
211 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL); 222 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
212 Object* code = receiver->map()->FindInCodeCache(name, flags); 223 Object* code = map->FindInCodeCache(name, flags);
213 if (code->IsUndefined()) { 224 if (code->IsUndefined()) {
214 LoadStubCompiler compiler; 225 LoadStubCompiler compiler;
215 code = compiler.CompileLoadGlobal(receiver, 226 code = compiler.CompileLoadGlobal(receiver,
216 holder, 227 holder,
217 cell, 228 cell,
218 name, 229 name,
219 is_dont_delete); 230 is_dont_delete);
220 if (code->IsFailure()) return code; 231 if (code->IsFailure()) return code;
221 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); 232 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
222 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 233 Object* result = map->UpdateCodeCache(name, Code::cast(code));
223 if (result->IsFailure()) return result; 234 if (result->IsFailure()) return result;
224 } 235 }
225 return code; 236 return code;
226 } 237 }
227 238
228 239
229 Object* StubCache::ComputeKeyedLoadField(String* name, 240 Object* StubCache::ComputeKeyedLoadField(String* name,
230 JSObject* receiver, 241 JSObject* receiver,
231 JSObject* holder, 242 JSObject* holder,
232 int field_index) { 243 int field_index) {
244 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
245 Map* map = receiver->map();
233 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD); 246 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD);
234 Object* code = receiver->map()->FindInCodeCache(name, flags); 247 Object* code = map->FindInCodeCache(name, flags);
235 if (code->IsUndefined()) { 248 if (code->IsUndefined()) {
236 KeyedLoadStubCompiler compiler; 249 KeyedLoadStubCompiler compiler;
237 code = compiler.CompileLoadField(name, receiver, holder, field_index); 250 code = compiler.CompileLoadField(name, receiver, holder, field_index);
238 if (code->IsFailure()) return code; 251 if (code->IsFailure()) return code;
239 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); 252 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
240 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 253 Object* result = map->UpdateCodeCache(name, Code::cast(code));
241 if (result->IsFailure()) return result; 254 if (result->IsFailure()) return result;
242 } 255 }
243 return code; 256 return code;
244 } 257 }
245 258
246 259
247 Object* StubCache::ComputeKeyedLoadConstant(String* name, 260 Object* StubCache::ComputeKeyedLoadConstant(String* name,
248 JSObject* receiver, 261 JSObject* receiver,
249 JSObject* holder, 262 JSObject* holder,
250 Object* value) { 263 Object* value) {
264 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
265 Map* map = receiver->map();
251 Code::Flags flags = 266 Code::Flags flags =
252 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION); 267 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION);
253 Object* code = receiver->map()->FindInCodeCache(name, flags); 268 Object* code = map->FindInCodeCache(name, flags);
254 if (code->IsUndefined()) { 269 if (code->IsUndefined()) {
255 KeyedLoadStubCompiler compiler; 270 KeyedLoadStubCompiler compiler;
256 code = compiler.CompileLoadConstant(name, receiver, holder, value); 271 code = compiler.CompileLoadConstant(name, receiver, holder, value);
257 if (code->IsFailure()) return code; 272 if (code->IsFailure()) return code;
258 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); 273 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
259 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 274 Object* result = map->UpdateCodeCache(name, Code::cast(code));
260 if (result->IsFailure()) return result; 275 if (result->IsFailure()) return result;
261 } 276 }
262 return code; 277 return code;
263 } 278 }
264 279
265 280
266 Object* StubCache::ComputeKeyedLoadInterceptor(String* name, 281 Object* StubCache::ComputeKeyedLoadInterceptor(String* name,
267 JSObject* receiver, 282 JSObject* receiver,
268 JSObject* holder) { 283 JSObject* holder) {
284 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
285 Map* map = receiver->map();
269 Code::Flags flags = 286 Code::Flags flags =
270 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR); 287 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR);
271 Object* code = receiver->map()->FindInCodeCache(name, flags); 288 Object* code = map->FindInCodeCache(name, flags);
272 if (code->IsUndefined()) { 289 if (code->IsUndefined()) {
273 KeyedLoadStubCompiler compiler; 290 KeyedLoadStubCompiler compiler;
274 code = compiler.CompileLoadInterceptor(receiver, holder, name); 291 code = compiler.CompileLoadInterceptor(receiver, holder, name);
275 if (code->IsFailure()) return code; 292 if (code->IsFailure()) return code;
276 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); 293 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
277 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 294 Object* result = map->UpdateCodeCache(name, Code::cast(code));
278 if (result->IsFailure()) return result; 295 if (result->IsFailure()) return result;
279 } 296 }
280 return code; 297 return code;
281 } 298 }
282 299
283 300
284 Object* StubCache::ComputeKeyedLoadCallback(String* name, 301 Object* StubCache::ComputeKeyedLoadCallback(String* name,
285 JSObject* receiver, 302 JSObject* receiver,
286 JSObject* holder, 303 JSObject* holder,
287 AccessorInfo* callback) { 304 AccessorInfo* callback) {
305 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
306 Map* map = receiver->map();
288 Code::Flags flags = 307 Code::Flags flags =
289 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); 308 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
290 Object* code = receiver->map()->FindInCodeCache(name, flags); 309 Object* code = map->FindInCodeCache(name, flags);
291 if (code->IsUndefined()) { 310 if (code->IsUndefined()) {
292 KeyedLoadStubCompiler compiler; 311 KeyedLoadStubCompiler compiler;
293 code = compiler.CompileLoadCallback(name, receiver, holder, callback); 312 code = compiler.CompileLoadCallback(name, receiver, holder, callback);
294 if (code->IsFailure()) return code; 313 if (code->IsFailure()) return code;
295 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); 314 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
296 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 315 Object* result = map->UpdateCodeCache(name, Code::cast(code));
297 if (result->IsFailure()) return result; 316 if (result->IsFailure()) return result;
298 } 317 }
299 return code; 318 return code;
300 } 319 }
301 320
302 321
303 322
304 Object* StubCache::ComputeKeyedLoadArrayLength(String* name, 323 Object* StubCache::ComputeKeyedLoadArrayLength(String* name,
305 JSArray* receiver) { 324 JSArray* receiver) {
306 Code::Flags flags = 325 Code::Flags flags =
307 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); 326 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
308 Object* code = receiver->map()->FindInCodeCache(name, flags); 327 ASSERT(receiver->IsJSObject());
328 Map* map = receiver->map();
329 Object* code = map->FindInCodeCache(name, flags);
309 if (code->IsUndefined()) { 330 if (code->IsUndefined()) {
310 KeyedLoadStubCompiler compiler; 331 KeyedLoadStubCompiler compiler;
311 code = compiler.CompileLoadArrayLength(name); 332 code = compiler.CompileLoadArrayLength(name);
312 if (code->IsFailure()) return code; 333 if (code->IsFailure()) return code;
313 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); 334 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
314 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 335 Object* result = map->UpdateCodeCache(name, Code::cast(code));
315 if (result->IsFailure()) return result; 336 if (result->IsFailure()) return result;
316 } 337 }
317 return code; 338 return code;
318 } 339 }
319 340
320 341
321 Object* StubCache::ComputeKeyedLoadStringLength(String* name, 342 Object* StubCache::ComputeKeyedLoadStringLength(String* name,
322 String* receiver) { 343 String* receiver) {
323 Code::Flags flags = 344 Code::Flags flags =
324 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); 345 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
325 Object* code = receiver->map()->FindInCodeCache(name, flags); 346 Map* map = receiver->map();
347 Object* code = map->FindInCodeCache(name, flags);
326 if (code->IsUndefined()) { 348 if (code->IsUndefined()) {
327 KeyedLoadStubCompiler compiler; 349 KeyedLoadStubCompiler compiler;
328 code = compiler.CompileLoadStringLength(name); 350 code = compiler.CompileLoadStringLength(name);
329 if (code->IsFailure()) return code; 351 if (code->IsFailure()) return code;
330 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); 352 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
331 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 353 Object* result = map->UpdateCodeCache(name, Code::cast(code));
332 if (result->IsFailure()) return result; 354 if (result->IsFailure()) return result;
333 } 355 }
334 return code; 356 return code;
335 } 357 }
336 358
337 359
338 Object* StubCache::ComputeKeyedLoadFunctionPrototype(String* name, 360 Object* StubCache::ComputeKeyedLoadFunctionPrototype(String* name,
339 JSFunction* receiver) { 361 JSFunction* receiver) {
340 Code::Flags flags = 362 Code::Flags flags =
341 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); 363 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
342 Object* code = receiver->map()->FindInCodeCache(name, flags); 364 Map* map = receiver->map();
365 Object* code = map->FindInCodeCache(name, flags);
343 if (code->IsUndefined()) { 366 if (code->IsUndefined()) {
344 KeyedLoadStubCompiler compiler; 367 KeyedLoadStubCompiler compiler;
345 code = compiler.CompileLoadFunctionPrototype(name); 368 code = compiler.CompileLoadFunctionPrototype(name);
346 if (code->IsFailure()) return code; 369 if (code->IsFailure()) return code;
347 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); 370 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
348 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 371 Object* result = map->UpdateCodeCache(name, Code::cast(code));
349 if (result->IsFailure()) return result; 372 if (result->IsFailure()) return result;
350 } 373 }
351 return code; 374 return code;
352 } 375 }
353 376
354 377
355 Object* StubCache::ComputeStoreField(String* name, 378 Object* StubCache::ComputeStoreField(String* name,
356 JSObject* receiver, 379 JSObject* receiver,
357 int field_index, 380 int field_index,
358 Map* transition) { 381 Map* transition) {
(...skipping 19 matching lines...) Expand all
378 401
379 Object* StubCache::ComputeStoreGlobal(String* name, 402 Object* StubCache::ComputeStoreGlobal(String* name,
380 GlobalObject* receiver, 403 GlobalObject* receiver,
381 JSGlobalPropertyCell* cell) { 404 JSGlobalPropertyCell* cell) {
382 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL); 405 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL);
383 Object* code = receiver->map()->FindInCodeCache(name, flags); 406 Object* code = receiver->map()->FindInCodeCache(name, flags);
384 if (code->IsUndefined()) { 407 if (code->IsUndefined()) {
385 StoreStubCompiler compiler; 408 StoreStubCompiler compiler;
386 code = compiler.CompileStoreGlobal(receiver, cell, name); 409 code = compiler.CompileStoreGlobal(receiver, cell, name);
387 if (code->IsFailure()) return code; 410 if (code->IsFailure()) return code;
388 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); 411 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
389 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 412 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
390 if (result->IsFailure()) return result; 413 if (result->IsFailure()) return result;
391 } 414 }
392 return code; 415 return code;
393 } 416 }
394 417
395 418
396 Object* StubCache::ComputeStoreCallback(String* name, 419 Object* StubCache::ComputeStoreCallback(String* name,
397 JSObject* receiver, 420 JSObject* receiver,
398 AccessorInfo* callback) { 421 AccessorInfo* callback) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) 472 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
450 473
451 Object* StubCache::ComputeCallConstant(int argc, 474 Object* StubCache::ComputeCallConstant(int argc,
452 InLoopFlag in_loop, 475 InLoopFlag in_loop,
453 Code::Kind kind, 476 Code::Kind kind,
454 String* name, 477 String* name,
455 Object* object, 478 Object* object,
456 JSObject* holder, 479 JSObject* holder,
457 JSFunction* function) { 480 JSFunction* function) {
458 // Compute the check type and the map. 481 // Compute the check type and the map.
459 Map* map = IC::GetCodeCacheMapForObject(object); 482 InlineCacheHolderFlag cache_holder =
483 IC::GetCodeCacheForObject(object, holder);
484 Map* map = IC::GetCodeCacheMap(object, cache_holder);
460 485
461 // Compute check type based on receiver/holder. 486 // Compute check type based on receiver/holder.
462 StubCompiler::CheckType check = StubCompiler::RECEIVER_MAP_CHECK; 487 StubCompiler::CheckType check = StubCompiler::RECEIVER_MAP_CHECK;
463 if (object->IsString()) { 488 if (object->IsString()) {
464 check = StubCompiler::STRING_CHECK; 489 check = StubCompiler::STRING_CHECK;
465 } else if (object->IsNumber()) { 490 } else if (object->IsNumber()) {
466 check = StubCompiler::NUMBER_CHECK; 491 check = StubCompiler::NUMBER_CHECK;
467 } else if (object->IsBoolean()) { 492 } else if (object->IsBoolean()) {
468 check = StubCompiler::BOOLEAN_CHECK; 493 check = StubCompiler::BOOLEAN_CHECK;
469 } 494 }
470 495
471 Code::Flags flags = 496 Code::Flags flags =
472 Code::ComputeMonomorphicFlags(kind, 497 Code::ComputeMonomorphicFlags(kind,
473 CONSTANT_FUNCTION, 498 CONSTANT_FUNCTION,
499 cache_holder,
474 in_loop, 500 in_loop,
475 argc); 501 argc);
476 Object* code = map->FindInCodeCache(name, flags); 502 Object* code = map->FindInCodeCache(name, flags);
477 if (code->IsUndefined()) { 503 if (code->IsUndefined()) {
478 // If the function hasn't been compiled yet, we cannot do it now 504 // If the function hasn't been compiled yet, we cannot do it now
479 // because it may cause GC. To avoid this issue, we return an 505 // because it may cause GC. To avoid this issue, we return an
480 // internal error which will make sure we do not update any 506 // internal error which will make sure we do not update any
481 // caches. 507 // caches.
482 if (!function->is_compiled()) return Failure::InternalError(); 508 if (!function->is_compiled()) return Failure::InternalError();
483 // Compile the stub - only create stubs for fully compiled functions. 509 // Compile the stub - only create stubs for fully compiled functions.
484 CallStubCompiler compiler(argc, in_loop, kind); 510 CallStubCompiler compiler(argc, in_loop, kind, cache_holder);
485 code = compiler.CompileCallConstant(object, holder, function, name, check); 511 code = compiler.CompileCallConstant(object, holder, function, name, check);
486 if (code->IsFailure()) return code; 512 if (code->IsFailure()) return code;
487 ASSERT_EQ(flags, Code::cast(code)->flags()); 513 ASSERT_EQ(flags, Code::cast(code)->flags());
488 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), 514 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
489 Code::cast(code), name)); 515 Code::cast(code), name));
490 Object* result = map->UpdateCodeCache(name, Code::cast(code)); 516 Object* result = map->UpdateCodeCache(name, Code::cast(code));
491 if (result->IsFailure()) return result; 517 if (result->IsFailure()) return result;
492 } 518 }
493 return code; 519 return code;
494 } 520 }
495 521
496 522
497 Object* StubCache::ComputeCallField(int argc, 523 Object* StubCache::ComputeCallField(int argc,
498 InLoopFlag in_loop, 524 InLoopFlag in_loop,
499 Code::Kind kind, 525 Code::Kind kind,
500 String* name, 526 String* name,
501 Object* object, 527 Object* object,
502 JSObject* holder, 528 JSObject* holder,
503 int index) { 529 int index) {
504 // Compute the check type and the map. 530 // Compute the check type and the map.
505 Map* map = IC::GetCodeCacheMapForObject(object); 531 InlineCacheHolderFlag cache_holder =
532 IC::GetCodeCacheForObject(object, holder);
533 Map* map = IC::GetCodeCacheMap(object, cache_holder);
506 534
507 // TODO(1233596): We cannot do receiver map check for non-JS objects 535 // TODO(1233596): We cannot do receiver map check for non-JS objects
508 // because they may be represented as immediates without a 536 // because they may be represented as immediates without a
509 // map. Instead, we check against the map in the holder. 537 // map. Instead, we check against the map in the holder.
510 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { 538 if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
511 object = holder; 539 object = holder;
512 } 540 }
513 541
514 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, 542 Code::Flags flags = Code::ComputeMonomorphicFlags(kind,
515 FIELD, 543 FIELD,
544 cache_holder,
516 in_loop, 545 in_loop,
517 argc); 546 argc);
518 Object* code = map->FindInCodeCache(name, flags); 547 Object* code = map->FindInCodeCache(name, flags);
519 if (code->IsUndefined()) { 548 if (code->IsUndefined()) {
520 CallStubCompiler compiler(argc, in_loop, kind); 549 CallStubCompiler compiler(argc, in_loop, kind, cache_holder);
521 code = compiler.CompileCallField(JSObject::cast(object), 550 code = compiler.CompileCallField(JSObject::cast(object),
522 holder, 551 holder,
523 index, 552 index,
524 name); 553 name);
525 if (code->IsFailure()) return code; 554 if (code->IsFailure()) return code;
526 ASSERT_EQ(flags, Code::cast(code)->flags()); 555 ASSERT_EQ(flags, Code::cast(code)->flags());
527 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), 556 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
528 Code::cast(code), name)); 557 Code::cast(code), name));
529 Object* result = map->UpdateCodeCache(name, Code::cast(code)); 558 Object* result = map->UpdateCodeCache(name, Code::cast(code));
530 if (result->IsFailure()) return result; 559 if (result->IsFailure()) return result;
531 } 560 }
532 return code; 561 return code;
533 } 562 }
534 563
535 564
536 Object* StubCache::ComputeCallInterceptor(int argc, 565 Object* StubCache::ComputeCallInterceptor(int argc,
537 Code::Kind kind, 566 Code::Kind kind,
538 String* name, 567 String* name,
539 Object* object, 568 Object* object,
540 JSObject* holder) { 569 JSObject* holder) {
541 // Compute the check type and the map. 570 // Compute the check type and the map.
542 // If the object is a value, we use the prototype map for the cache. 571 InlineCacheHolderFlag cache_holder =
543 Map* map = IC::GetCodeCacheMapForObject(object); 572 IC::GetCodeCacheForObject(object, holder);
573 Map* map = IC::GetCodeCacheMap(object, cache_holder);
544 574
545 // TODO(1233596): We cannot do receiver map check for non-JS objects 575 // TODO(1233596): We cannot do receiver map check for non-JS objects
546 // because they may be represented as immediates without a 576 // because they may be represented as immediates without a
547 // map. Instead, we check against the map in the holder. 577 // map. Instead, we check against the map in the holder.
548 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { 578 if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
549 object = holder; 579 object = holder;
550 } 580 }
551 581
552 Code::Flags flags = 582 Code::Flags flags =
553 Code::ComputeMonomorphicFlags(kind, 583 Code::ComputeMonomorphicFlags(kind,
554 INTERCEPTOR, 584 INTERCEPTOR,
585 cache_holder,
555 NOT_IN_LOOP, 586 NOT_IN_LOOP,
556 argc); 587 argc);
557 Object* code = map->FindInCodeCache(name, flags); 588 Object* code = map->FindInCodeCache(name, flags);
558 if (code->IsUndefined()) { 589 if (code->IsUndefined()) {
559 CallStubCompiler compiler(argc, NOT_IN_LOOP, kind); 590 CallStubCompiler compiler(argc, NOT_IN_LOOP, kind, cache_holder);
560 code = compiler.CompileCallInterceptor(JSObject::cast(object), 591 code = compiler.CompileCallInterceptor(JSObject::cast(object),
561 holder, 592 holder,
562 name); 593 name);
563 if (code->IsFailure()) return code; 594 if (code->IsFailure()) return code;
564 ASSERT_EQ(flags, Code::cast(code)->flags()); 595 ASSERT_EQ(flags, Code::cast(code)->flags());
565 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), 596 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
566 Code::cast(code), name)); 597 Code::cast(code), name));
567 Object* result = map->UpdateCodeCache(name, Code::cast(code)); 598 Object* result = map->UpdateCodeCache(name, Code::cast(code));
568 if (result->IsFailure()) return result; 599 if (result->IsFailure()) return result;
569 } 600 }
(...skipping 13 matching lines...) Expand all
583 614
584 615
585 Object* StubCache::ComputeCallGlobal(int argc, 616 Object* StubCache::ComputeCallGlobal(int argc,
586 InLoopFlag in_loop, 617 InLoopFlag in_loop,
587 Code::Kind kind, 618 Code::Kind kind,
588 String* name, 619 String* name,
589 JSObject* receiver, 620 JSObject* receiver,
590 GlobalObject* holder, 621 GlobalObject* holder,
591 JSGlobalPropertyCell* cell, 622 JSGlobalPropertyCell* cell,
592 JSFunction* function) { 623 JSFunction* function) {
624 InlineCacheHolderFlag cache_holder =
625 IC::GetCodeCacheForObject(receiver, holder);
626 Map* map = IC::GetCodeCacheMap(receiver, cache_holder);
593 Code::Flags flags = 627 Code::Flags flags =
594 Code::ComputeMonomorphicFlags(kind, 628 Code::ComputeMonomorphicFlags(kind,
595 NORMAL, 629 NORMAL,
630 cache_holder,
596 in_loop, 631 in_loop,
597 argc); 632 argc);
598 Object* code = receiver->map()->FindInCodeCache(name, flags); 633 Object* code = map->FindInCodeCache(name, flags);
599 if (code->IsUndefined()) { 634 if (code->IsUndefined()) {
600 // If the function hasn't been compiled yet, we cannot do it now 635 // If the function hasn't been compiled yet, we cannot do it now
601 // because it may cause GC. To avoid this issue, we return an 636 // because it may cause GC. To avoid this issue, we return an
602 // internal error which will make sure we do not update any 637 // internal error which will make sure we do not update any
603 // caches. 638 // caches.
604 if (!function->is_compiled()) return Failure::InternalError(); 639 if (!function->is_compiled()) return Failure::InternalError();
605 CallStubCompiler compiler(argc, in_loop, kind); 640 CallStubCompiler compiler(argc, in_loop, kind, cache_holder);
606 code = compiler.CompileCallGlobal(receiver, holder, cell, function, name); 641 code = compiler.CompileCallGlobal(receiver, holder, cell, function, name);
607 if (code->IsFailure()) return code; 642 if (code->IsFailure()) return code;
608 ASSERT_EQ(flags, Code::cast(code)->flags()); 643 ASSERT_EQ(flags, Code::cast(code)->flags());
609 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), 644 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
610 Code::cast(code), name)); 645 Code::cast(code), name));
611 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 646 Object* result = map->UpdateCodeCache(name, Code::cast(code));
612 if (result->IsFailure()) return result; 647 if (result->IsFailure()) return result;
613 } 648 }
614 return code; 649 return code;
615 } 650 }
616 651
617 652
618 static Object* GetProbeValue(Code::Flags flags) { 653 static Object* GetProbeValue(Code::Flags flags) {
619 // Use raw_unchecked... so we don't get assert failures during GC. 654 // Use raw_unchecked... so we don't get assert failures during GC.
620 NumberDictionary* dictionary = Heap::raw_unchecked_non_monomorphic_cache(); 655 NumberDictionary* dictionary = Heap::raw_unchecked_non_monomorphic_cache();
621 int entry = dictionary->FindEntry(flags); 656 int entry = dictionary->FindEntry(flags);
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 return GetCodeWithFlags(flags, name); 1236 return GetCodeWithFlags(flags, name);
1202 } 1237 }
1203 1238
1204 1239
1205 Object* KeyedStoreStubCompiler::GetCode(PropertyType type, String* name) { 1240 Object* KeyedStoreStubCompiler::GetCode(PropertyType type, String* name) {
1206 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, type); 1241 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, type);
1207 return GetCodeWithFlags(flags, name); 1242 return GetCodeWithFlags(flags, name);
1208 } 1243 }
1209 1244
1210 1245
1246 CallStubCompiler::CallStubCompiler(int argc,
1247 InLoopFlag in_loop,
1248 Code::Kind kind,
1249 InlineCacheHolderFlag cache_holder)
1250 : arguments_(argc)
1251 , in_loop_(in_loop)
1252 , kind_(kind)
1253 , cache_holder_(cache_holder) {
1254 }
1255
1256
1211 Object* CallStubCompiler::CompileCustomCall(int generator_id, 1257 Object* CallStubCompiler::CompileCustomCall(int generator_id,
1212 Object* object, 1258 Object* object,
1213 JSObject* holder, 1259 JSObject* holder,
1214 JSFunction* function, 1260 JSFunction* function,
1215 String* fname, 1261 String* fname,
1216 CheckType check) { 1262 CheckType check) {
1217 ASSERT(generator_id >= 0 && generator_id < kNumCallGenerators); 1263 ASSERT(generator_id >= 0 && generator_id < kNumCallGenerators);
1218 switch (generator_id) { 1264 switch (generator_id) {
1219 #define CALL_GENERATOR_CASE(ignored1, ignored2, name) \ 1265 #define CALL_GENERATOR_CASE(ignored1, ignored2, name) \
1220 case k##name##CallGenerator: \ 1266 case k##name##CallGenerator: \
1221 return CallStubCompiler::Compile##name##Call(object, \ 1267 return CallStubCompiler::Compile##name##Call(object, \
1222 holder, \ 1268 holder, \
1223 function, \ 1269 function, \
1224 fname, \ 1270 fname, \
1225 check); 1271 check);
1226 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) 1272 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE)
1227 #undef CALL_GENERATOR_CASE 1273 #undef CALL_GENERATOR_CASE
1228 } 1274 }
1229 UNREACHABLE(); 1275 UNREACHABLE();
1230 return Heap::undefined_value(); 1276 return Heap::undefined_value();
1231 } 1277 }
1232 1278
1233 1279
1234 Object* CallStubCompiler::GetCode(PropertyType type, String* name) { 1280 Object* CallStubCompiler::GetCode(PropertyType type, String* name) {
1235 int argc = arguments_.immediate(); 1281 int argc = arguments_.immediate();
1236 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, 1282 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_,
1237 type, 1283 type,
1284 cache_holder_,
1238 in_loop_, 1285 in_loop_,
1239 argc); 1286 argc);
1240 return GetCodeWithFlags(flags, name); 1287 return GetCodeWithFlags(flags, name);
1241 } 1288 }
1242 1289
1243 1290
1244 Object* CallStubCompiler::GetCode(JSFunction* function) { 1291 Object* CallStubCompiler::GetCode(JSFunction* function) {
1245 String* function_name = NULL; 1292 String* function_name = NULL;
1246 if (function->shared()->name()->IsString()) { 1293 if (function->shared()->name()->IsString()) {
1247 function_name = String::cast(function->shared()->name()); 1294 function_name = String::cast(function->shared()->name());
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1323 expected_receiver_type_ = 1370 expected_receiver_type_ =
1324 FunctionTemplateInfo::cast(signature->receiver()); 1371 FunctionTemplateInfo::cast(signature->receiver());
1325 } 1372 }
1326 } 1373 }
1327 1374
1328 is_simple_api_call_ = true; 1375 is_simple_api_call_ = true;
1329 } 1376 }
1330 1377
1331 1378
1332 } } // namespace v8::internal 1379 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | src/v8-counters.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698