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

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

Issue 3970005: Make Failure inherit from MaybeObject instead of Object. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 1 month 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/top.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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 *secondary = *primary; 86 *secondary = *primary;
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 MaybeObject* StubCache::ComputeLoadNonexistent(String* name,
97 JSObject* receiver) {
97 ASSERT(receiver->IsGlobalObject() || receiver->HasFastProperties()); 98 ASSERT(receiver->IsGlobalObject() || receiver->HasFastProperties());
98 // If no global objects are present in the prototype chain, the load 99 // If no global objects are present in the prototype chain, the load
99 // nonexistent IC stub can be shared for all names for a given map 100 // nonexistent IC stub can be shared for all names for a given map
100 // and we use the empty string for the map cache in that case. If 101 // and we use the empty string for the map cache in that case. If
101 // there are global objects involved, we need to check global 102 // there are global objects involved, we need to check global
102 // property cells in the stub and therefore the stub will be 103 // property cells in the stub and therefore the stub will be
103 // specific to the name. 104 // specific to the name.
104 String* cache_name = Heap::empty_string(); 105 String* cache_name = Heap::empty_string();
105 if (receiver->IsGlobalObject()) cache_name = name; 106 if (receiver->IsGlobalObject()) cache_name = name;
106 JSObject* last = receiver; 107 JSObject* last = receiver;
107 while (last->GetPrototype() != Heap::null_value()) { 108 while (last->GetPrototype() != Heap::null_value()) {
108 last = JSObject::cast(last->GetPrototype()); 109 last = JSObject::cast(last->GetPrototype());
109 if (last->IsGlobalObject()) cache_name = name; 110 if (last->IsGlobalObject()) cache_name = name;
110 } 111 }
111 // Compile the stub that is either shared for all names or 112 // Compile the stub that is either shared for all names or
112 // name specific if there are global objects involved. 113 // name specific if there are global objects involved.
113 Code::Flags flags = 114 Code::Flags flags =
114 Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT); 115 Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT);
115 Object* code = receiver->map()->FindInCodeCache(cache_name, flags); 116 Object* code = receiver->map()->FindInCodeCache(cache_name, flags);
116 if (code->IsUndefined()) { 117 if (code->IsUndefined()) {
117 LoadStubCompiler compiler; 118 LoadStubCompiler compiler;
118 code = compiler.CompileLoadNonexistent(cache_name, receiver, last); 119 { MaybeObject* maybe_code =
119 if (code->IsFailure()) return code; 120 compiler.CompileLoadNonexistent(cache_name, receiver, last);
121 if (!maybe_code->ToObject(&code)) return maybe_code;
122 }
120 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), cache_name)); 123 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), cache_name));
121 Object* result = 124 Object* result;
122 receiver->UpdateMapCodeCache(cache_name, Code::cast(code)); 125 { MaybeObject* maybe_result =
123 if (result->IsFailure()) return result; 126 receiver->UpdateMapCodeCache(cache_name, Code::cast(code));
124 } 127 if (!maybe_result->ToObject(&result)) return maybe_result;
125 return code; 128 }
126 } 129 }
127 130 return code;
128 131 }
129 Object* StubCache::ComputeLoadField(String* name, 132
130 JSObject* receiver, 133
131 JSObject* holder, 134 MaybeObject* StubCache::ComputeLoadField(String* name,
132 int field_index) {
133 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
134 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD);
135 Object* code = receiver->map()->FindInCodeCache(name, flags);
136 if (code->IsUndefined()) {
137 LoadStubCompiler compiler;
138 code = compiler.CompileLoadField(receiver, holder, field_index, name);
139 if (code->IsFailure()) return code;
140 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
141 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code));
142 if (result->IsFailure()) return result;
143 }
144 return code;
145 }
146
147
148 Object* StubCache::ComputeLoadCallback(String* name,
149 JSObject* receiver,
150 JSObject* holder,
151 AccessorInfo* callback) {
152 ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
153 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
154 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS);
155 Object* code = receiver->map()->FindInCodeCache(name, flags);
156 if (code->IsUndefined()) {
157 LoadStubCompiler compiler;
158 code = compiler.CompileLoadCallback(name, receiver, holder, callback);
159 if (code->IsFailure()) return code;
160 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
161 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code));
162 if (result->IsFailure()) return result;
163 }
164 return code;
165 }
166
167
168 Object* StubCache::ComputeLoadConstant(String* name,
169 JSObject* receiver,
170 JSObject* holder,
171 Object* value) {
172 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
173 Code::Flags flags =
174 Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION);
175 Object* code = receiver->map()->FindInCodeCache(name, flags);
176 if (code->IsUndefined()) {
177 LoadStubCompiler compiler;
178 code = compiler.CompileLoadConstant(receiver, holder, value, name);
179 if (code->IsFailure()) return code;
180 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
181 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code));
182 if (result->IsFailure()) return result;
183 }
184 return code;
185 }
186
187
188 Object* StubCache::ComputeLoadInterceptor(String* name,
189 JSObject* receiver,
190 JSObject* holder) {
191 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
192 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR);
193 Object* code = receiver->map()->FindInCodeCache(name, flags);
194 if (code->IsUndefined()) {
195 LoadStubCompiler compiler;
196 code = compiler.CompileLoadInterceptor(receiver, holder, name);
197 if (code->IsFailure()) return code;
198 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
199 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code));
200 if (result->IsFailure()) return result;
201 }
202 return code;
203 }
204
205
206 Object* StubCache::ComputeLoadNormal() {
207 return Builtins::builtin(Builtins::LoadIC_Normal);
208 }
209
210
211 Object* StubCache::ComputeLoadGlobal(String* name,
212 JSObject* receiver,
213 GlobalObject* holder,
214 JSGlobalPropertyCell* cell,
215 bool is_dont_delete) {
216 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
217 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
218 Object* code = receiver->map()->FindInCodeCache(name, flags);
219 if (code->IsUndefined()) {
220 LoadStubCompiler compiler;
221 code = compiler.CompileLoadGlobal(receiver,
222 holder,
223 cell,
224 name,
225 is_dont_delete);
226 if (code->IsFailure()) return code;
227 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
228 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code));
229 if (result->IsFailure()) return result;
230 }
231 return code;
232 }
233
234
235 Object* StubCache::ComputeKeyedLoadField(String* name,
236 JSObject* receiver, 135 JSObject* receiver,
237 JSObject* holder, 136 JSObject* holder,
238 int field_index) { 137 int field_index) {
239 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); 138 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
240 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD); 139 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD);
241 Object* code = receiver->map()->FindInCodeCache(name, flags); 140 Object* code = receiver->map()->FindInCodeCache(name, flags);
242 if (code->IsUndefined()) { 141 if (code->IsUndefined()) {
243 KeyedLoadStubCompiler compiler; 142 LoadStubCompiler compiler;
244 code = compiler.CompileLoadField(name, receiver, holder, field_index); 143 { MaybeObject* maybe_code =
245 if (code->IsFailure()) return code; 144 compiler.CompileLoadField(receiver, holder, field_index, name);
246 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); 145 if (!maybe_code->ToObject(&code)) return maybe_code;
247 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); 146 }
248 if (result->IsFailure()) return result; 147 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
249 } 148 Object* result;
250 return code; 149 { MaybeObject* maybe_result =
251 } 150 receiver->UpdateMapCodeCache(name, Code::cast(code));
252 151 if (!maybe_result->ToObject(&result)) return maybe_result;
253 152 }
254 Object* StubCache::ComputeKeyedLoadConstant(String* name, 153 }
154 return code;
155 }
156
157
158 MaybeObject* StubCache::ComputeLoadCallback(String* name,
159 JSObject* receiver,
160 JSObject* holder,
161 AccessorInfo* callback) {
162 ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
163 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
164 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS);
165 Object* code = receiver->map()->FindInCodeCache(name, flags);
166 if (code->IsUndefined()) {
167 LoadStubCompiler compiler;
168 { MaybeObject* maybe_code =
169 compiler.CompileLoadCallback(name, receiver, holder, callback);
170 if (!maybe_code->ToObject(&code)) return maybe_code;
171 }
172 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
173 Object* result;
174 { MaybeObject* maybe_result =
175 receiver->UpdateMapCodeCache(name, Code::cast(code));
176 if (!maybe_result->ToObject(&result)) return maybe_result;
177 }
178 }
179 return code;
180 }
181
182
183 MaybeObject* StubCache::ComputeLoadConstant(String* name,
255 JSObject* receiver, 184 JSObject* receiver,
256 JSObject* holder, 185 JSObject* holder,
257 Object* value) { 186 Object* value) {
258 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); 187 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
259 Code::Flags flags = 188 Code::Flags flags =
260 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION); 189 Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION);
261 Object* code = receiver->map()->FindInCodeCache(name, flags); 190 Object* code = receiver->map()->FindInCodeCache(name, flags);
262 if (code->IsUndefined()) { 191 if (code->IsUndefined()) {
263 KeyedLoadStubCompiler compiler; 192 LoadStubCompiler compiler;
264 code = compiler.CompileLoadConstant(name, receiver, holder, value); 193 { MaybeObject* maybe_code =
265 if (code->IsFailure()) return code; 194 compiler.CompileLoadConstant(receiver, holder, value, name);
266 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); 195 if (!maybe_code->ToObject(&code)) return maybe_code;
267 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); 196 }
268 if (result->IsFailure()) return result; 197 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
269 } 198 Object* result;
270 return code; 199 { MaybeObject* maybe_result =
271 } 200 receiver->UpdateMapCodeCache(name, Code::cast(code));
272 201 if (!maybe_result->ToObject(&result)) return maybe_result;
273 202 }
274 Object* StubCache::ComputeKeyedLoadInterceptor(String* name, 203 }
204 return code;
205 }
206
207
208 MaybeObject* StubCache::ComputeLoadInterceptor(String* name,
275 JSObject* receiver, 209 JSObject* receiver,
276 JSObject* holder) { 210 JSObject* holder) {
277 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); 211 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
212 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR);
213 Object* code = receiver->map()->FindInCodeCache(name, flags);
214 if (code->IsUndefined()) {
215 LoadStubCompiler compiler;
216 { MaybeObject* maybe_code =
217 compiler.CompileLoadInterceptor(receiver, holder, name);
218 if (!maybe_code->ToObject(&code)) return maybe_code;
219 }
220 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
221 Object* result;
222 { MaybeObject* maybe_result =
223 receiver->UpdateMapCodeCache(name, Code::cast(code));
224 if (!maybe_result->ToObject(&result)) return maybe_result;
225 }
226 }
227 return code;
228 }
229
230
231 MaybeObject* StubCache::ComputeLoadNormal() {
232 return Builtins::builtin(Builtins::LoadIC_Normal);
233 }
234
235
236 MaybeObject* StubCache::ComputeLoadGlobal(String* name,
237 JSObject* receiver,
238 GlobalObject* holder,
239 JSGlobalPropertyCell* cell,
240 bool is_dont_delete) {
241 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
242 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
243 Object* code = receiver->map()->FindInCodeCache(name, flags);
244 if (code->IsUndefined()) {
245 LoadStubCompiler compiler;
246 { MaybeObject* maybe_code = compiler.CompileLoadGlobal(receiver,
247 holder,
248 cell,
249 name,
250 is_dont_delete);
251 if (!maybe_code->ToObject(&code)) return maybe_code;
252 }
253 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
254 Object* result;
255 { MaybeObject* maybe_result =
256 receiver->UpdateMapCodeCache(name, Code::cast(code));
257 if (!maybe_result->ToObject(&result)) return maybe_result;
258 }
259 }
260 return code;
261 }
262
263
264 MaybeObject* StubCache::ComputeKeyedLoadField(String* name,
265 JSObject* receiver,
266 JSObject* holder,
267 int field_index) {
268 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
269 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD);
270 Object* code = receiver->map()->FindInCodeCache(name, flags);
271 if (code->IsUndefined()) {
272 KeyedLoadStubCompiler compiler;
273 { MaybeObject* maybe_code =
274 compiler.CompileLoadField(name, receiver, holder, field_index);
275 if (!maybe_code->ToObject(&code)) return maybe_code;
276 }
277 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
278 Object* result;
279 { MaybeObject* maybe_result =
280 receiver->UpdateMapCodeCache(name, Code::cast(code));
281 if (!maybe_result->ToObject(&result)) return maybe_result;
282 }
283 }
284 return code;
285 }
286
287
288 MaybeObject* StubCache::ComputeKeyedLoadConstant(String* name,
289 JSObject* receiver,
290 JSObject* holder,
291 Object* value) {
292 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
293 Code::Flags flags =
294 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION);
295 Object* code = receiver->map()->FindInCodeCache(name, flags);
296 if (code->IsUndefined()) {
297 KeyedLoadStubCompiler compiler;
298 { MaybeObject* maybe_code =
299 compiler.CompileLoadConstant(name, receiver, holder, value);
300 if (!maybe_code->ToObject(&code)) return maybe_code;
301 }
302 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
303 Object* result;
304 { MaybeObject* maybe_result =
305 receiver->UpdateMapCodeCache(name, Code::cast(code));
306 if (!maybe_result->ToObject(&result)) return maybe_result;
307 }
308 }
309 return code;
310 }
311
312
313 MaybeObject* StubCache::ComputeKeyedLoadInterceptor(String* name,
314 JSObject* receiver,
315 JSObject* holder) {
316 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
278 Code::Flags flags = 317 Code::Flags flags =
279 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR); 318 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR);
280 Object* code = receiver->map()->FindInCodeCache(name, flags); 319 Object* code = receiver->map()->FindInCodeCache(name, flags);
281 if (code->IsUndefined()) { 320 if (code->IsUndefined()) {
282 KeyedLoadStubCompiler compiler; 321 KeyedLoadStubCompiler compiler;
283 code = compiler.CompileLoadInterceptor(receiver, holder, name); 322 { MaybeObject* maybe_code =
284 if (code->IsFailure()) return code; 323 compiler.CompileLoadInterceptor(receiver, holder, name);
285 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); 324 if (!maybe_code->ToObject(&code)) return maybe_code;
286 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); 325 }
287 if (result->IsFailure()) return result; 326 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
288 } 327 Object* result;
289 return code; 328 { MaybeObject* maybe_result =
290 } 329 receiver->UpdateMapCodeCache(name, Code::cast(code));
291 330 if (!maybe_result->ToObject(&result)) return maybe_result;
292 331 }
293 Object* StubCache::ComputeKeyedLoadCallback(String* name, 332 }
294 JSObject* receiver, 333 return code;
295 JSObject* holder, 334 }
296 AccessorInfo* callback) { 335
336
337 MaybeObject* StubCache::ComputeKeyedLoadCallback(String* name,
338 JSObject* receiver,
339 JSObject* holder,
340 AccessorInfo* callback) {
297 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); 341 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
298 Code::Flags flags = 342 Code::Flags flags =
299 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); 343 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
300 Object* code = receiver->map()->FindInCodeCache(name, flags); 344 Object* code = receiver->map()->FindInCodeCache(name, flags);
301 if (code->IsUndefined()) { 345 if (code->IsUndefined()) {
302 KeyedLoadStubCompiler compiler; 346 KeyedLoadStubCompiler compiler;
303 code = compiler.CompileLoadCallback(name, receiver, holder, callback); 347 { MaybeObject* maybe_code =
304 if (code->IsFailure()) return code; 348 compiler.CompileLoadCallback(name, receiver, holder, callback);
305 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); 349 if (!maybe_code->ToObject(&code)) return maybe_code;
306 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); 350 }
307 if (result->IsFailure()) return result; 351 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
308 } 352 Object* result;
309 return code; 353 { MaybeObject* maybe_result =
310 } 354 receiver->UpdateMapCodeCache(name, Code::cast(code));
311 355 if (!maybe_result->ToObject(&result)) return maybe_result;
312 356 }
313 357 }
314 Object* StubCache::ComputeKeyedLoadArrayLength(String* name, 358 return code;
315 JSArray* receiver) { 359 }
360
361
362
363 MaybeObject* StubCache::ComputeKeyedLoadArrayLength(String* name,
364 JSArray* receiver) {
316 Code::Flags flags = 365 Code::Flags flags =
317 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); 366 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
318 ASSERT(receiver->IsJSObject()); 367 ASSERT(receiver->IsJSObject());
319 Object* code = receiver->map()->FindInCodeCache(name, flags); 368 Object* code = receiver->map()->FindInCodeCache(name, flags);
320 if (code->IsUndefined()) { 369 if (code->IsUndefined()) {
321 KeyedLoadStubCompiler compiler; 370 KeyedLoadStubCompiler compiler;
322 code = compiler.CompileLoadArrayLength(name); 371 { MaybeObject* maybe_code = compiler.CompileLoadArrayLength(name);
323 if (code->IsFailure()) return code; 372 if (!maybe_code->ToObject(&code)) return maybe_code;
324 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); 373 }
325 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); 374 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
326 if (result->IsFailure()) return result; 375 Object* result;
327 } 376 { MaybeObject* maybe_result =
328 return code; 377 receiver->UpdateMapCodeCache(name, Code::cast(code));
329 } 378 if (!maybe_result->ToObject(&result)) return maybe_result;
330 379 }
331 380 }
332 Object* StubCache::ComputeKeyedLoadStringLength(String* name, 381 return code;
333 String* receiver) { 382 }
383
384
385 MaybeObject* StubCache::ComputeKeyedLoadStringLength(String* name,
386 String* receiver) {
334 Code::Flags flags = 387 Code::Flags flags =
335 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); 388 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
336 Map* map = receiver->map(); 389 Map* map = receiver->map();
337 Object* code = map->FindInCodeCache(name, flags); 390 Object* code = map->FindInCodeCache(name, flags);
338 if (code->IsUndefined()) { 391 if (code->IsUndefined()) {
339 KeyedLoadStubCompiler compiler; 392 KeyedLoadStubCompiler compiler;
340 code = compiler.CompileLoadStringLength(name); 393 { MaybeObject* maybe_code = compiler.CompileLoadStringLength(name);
341 if (code->IsFailure()) return code; 394 if (!maybe_code->ToObject(&code)) return maybe_code;
342 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); 395 }
343 Object* result = map->UpdateCodeCache(name, Code::cast(code)); 396 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
344 if (result->IsFailure()) return result; 397 Object* result;
345 } 398 { MaybeObject* maybe_result = map->UpdateCodeCache(name, Code::cast(code));
346 return code; 399 if (!maybe_result->ToObject(&result)) return maybe_result;
347 } 400 }
348 401 }
349 402 return code;
350 Object* StubCache::ComputeKeyedLoadFunctionPrototype(String* name, 403 }
351 JSFunction* receiver) { 404
405
406 MaybeObject* StubCache::ComputeKeyedLoadFunctionPrototype(
407 String* name,
408 JSFunction* receiver) {
352 Code::Flags flags = 409 Code::Flags flags =
353 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); 410 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
354 Object* code = receiver->map()->FindInCodeCache(name, flags); 411 Object* code = receiver->map()->FindInCodeCache(name, flags);
355 if (code->IsUndefined()) { 412 if (code->IsUndefined()) {
356 KeyedLoadStubCompiler compiler; 413 KeyedLoadStubCompiler compiler;
357 code = compiler.CompileLoadFunctionPrototype(name); 414 { MaybeObject* maybe_code = compiler.CompileLoadFunctionPrototype(name);
358 if (code->IsFailure()) return code; 415 if (!maybe_code->ToObject(&code)) return maybe_code;
359 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); 416 }
360 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); 417 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
361 if (result->IsFailure()) return result; 418 Object* result;
362 } 419 { MaybeObject* maybe_result =
363 return code; 420 receiver->UpdateMapCodeCache(name, Code::cast(code));
364 } 421 if (!maybe_result->ToObject(&result)) return maybe_result;
365 422 }
366 423 }
367 Object* StubCache::ComputeStoreField(String* name, 424 return code;
368 JSObject* receiver, 425 }
369 int field_index, 426
370 Map* transition) { 427
428 MaybeObject* StubCache::ComputeStoreField(String* name,
429 JSObject* receiver,
430 int field_index,
431 Map* transition) {
371 PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION; 432 PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION;
372 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, type); 433 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, type);
373 Object* code = receiver->map()->FindInCodeCache(name, flags); 434 Object* code = receiver->map()->FindInCodeCache(name, flags);
374 if (code->IsUndefined()) { 435 if (code->IsUndefined()) {
375 StoreStubCompiler compiler; 436 StoreStubCompiler compiler;
376 code = compiler.CompileStoreField(receiver, field_index, transition, name); 437 { MaybeObject* maybe_code =
377 if (code->IsFailure()) return code; 438 compiler.CompileStoreField(receiver, field_index, transition, name);
439 if (!maybe_code->ToObject(&code)) return maybe_code;
440 }
378 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); 441 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
379 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); 442 Object* result;
380 if (result->IsFailure()) return result; 443 { MaybeObject* maybe_result =
381 } 444 receiver->UpdateMapCodeCache(name, Code::cast(code));
382 return code; 445 if (!maybe_result->ToObject(&result)) return maybe_result;
383 } 446 }
384 447 }
385 448 return code;
386 Object* StubCache::ComputeStoreNormal() { 449 }
450
451
452 MaybeObject* StubCache::ComputeStoreNormal() {
387 return Builtins::builtin(Builtins::StoreIC_Normal); 453 return Builtins::builtin(Builtins::StoreIC_Normal);
388 } 454 }
389 455
390 456
391 Object* StubCache::ComputeStoreGlobal(String* name, 457 MaybeObject* StubCache::ComputeStoreGlobal(String* name,
392 GlobalObject* receiver, 458 GlobalObject* receiver,
393 JSGlobalPropertyCell* cell) { 459 JSGlobalPropertyCell* cell) {
394 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL); 460 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL);
395 Object* code = receiver->map()->FindInCodeCache(name, flags); 461 Object* code = receiver->map()->FindInCodeCache(name, flags);
396 if (code->IsUndefined()) { 462 if (code->IsUndefined()) {
397 StoreStubCompiler compiler; 463 StoreStubCompiler compiler;
398 code = compiler.CompileStoreGlobal(receiver, cell, name); 464 { MaybeObject* maybe_code =
399 if (code->IsFailure()) return code; 465 compiler.CompileStoreGlobal(receiver, cell, name);
466 if (!maybe_code->ToObject(&code)) return maybe_code;
467 }
400 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); 468 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
401 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); 469 Object* result;
402 if (result->IsFailure()) return result; 470 { MaybeObject* maybe_result =
403 } 471 receiver->UpdateMapCodeCache(name, Code::cast(code));
404 return code; 472 if (!maybe_result->ToObject(&result)) return maybe_result;
405 } 473 }
406 474 }
407 475 return code;
408 Object* StubCache::ComputeStoreCallback(String* name, 476 }
409 JSObject* receiver, 477
410 AccessorInfo* callback) { 478
479 MaybeObject* StubCache::ComputeStoreCallback(String* name,
480 JSObject* receiver,
481 AccessorInfo* callback) {
411 ASSERT(v8::ToCData<Address>(callback->setter()) != 0); 482 ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
412 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, CALLBACKS); 483 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, CALLBACKS);
413 Object* code = receiver->map()->FindInCodeCache(name, flags); 484 Object* code = receiver->map()->FindInCodeCache(name, flags);
414 if (code->IsUndefined()) { 485 if (code->IsUndefined()) {
415 StoreStubCompiler compiler; 486 StoreStubCompiler compiler;
416 code = compiler.CompileStoreCallback(receiver, callback, name); 487 { MaybeObject* maybe_code =
417 if (code->IsFailure()) return code; 488 compiler.CompileStoreCallback(receiver, callback, name);
489 if (!maybe_code->ToObject(&code)) return maybe_code;
490 }
418 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); 491 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
419 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); 492 Object* result;
420 if (result->IsFailure()) return result; 493 { MaybeObject* maybe_result =
421 } 494 receiver->UpdateMapCodeCache(name, Code::cast(code));
422 return code; 495 if (!maybe_result->ToObject(&result)) return maybe_result;
423 } 496 }
424 497 }
425 498 return code;
426 Object* StubCache::ComputeStoreInterceptor(String* name, 499 }
427 JSObject* receiver) { 500
501
502 MaybeObject* StubCache::ComputeStoreInterceptor(String* name,
503 JSObject* receiver) {
428 Code::Flags flags = 504 Code::Flags flags =
429 Code::ComputeMonomorphicFlags(Code::STORE_IC, INTERCEPTOR); 505 Code::ComputeMonomorphicFlags(Code::STORE_IC, INTERCEPTOR);
430 Object* code = receiver->map()->FindInCodeCache(name, flags); 506 Object* code = receiver->map()->FindInCodeCache(name, flags);
431 if (code->IsUndefined()) { 507 if (code->IsUndefined()) {
432 StoreStubCompiler compiler; 508 StoreStubCompiler compiler;
433 code = compiler.CompileStoreInterceptor(receiver, name); 509 { MaybeObject* maybe_code =
434 if (code->IsFailure()) return code; 510 compiler.CompileStoreInterceptor(receiver, name);
511 if (!maybe_code->ToObject(&code)) return maybe_code;
512 }
435 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); 513 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
436 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); 514 Object* result;
437 if (result->IsFailure()) return result; 515 { MaybeObject* maybe_result =
438 } 516 receiver->UpdateMapCodeCache(name, Code::cast(code));
439 return code; 517 if (!maybe_result->ToObject(&result)) return maybe_result;
440 } 518 }
441 519 }
442 520 return code;
443 Object* StubCache::ComputeKeyedStoreField(String* name, JSObject* receiver, 521 }
444 int field_index, Map* transition) { 522
523
524 MaybeObject* StubCache::ComputeKeyedStoreField(String* name,
525 JSObject* receiver,
526 int field_index,
527 Map* transition) {
445 PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION; 528 PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION;
446 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, type); 529 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, type);
447 Object* code = receiver->map()->FindInCodeCache(name, flags); 530 Object* code = receiver->map()->FindInCodeCache(name, flags);
448 if (code->IsUndefined()) { 531 if (code->IsUndefined()) {
449 KeyedStoreStubCompiler compiler; 532 KeyedStoreStubCompiler compiler;
450 code = compiler.CompileStoreField(receiver, field_index, transition, name); 533 { MaybeObject* maybe_code =
451 if (code->IsFailure()) return code; 534 compiler.CompileStoreField(receiver, field_index, transition, name);
535 if (!maybe_code->ToObject(&code)) return maybe_code;
536 }
452 PROFILE(CodeCreateEvent( 537 PROFILE(CodeCreateEvent(
453 Logger::KEYED_STORE_IC_TAG, Code::cast(code), name)); 538 Logger::KEYED_STORE_IC_TAG, Code::cast(code), name));
454 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); 539 Object* result;
455 if (result->IsFailure()) return result; 540 { MaybeObject* maybe_result =
456 } 541 receiver->UpdateMapCodeCache(name, Code::cast(code));
457 return code; 542 if (!maybe_result->ToObject(&result)) return maybe_result;
458 } 543 }
544 }
545 return code;
546 }
459 547
460 #define CALL_LOGGER_TAG(kind, type) \ 548 #define CALL_LOGGER_TAG(kind, type) \
461 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) 549 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
462 550
463 Object* StubCache::ComputeCallConstant(int argc, 551 MaybeObject* StubCache::ComputeCallConstant(int argc,
464 InLoopFlag in_loop, 552 InLoopFlag in_loop,
465 Code::Kind kind, 553 Code::Kind kind,
466 String* name, 554 String* name,
467 Object* object, 555 Object* object,
468 JSObject* holder, 556 JSObject* holder,
469 JSFunction* function) { 557 JSFunction* function) {
470 // Compute the check type and the map. 558 // Compute the check type and the map.
471 InlineCacheHolderFlag cache_holder = 559 InlineCacheHolderFlag cache_holder =
472 IC::GetCodeCacheForObject(object, holder); 560 IC::GetCodeCacheForObject(object, holder);
473 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); 561 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder);
474 562
475 // Compute check type based on receiver/holder. 563 // Compute check type based on receiver/holder.
476 StubCompiler::CheckType check = StubCompiler::RECEIVER_MAP_CHECK; 564 StubCompiler::CheckType check = StubCompiler::RECEIVER_MAP_CHECK;
477 if (object->IsString()) { 565 if (object->IsString()) {
478 check = StubCompiler::STRING_CHECK; 566 check = StubCompiler::STRING_CHECK;
479 } else if (object->IsNumber()) { 567 } else if (object->IsNumber()) {
(...skipping 10 matching lines...) Expand all
490 argc); 578 argc);
491 Object* code = map_holder->map()->FindInCodeCache(name, flags); 579 Object* code = map_holder->map()->FindInCodeCache(name, flags);
492 if (code->IsUndefined()) { 580 if (code->IsUndefined()) {
493 // If the function hasn't been compiled yet, we cannot do it now 581 // If the function hasn't been compiled yet, we cannot do it now
494 // because it may cause GC. To avoid this issue, we return an 582 // because it may cause GC. To avoid this issue, we return an
495 // internal error which will make sure we do not update any 583 // internal error which will make sure we do not update any
496 // caches. 584 // caches.
497 if (!function->is_compiled()) return Failure::InternalError(); 585 if (!function->is_compiled()) return Failure::InternalError();
498 // Compile the stub - only create stubs for fully compiled functions. 586 // Compile the stub - only create stubs for fully compiled functions.
499 CallStubCompiler compiler(argc, in_loop, kind, cache_holder); 587 CallStubCompiler compiler(argc, in_loop, kind, cache_holder);
500 code = compiler.CompileCallConstant(object, holder, function, name, check); 588 { MaybeObject* maybe_code =
501 if (code->IsFailure()) return code; 589 compiler.CompileCallConstant(object, holder, function, name, check);
590 if (!maybe_code->ToObject(&code)) return maybe_code;
591 }
502 ASSERT_EQ(flags, Code::cast(code)->flags()); 592 ASSERT_EQ(flags, Code::cast(code)->flags());
503 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), 593 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
504 Code::cast(code), name)); 594 Code::cast(code), name));
505 Object* result = map_holder->UpdateMapCodeCache(name, Code::cast(code)); 595 Object* result;
506 if (result->IsFailure()) return result; 596 { MaybeObject* maybe_result =
597 map_holder->UpdateMapCodeCache(name, Code::cast(code));
598 if (!maybe_result->ToObject(&result)) return maybe_result;
599 }
507 } 600 }
508 return code; 601 return code;
509 } 602 }
510 603
511 604
512 Object* StubCache::ComputeCallField(int argc, 605 MaybeObject* StubCache::ComputeCallField(int argc,
513 InLoopFlag in_loop, 606 InLoopFlag in_loop,
514 Code::Kind kind, 607 Code::Kind kind,
515 String* name, 608 String* name,
516 Object* object, 609 Object* object,
517 JSObject* holder, 610 JSObject* holder,
518 int index) { 611 int index) {
519 // Compute the check type and the map. 612 // Compute the check type and the map.
520 InlineCacheHolderFlag cache_holder = 613 InlineCacheHolderFlag cache_holder =
521 IC::GetCodeCacheForObject(object, holder); 614 IC::GetCodeCacheForObject(object, holder);
522 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); 615 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder);
523 616
524 // TODO(1233596): We cannot do receiver map check for non-JS objects 617 // TODO(1233596): We cannot do receiver map check for non-JS objects
525 // because they may be represented as immediates without a 618 // because they may be represented as immediates without a
526 // map. Instead, we check against the map in the holder. 619 // map. Instead, we check against the map in the holder.
527 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { 620 if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
528 object = holder; 621 object = holder;
529 } 622 }
530 623
531 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, 624 Code::Flags flags = Code::ComputeMonomorphicFlags(kind,
532 FIELD, 625 FIELD,
533 cache_holder, 626 cache_holder,
534 in_loop, 627 in_loop,
535 argc); 628 argc);
536 Object* code = map_holder->map()->FindInCodeCache(name, flags); 629 Object* code = map_holder->map()->FindInCodeCache(name, flags);
537 if (code->IsUndefined()) { 630 if (code->IsUndefined()) {
538 CallStubCompiler compiler(argc, in_loop, kind, cache_holder); 631 CallStubCompiler compiler(argc, in_loop, kind, cache_holder);
539 code = compiler.CompileCallField(JSObject::cast(object), 632 { MaybeObject* maybe_code =
540 holder, 633 compiler.CompileCallField(JSObject::cast(object),
541 index, 634 holder,
542 name); 635 index,
543 if (code->IsFailure()) return code; 636 name);
637 if (!maybe_code->ToObject(&code)) return maybe_code;
638 }
544 ASSERT_EQ(flags, Code::cast(code)->flags()); 639 ASSERT_EQ(flags, Code::cast(code)->flags());
545 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), 640 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
546 Code::cast(code), name)); 641 Code::cast(code), name));
547 Object* result = map_holder->UpdateMapCodeCache(name, Code::cast(code)); 642 Object* result;
548 if (result->IsFailure()) return result; 643 { MaybeObject* maybe_result =
644 map_holder->UpdateMapCodeCache(name, Code::cast(code));
645 if (!maybe_result->ToObject(&result)) return maybe_result;
646 }
549 } 647 }
550 return code; 648 return code;
551 } 649 }
552 650
553 651
554 Object* StubCache::ComputeCallInterceptor(int argc, 652 MaybeObject* StubCache::ComputeCallInterceptor(int argc,
555 Code::Kind kind, 653 Code::Kind kind,
556 String* name, 654 String* name,
557 Object* object, 655 Object* object,
558 JSObject* holder) { 656 JSObject* holder) {
559 // Compute the check type and the map. 657 // Compute the check type and the map.
560 InlineCacheHolderFlag cache_holder = 658 InlineCacheHolderFlag cache_holder =
561 IC::GetCodeCacheForObject(object, holder); 659 IC::GetCodeCacheForObject(object, holder);
562 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); 660 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder);
563 661
564 // TODO(1233596): We cannot do receiver map check for non-JS objects 662 // TODO(1233596): We cannot do receiver map check for non-JS objects
565 // because they may be represented as immediates without a 663 // because they may be represented as immediates without a
566 // map. Instead, we check against the map in the holder. 664 // map. Instead, we check against the map in the holder.
567 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { 665 if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
568 object = holder; 666 object = holder;
569 } 667 }
570 668
571 Code::Flags flags = 669 Code::Flags flags =
572 Code::ComputeMonomorphicFlags(kind, 670 Code::ComputeMonomorphicFlags(kind,
573 INTERCEPTOR, 671 INTERCEPTOR,
574 cache_holder, 672 cache_holder,
575 NOT_IN_LOOP, 673 NOT_IN_LOOP,
576 argc); 674 argc);
577 Object* code = map_holder->map()->FindInCodeCache(name, flags); 675 Object* code = map_holder->map()->FindInCodeCache(name, flags);
578 if (code->IsUndefined()) { 676 if (code->IsUndefined()) {
579 CallStubCompiler compiler(argc, NOT_IN_LOOP, kind, cache_holder); 677 CallStubCompiler compiler(argc, NOT_IN_LOOP, kind, cache_holder);
580 code = compiler.CompileCallInterceptor(JSObject::cast(object), 678 { MaybeObject* maybe_code =
581 holder, 679 compiler.CompileCallInterceptor(JSObject::cast(object), holder, name);
582 name); 680 if (!maybe_code->ToObject(&code)) return maybe_code;
583 if (code->IsFailure()) return code; 681 }
584 ASSERT_EQ(flags, Code::cast(code)->flags()); 682 ASSERT_EQ(flags, Code::cast(code)->flags());
585 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), 683 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
586 Code::cast(code), name)); 684 Code::cast(code), name));
587 Object* result = map_holder->UpdateMapCodeCache(name, Code::cast(code)); 685 Object* result;
588 if (result->IsFailure()) return result; 686 { MaybeObject* maybe_result =
687 map_holder->UpdateMapCodeCache(name, Code::cast(code));
688 if (!maybe_result->ToObject(&result)) return maybe_result;
689 }
589 } 690 }
590 return code; 691 return code;
591 } 692 }
592 693
593 694
594 Object* StubCache::ComputeCallNormal(int argc, 695 MaybeObject* StubCache::ComputeCallNormal(int argc,
595 InLoopFlag in_loop, 696 InLoopFlag in_loop,
596 Code::Kind kind, 697 Code::Kind kind,
597 String* name, 698 String* name,
598 JSObject* receiver) { 699 JSObject* receiver) {
599 Object* code = ComputeCallNormal(argc, in_loop, kind); 700 Object* code;
600 if (code->IsFailure()) return code; 701 { MaybeObject* maybe_code = ComputeCallNormal(argc, in_loop, kind);
702 if (!maybe_code->ToObject(&code)) return maybe_code;
703 }
601 return code; 704 return code;
602 } 705 }
603 706
604 707
605 Object* StubCache::ComputeCallGlobal(int argc, 708 MaybeObject* StubCache::ComputeCallGlobal(int argc,
606 InLoopFlag in_loop, 709 InLoopFlag in_loop,
607 Code::Kind kind, 710 Code::Kind kind,
608 String* name, 711 String* name,
609 JSObject* receiver, 712 JSObject* receiver,
610 GlobalObject* holder, 713 GlobalObject* holder,
611 JSGlobalPropertyCell* cell, 714 JSGlobalPropertyCell* cell,
612 JSFunction* function) { 715 JSFunction* function) {
613 InlineCacheHolderFlag cache_holder = 716 InlineCacheHolderFlag cache_holder =
614 IC::GetCodeCacheForObject(receiver, holder); 717 IC::GetCodeCacheForObject(receiver, holder);
615 JSObject* map_holder = IC::GetCodeCacheHolder(receiver, cache_holder); 718 JSObject* map_holder = IC::GetCodeCacheHolder(receiver, cache_holder);
616 Code::Flags flags = 719 Code::Flags flags =
617 Code::ComputeMonomorphicFlags(kind, 720 Code::ComputeMonomorphicFlags(kind,
618 NORMAL, 721 NORMAL,
619 cache_holder, 722 cache_holder,
620 in_loop, 723 in_loop,
621 argc); 724 argc);
622 Object* code = map_holder->map()->FindInCodeCache(name, flags); 725 Object* code = map_holder->map()->FindInCodeCache(name, flags);
623 if (code->IsUndefined()) { 726 if (code->IsUndefined()) {
624 // If the function hasn't been compiled yet, we cannot do it now 727 // If the function hasn't been compiled yet, we cannot do it now
625 // because it may cause GC. To avoid this issue, we return an 728 // because it may cause GC. To avoid this issue, we return an
626 // internal error which will make sure we do not update any 729 // internal error which will make sure we do not update any
627 // caches. 730 // caches.
628 if (!function->is_compiled()) return Failure::InternalError(); 731 if (!function->is_compiled()) return Failure::InternalError();
629 CallStubCompiler compiler(argc, in_loop, kind, cache_holder); 732 CallStubCompiler compiler(argc, in_loop, kind, cache_holder);
630 code = compiler.CompileCallGlobal(receiver, holder, cell, function, name); 733 { MaybeObject* maybe_code =
631 if (code->IsFailure()) return code; 734 compiler.CompileCallGlobal(receiver, holder, cell, function, name);
735 if (!maybe_code->ToObject(&code)) return maybe_code;
736 }
632 ASSERT_EQ(flags, Code::cast(code)->flags()); 737 ASSERT_EQ(flags, Code::cast(code)->flags());
633 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), 738 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
634 Code::cast(code), name)); 739 Code::cast(code), name));
635 Object* result = map_holder->UpdateMapCodeCache(name, Code::cast(code)); 740 Object* result;
636 if (result->IsFailure()) return result; 741 { MaybeObject* maybe_result =
742 map_holder->UpdateMapCodeCache(name, Code::cast(code));
743 if (!maybe_result->ToObject(&result)) return maybe_result;
744 }
637 } 745 }
638 return code; 746 return code;
639 } 747 }
640 748
641 749
642 static Object* GetProbeValue(Code::Flags flags) { 750 static Object* GetProbeValue(Code::Flags flags) {
643 // Use raw_unchecked... so we don't get assert failures during GC. 751 // Use raw_unchecked... so we don't get assert failures during GC.
644 NumberDictionary* dictionary = Heap::raw_unchecked_non_monomorphic_cache(); 752 NumberDictionary* dictionary = Heap::raw_unchecked_non_monomorphic_cache();
645 int entry = dictionary->FindEntry(flags); 753 int entry = dictionary->FindEntry(flags);
646 if (entry != -1) return dictionary->ValueAt(entry); 754 if (entry != -1) return dictionary->ValueAt(entry);
647 return Heap::raw_unchecked_undefined_value(); 755 return Heap::raw_unchecked_undefined_value();
648 } 756 }
649 757
650 758
651 static Object* ProbeCache(Code::Flags flags) { 759 MUST_USE_RESULT static MaybeObject* ProbeCache(Code::Flags flags) {
652 Object* probe = GetProbeValue(flags); 760 Object* probe = GetProbeValue(flags);
653 if (probe != Heap::undefined_value()) return probe; 761 if (probe != Heap::undefined_value()) return probe;
654 // Seed the cache with an undefined value to make sure that any 762 // Seed the cache with an undefined value to make sure that any
655 // generated code object can always be inserted into the cache 763 // generated code object can always be inserted into the cache
656 // without causing allocation failures. 764 // without causing allocation failures.
657 Object* result = 765 Object* result;
658 Heap::non_monomorphic_cache()->AtNumberPut(flags, 766 { MaybeObject* maybe_result =
659 Heap::undefined_value()); 767 Heap::non_monomorphic_cache()->AtNumberPut(flags,
660 if (result->IsFailure()) return result; 768 Heap::undefined_value());
769 if (!maybe_result->ToObject(&result)) return maybe_result;
770 }
661 Heap::public_set_non_monomorphic_cache(NumberDictionary::cast(result)); 771 Heap::public_set_non_monomorphic_cache(NumberDictionary::cast(result));
662 return probe; 772 return probe;
663 } 773 }
664 774
665 775
666 static Object* FillCache(Object* code) { 776 static MaybeObject* FillCache(MaybeObject* maybe_code) {
667 if (code->IsCode()) { 777 Object* code;
668 int entry = 778 if (maybe_code->ToObject(&code)) {
669 Heap::non_monomorphic_cache()->FindEntry( 779 if (code->IsCode()) {
670 Code::cast(code)->flags()); 780 int entry =
671 // The entry must be present see comment in ProbeCache. 781 Heap::non_monomorphic_cache()->FindEntry(
672 ASSERT(entry != -1); 782 Code::cast(code)->flags());
673 ASSERT(Heap::non_monomorphic_cache()->ValueAt(entry) == 783 // The entry must be present see comment in ProbeCache.
674 Heap::undefined_value()); 784 ASSERT(entry != -1);
675 Heap::non_monomorphic_cache()->ValueAtPut(entry, code); 785 ASSERT(Heap::non_monomorphic_cache()->ValueAt(entry) ==
676 CHECK(GetProbeValue(Code::cast(code)->flags()) == code); 786 Heap::undefined_value());
787 Heap::non_monomorphic_cache()->ValueAtPut(entry, code);
788 CHECK(GetProbeValue(Code::cast(code)->flags()) == code);
789 }
677 } 790 }
678 return code; 791 return maybe_code;
679 } 792 }
680 793
681 794
682 Code* StubCache::FindCallInitialize(int argc, 795 Code* StubCache::FindCallInitialize(int argc,
683 InLoopFlag in_loop, 796 InLoopFlag in_loop,
684 Code::Kind kind) { 797 Code::Kind kind) {
685 Code::Flags flags = 798 Code::Flags flags =
686 Code::ComputeFlags(kind, in_loop, UNINITIALIZED, NORMAL, argc); 799 Code::ComputeFlags(kind, in_loop, UNINITIALIZED, NORMAL, argc);
687 Object* result = ProbeCache(flags); 800 Object* result = ProbeCache(flags)->ToObjectUnchecked();
688 ASSERT(!result->IsUndefined()); 801 ASSERT(!result->IsUndefined());
689 // This might be called during the marking phase of the collector 802 // This might be called during the marking phase of the collector
690 // hence the unchecked cast. 803 // hence the unchecked cast.
691 return reinterpret_cast<Code*>(result); 804 return reinterpret_cast<Code*>(result);
692 } 805 }
693 806
694 807
695 Object* StubCache::ComputeCallInitialize(int argc, 808 MaybeObject* StubCache::ComputeCallInitialize(int argc,
696 InLoopFlag in_loop, 809 InLoopFlag in_loop,
697 Code::Kind kind) { 810 Code::Kind kind) {
698 Code::Flags flags = 811 Code::Flags flags =
699 Code::ComputeFlags(kind, in_loop, UNINITIALIZED, NORMAL, argc); 812 Code::ComputeFlags(kind, in_loop, UNINITIALIZED, NORMAL, argc);
700 Object* probe = ProbeCache(flags); 813 Object* probe;
814 { MaybeObject* maybe_probe = ProbeCache(flags);
815 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
816 }
701 if (!probe->IsUndefined()) return probe; 817 if (!probe->IsUndefined()) return probe;
702 StubCompiler compiler; 818 StubCompiler compiler;
703 return FillCache(compiler.CompileCallInitialize(flags)); 819 return FillCache(compiler.CompileCallInitialize(flags));
704 } 820 }
705 821
706 822
707 Object* StubCache::ComputeCallPreMonomorphic(int argc, 823 MaybeObject* StubCache::ComputeCallPreMonomorphic(int argc,
708 InLoopFlag in_loop, 824 InLoopFlag in_loop,
709 Code::Kind kind) { 825 Code::Kind kind) {
710 Code::Flags flags = 826 Code::Flags flags =
711 Code::ComputeFlags(kind, in_loop, PREMONOMORPHIC, NORMAL, argc); 827 Code::ComputeFlags(kind, in_loop, PREMONOMORPHIC, NORMAL, argc);
712 Object* probe = ProbeCache(flags); 828 Object* probe;
829 { MaybeObject* maybe_probe = ProbeCache(flags);
830 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
831 }
713 if (!probe->IsUndefined()) return probe; 832 if (!probe->IsUndefined()) return probe;
714 StubCompiler compiler; 833 StubCompiler compiler;
715 return FillCache(compiler.CompileCallPreMonomorphic(flags)); 834 return FillCache(compiler.CompileCallPreMonomorphic(flags));
716 } 835 }
717 836
718 837
719 Object* StubCache::ComputeCallNormal(int argc, 838 MaybeObject* StubCache::ComputeCallNormal(int argc,
720 InLoopFlag in_loop, 839 InLoopFlag in_loop,
721 Code::Kind kind) { 840 Code::Kind kind) {
722 Code::Flags flags = 841 Code::Flags flags =
723 Code::ComputeFlags(kind, in_loop, MONOMORPHIC, NORMAL, argc); 842 Code::ComputeFlags(kind, in_loop, MONOMORPHIC, NORMAL, argc);
724 Object* probe = ProbeCache(flags); 843 Object* probe;
844 { MaybeObject* maybe_probe = ProbeCache(flags);
845 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
846 }
725 if (!probe->IsUndefined()) return probe; 847 if (!probe->IsUndefined()) return probe;
726 StubCompiler compiler; 848 StubCompiler compiler;
727 return FillCache(compiler.CompileCallNormal(flags)); 849 return FillCache(compiler.CompileCallNormal(flags));
728 } 850 }
729 851
730 852
731 Object* StubCache::ComputeCallMegamorphic(int argc, 853 MaybeObject* StubCache::ComputeCallMegamorphic(int argc,
732 InLoopFlag in_loop, 854 InLoopFlag in_loop,
733 Code::Kind kind) { 855 Code::Kind kind) {
734 Code::Flags flags = 856 Code::Flags flags =
735 Code::ComputeFlags(kind, in_loop, MEGAMORPHIC, NORMAL, argc); 857 Code::ComputeFlags(kind, in_loop, MEGAMORPHIC, NORMAL, argc);
736 Object* probe = ProbeCache(flags); 858 Object* probe;
859 { MaybeObject* maybe_probe = ProbeCache(flags);
860 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
861 }
737 if (!probe->IsUndefined()) return probe; 862 if (!probe->IsUndefined()) return probe;
738 StubCompiler compiler; 863 StubCompiler compiler;
739 return FillCache(compiler.CompileCallMegamorphic(flags)); 864 return FillCache(compiler.CompileCallMegamorphic(flags));
740 } 865 }
741 866
742 867
743 Object* StubCache::ComputeCallMiss(int argc, Code::Kind kind) { 868 MaybeObject* StubCache::ComputeCallMiss(int argc, Code::Kind kind) {
744 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs 869 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs
745 // and monomorphic stubs are not mixed up together in the stub cache. 870 // and monomorphic stubs are not mixed up together in the stub cache.
746 Code::Flags flags = Code::ComputeFlags( 871 Code::Flags flags = Code::ComputeFlags(
747 kind, NOT_IN_LOOP, MONOMORPHIC_PROTOTYPE_FAILURE, NORMAL, argc); 872 kind, NOT_IN_LOOP, MONOMORPHIC_PROTOTYPE_FAILURE, NORMAL, argc);
748 Object* probe = ProbeCache(flags); 873 Object* probe;
874 { MaybeObject* maybe_probe = ProbeCache(flags);
875 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
876 }
749 if (!probe->IsUndefined()) return probe; 877 if (!probe->IsUndefined()) return probe;
750 StubCompiler compiler; 878 StubCompiler compiler;
751 return FillCache(compiler.CompileCallMiss(flags)); 879 return FillCache(compiler.CompileCallMiss(flags));
752 } 880 }
753 881
754 882
755 #ifdef ENABLE_DEBUGGER_SUPPORT 883 #ifdef ENABLE_DEBUGGER_SUPPORT
756 Object* StubCache::ComputeCallDebugBreak(int argc, Code::Kind kind) { 884 MaybeObject* StubCache::ComputeCallDebugBreak(int argc, Code::Kind kind) {
757 Code::Flags flags = 885 Code::Flags flags =
758 Code::ComputeFlags(kind, NOT_IN_LOOP, DEBUG_BREAK, NORMAL, argc); 886 Code::ComputeFlags(kind, NOT_IN_LOOP, DEBUG_BREAK, NORMAL, argc);
759 Object* probe = ProbeCache(flags); 887 Object* probe;
888 { MaybeObject* maybe_probe = ProbeCache(flags);
889 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
890 }
760 if (!probe->IsUndefined()) return probe; 891 if (!probe->IsUndefined()) return probe;
761 StubCompiler compiler; 892 StubCompiler compiler;
762 return FillCache(compiler.CompileCallDebugBreak(flags)); 893 return FillCache(compiler.CompileCallDebugBreak(flags));
763 } 894 }
764 895
765 896
766 Object* StubCache::ComputeCallDebugPrepareStepIn(int argc, Code::Kind kind) { 897 MaybeObject* StubCache::ComputeCallDebugPrepareStepIn(int argc,
898 Code::Kind kind) {
767 Code::Flags flags = 899 Code::Flags flags =
768 Code::ComputeFlags(kind, 900 Code::ComputeFlags(kind,
769 NOT_IN_LOOP, 901 NOT_IN_LOOP,
770 DEBUG_PREPARE_STEP_IN, 902 DEBUG_PREPARE_STEP_IN,
771 NORMAL, 903 NORMAL,
772 argc); 904 argc);
773 Object* probe = ProbeCache(flags); 905 Object* probe;
906 { MaybeObject* maybe_probe = ProbeCache(flags);
907 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
908 }
774 if (!probe->IsUndefined()) return probe; 909 if (!probe->IsUndefined()) return probe;
775 StubCompiler compiler; 910 StubCompiler compiler;
776 return FillCache(compiler.CompileCallDebugPrepareStepIn(flags)); 911 return FillCache(compiler.CompileCallDebugPrepareStepIn(flags));
777 } 912 }
778 #endif 913 #endif
779 914
780 915
781 void StubCache::Clear() { 916 void StubCache::Clear() {
782 for (int i = 0; i < kPrimaryTableSize; i++) { 917 for (int i = 0; i < kPrimaryTableSize; i++) {
783 primary_[i].key = Heap::empty_string(); 918 primary_[i].key = Heap::empty_string();
784 primary_[i].value = Builtins::builtin(Builtins::Illegal); 919 primary_[i].value = Builtins::builtin(Builtins::Illegal);
785 } 920 }
786 for (int j = 0; j < kSecondaryTableSize; j++) { 921 for (int j = 0; j < kSecondaryTableSize; j++) {
787 secondary_[j].key = Heap::empty_string(); 922 secondary_[j].key = Heap::empty_string();
788 secondary_[j].value = Builtins::builtin(Builtins::Illegal); 923 secondary_[j].value = Builtins::builtin(Builtins::Illegal);
789 } 924 }
790 } 925 }
791 926
792 927
793 // ------------------------------------------------------------------------ 928 // ------------------------------------------------------------------------
794 // StubCompiler implementation. 929 // StubCompiler implementation.
795 930
796 931
797 Object* LoadCallbackProperty(Arguments args) { 932 MaybeObject* LoadCallbackProperty(Arguments args) {
798 ASSERT(args[0]->IsJSObject()); 933 ASSERT(args[0]->IsJSObject());
799 ASSERT(args[1]->IsJSObject()); 934 ASSERT(args[1]->IsJSObject());
800 AccessorInfo* callback = AccessorInfo::cast(args[2]); 935 AccessorInfo* callback = AccessorInfo::cast(args[2]);
801 Address getter_address = v8::ToCData<Address>(callback->getter()); 936 Address getter_address = v8::ToCData<Address>(callback->getter());
802 v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address); 937 v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address);
803 ASSERT(fun != NULL); 938 ASSERT(fun != NULL);
804 CustomArguments custom_args(callback->data(), 939 CustomArguments custom_args(callback->data(),
805 JSObject::cast(args[0]), 940 JSObject::cast(args[0]),
806 JSObject::cast(args[1])); 941 JSObject::cast(args[1]));
807 v8::AccessorInfo info(custom_args.end()); 942 v8::AccessorInfo info(custom_args.end());
808 HandleScope scope; 943 HandleScope scope;
809 v8::Handle<v8::Value> result; 944 v8::Handle<v8::Value> result;
810 { 945 {
811 // Leaving JavaScript. 946 // Leaving JavaScript.
812 VMState state(EXTERNAL); 947 VMState state(EXTERNAL);
813 #ifdef ENABLE_LOGGING_AND_PROFILING 948 #ifdef ENABLE_LOGGING_AND_PROFILING
814 state.set_external_callback(getter_address); 949 state.set_external_callback(getter_address);
815 #endif 950 #endif
816 result = fun(v8::Utils::ToLocal(args.at<String>(4)), info); 951 result = fun(v8::Utils::ToLocal(args.at<String>(4)), info);
817 } 952 }
818 RETURN_IF_SCHEDULED_EXCEPTION(); 953 RETURN_IF_SCHEDULED_EXCEPTION();
819 if (result.IsEmpty()) return Heap::undefined_value(); 954 if (result.IsEmpty()) return Heap::undefined_value();
820 return *v8::Utils::OpenHandle(*result); 955 return *v8::Utils::OpenHandle(*result);
821 } 956 }
822 957
823 958
824 Object* StoreCallbackProperty(Arguments args) { 959 MaybeObject* StoreCallbackProperty(Arguments args) {
825 JSObject* recv = JSObject::cast(args[0]); 960 JSObject* recv = JSObject::cast(args[0]);
826 AccessorInfo* callback = AccessorInfo::cast(args[1]); 961 AccessorInfo* callback = AccessorInfo::cast(args[1]);
827 Address setter_address = v8::ToCData<Address>(callback->setter()); 962 Address setter_address = v8::ToCData<Address>(callback->setter());
828 v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address); 963 v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address);
829 ASSERT(fun != NULL); 964 ASSERT(fun != NULL);
830 Handle<String> name = args.at<String>(2); 965 Handle<String> name = args.at<String>(2);
831 Handle<Object> value = args.at<Object>(3); 966 Handle<Object> value = args.at<Object>(3);
832 HandleScope scope; 967 HandleScope scope;
833 LOG(ApiNamedPropertyAccess("store", recv, *name)); 968 LOG(ApiNamedPropertyAccess("store", recv, *name));
834 CustomArguments custom_args(callback->data(), recv, recv); 969 CustomArguments custom_args(callback->data(), recv, recv);
(...skipping 14 matching lines...) Expand all
849 static const int kAccessorInfoOffsetInInterceptorArgs = 2; 984 static const int kAccessorInfoOffsetInInterceptorArgs = 2;
850 985
851 986
852 /** 987 /**
853 * Attempts to load a property with an interceptor (which must be present), 988 * Attempts to load a property with an interceptor (which must be present),
854 * but doesn't search the prototype chain. 989 * but doesn't search the prototype chain.
855 * 990 *
856 * Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't 991 * Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't
857 * provide any value for the given name. 992 * provide any value for the given name.
858 */ 993 */
859 Object* LoadPropertyWithInterceptorOnly(Arguments args) { 994 MaybeObject* LoadPropertyWithInterceptorOnly(Arguments args) {
860 Handle<String> name_handle = args.at<String>(0); 995 Handle<String> name_handle = args.at<String>(0);
861 Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(1); 996 Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(1);
862 ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2); 997 ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2);
863 ASSERT(args[2]->IsJSObject()); // Receiver. 998 ASSERT(args[2]->IsJSObject()); // Receiver.
864 ASSERT(args[3]->IsJSObject()); // Holder. 999 ASSERT(args[3]->IsJSObject()); // Holder.
865 ASSERT(args.length() == 5); // Last arg is data object. 1000 ASSERT(args.length() == 5); // Last arg is data object.
866 1001
867 Address getter_address = v8::ToCData<Address>(interceptor_info->getter()); 1002 Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
868 v8::NamedPropertyGetter getter = 1003 v8::NamedPropertyGetter getter =
869 FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address); 1004 FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address);
(...skipping 13 matching lines...) Expand all
883 RETURN_IF_SCHEDULED_EXCEPTION(); 1018 RETURN_IF_SCHEDULED_EXCEPTION();
884 if (!r.IsEmpty()) { 1019 if (!r.IsEmpty()) {
885 return *v8::Utils::OpenHandle(*r); 1020 return *v8::Utils::OpenHandle(*r);
886 } 1021 }
887 } 1022 }
888 1023
889 return Heap::no_interceptor_result_sentinel(); 1024 return Heap::no_interceptor_result_sentinel();
890 } 1025 }
891 1026
892 1027
893 static Object* ThrowReferenceError(String* name) { 1028 static MaybeObject* ThrowReferenceError(String* name) {
894 // If the load is non-contextual, just return the undefined result. 1029 // If the load is non-contextual, just return the undefined result.
895 // Note that both keyed and non-keyed loads may end up here, so we 1030 // Note that both keyed and non-keyed loads may end up here, so we
896 // can't use either LoadIC or KeyedLoadIC constructors. 1031 // can't use either LoadIC or KeyedLoadIC constructors.
897 IC ic(IC::NO_EXTRA_FRAME); 1032 IC ic(IC::NO_EXTRA_FRAME);
898 ASSERT(ic.target()->is_load_stub() || ic.target()->is_keyed_load_stub()); 1033 ASSERT(ic.target()->is_load_stub() || ic.target()->is_keyed_load_stub());
899 if (!ic.SlowIsContextual()) return Heap::undefined_value(); 1034 if (!ic.SlowIsContextual()) return Heap::undefined_value();
900 1035
901 // Throw a reference error. 1036 // Throw a reference error.
902 HandleScope scope; 1037 HandleScope scope;
903 Handle<String> name_handle(name); 1038 Handle<String> name_handle(name);
904 Handle<Object> error = 1039 Handle<Object> error =
905 Factory::NewReferenceError("not_defined", 1040 Factory::NewReferenceError("not_defined",
906 HandleVector(&name_handle, 1)); 1041 HandleVector(&name_handle, 1));
907 return Top::Throw(*error); 1042 return Top::Throw(*error);
908 } 1043 }
909 1044
910 1045
911 static Object* LoadWithInterceptor(Arguments* args, 1046 static MaybeObject* LoadWithInterceptor(Arguments* args,
912 PropertyAttributes* attrs) { 1047 PropertyAttributes* attrs) {
913 Handle<String> name_handle = args->at<String>(0); 1048 Handle<String> name_handle = args->at<String>(0);
914 Handle<InterceptorInfo> interceptor_info = args->at<InterceptorInfo>(1); 1049 Handle<InterceptorInfo> interceptor_info = args->at<InterceptorInfo>(1);
915 ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2); 1050 ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2);
916 Handle<JSObject> receiver_handle = args->at<JSObject>(2); 1051 Handle<JSObject> receiver_handle = args->at<JSObject>(2);
917 Handle<JSObject> holder_handle = args->at<JSObject>(3); 1052 Handle<JSObject> holder_handle = args->at<JSObject>(3);
918 ASSERT(args->length() == 5); // Last arg is data object. 1053 ASSERT(args->length() == 5); // Last arg is data object.
919 1054
920 Address getter_address = v8::ToCData<Address>(interceptor_info->getter()); 1055 Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
921 v8::NamedPropertyGetter getter = 1056 v8::NamedPropertyGetter getter =
922 FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address); 1057 FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address);
(...skipping 10 matching lines...) Expand all
933 VMState state(EXTERNAL); 1068 VMState state(EXTERNAL);
934 r = getter(v8::Utils::ToLocal(name_handle), info); 1069 r = getter(v8::Utils::ToLocal(name_handle), info);
935 } 1070 }
936 RETURN_IF_SCHEDULED_EXCEPTION(); 1071 RETURN_IF_SCHEDULED_EXCEPTION();
937 if (!r.IsEmpty()) { 1072 if (!r.IsEmpty()) {
938 *attrs = NONE; 1073 *attrs = NONE;
939 return *v8::Utils::OpenHandle(*r); 1074 return *v8::Utils::OpenHandle(*r);
940 } 1075 }
941 } 1076 }
942 1077
943 Object* result = holder_handle->GetPropertyPostInterceptor( 1078 MaybeObject* result = holder_handle->GetPropertyPostInterceptor(
944 *receiver_handle, 1079 *receiver_handle,
945 *name_handle, 1080 *name_handle,
946 attrs); 1081 attrs);
947 RETURN_IF_SCHEDULED_EXCEPTION(); 1082 RETURN_IF_SCHEDULED_EXCEPTION();
948 return result; 1083 return result;
949 } 1084 }
950 1085
951 1086
952 /** 1087 /**
953 * Loads a property with an interceptor performing post interceptor 1088 * Loads a property with an interceptor performing post interceptor
954 * lookup if interceptor failed. 1089 * lookup if interceptor failed.
955 */ 1090 */
956 Object* LoadPropertyWithInterceptorForLoad(Arguments args) { 1091 MaybeObject* LoadPropertyWithInterceptorForLoad(Arguments args) {
957 PropertyAttributes attr = NONE; 1092 PropertyAttributes attr = NONE;
958 Object* result = LoadWithInterceptor(&args, &attr); 1093 Object* result;
959 if (result->IsFailure()) return result; 1094 { MaybeObject* maybe_result = LoadWithInterceptor(&args, &attr);
1095 if (!maybe_result->ToObject(&result)) return maybe_result;
1096 }
960 1097
961 // If the property is present, return it. 1098 // If the property is present, return it.
962 if (attr != ABSENT) return result; 1099 if (attr != ABSENT) return result;
963 return ThrowReferenceError(String::cast(args[0])); 1100 return ThrowReferenceError(String::cast(args[0]));
964 } 1101 }
965 1102
966 1103
967 Object* LoadPropertyWithInterceptorForCall(Arguments args) { 1104 MaybeObject* LoadPropertyWithInterceptorForCall(Arguments args) {
968 PropertyAttributes attr; 1105 PropertyAttributes attr;
969 Object* result = LoadWithInterceptor(&args, &attr); 1106 MaybeObject* result = LoadWithInterceptor(&args, &attr);
970 RETURN_IF_SCHEDULED_EXCEPTION(); 1107 RETURN_IF_SCHEDULED_EXCEPTION();
971 // This is call IC. In this case, we simply return the undefined result which 1108 // This is call IC. In this case, we simply return the undefined result which
972 // will lead to an exception when trying to invoke the result as a 1109 // will lead to an exception when trying to invoke the result as a
973 // function. 1110 // function.
974 return result; 1111 return result;
975 } 1112 }
976 1113
977 1114
978 Object* StoreInterceptorProperty(Arguments args) { 1115 MaybeObject* StoreInterceptorProperty(Arguments args) {
979 JSObject* recv = JSObject::cast(args[0]); 1116 JSObject* recv = JSObject::cast(args[0]);
980 String* name = String::cast(args[1]); 1117 String* name = String::cast(args[1]);
981 Object* value = args[2]; 1118 Object* value = args[2];
982 ASSERT(recv->HasNamedInterceptor()); 1119 ASSERT(recv->HasNamedInterceptor());
983 PropertyAttributes attr = NONE; 1120 PropertyAttributes attr = NONE;
984 Object* result = recv->SetPropertyWithInterceptor(name, value, attr); 1121 MaybeObject* result = recv->SetPropertyWithInterceptor(name, value, attr);
985 return result; 1122 return result;
986 } 1123 }
987 1124
988 1125
989 Object* KeyedLoadPropertyWithInterceptor(Arguments args) { 1126 MaybeObject* KeyedLoadPropertyWithInterceptor(Arguments args) {
990 JSObject* receiver = JSObject::cast(args[0]); 1127 JSObject* receiver = JSObject::cast(args[0]);
991 ASSERT(Smi::cast(args[1])->value() >= 0); 1128 ASSERT(Smi::cast(args[1])->value() >= 0);
992 uint32_t index = Smi::cast(args[1])->value(); 1129 uint32_t index = Smi::cast(args[1])->value();
993 return receiver->GetElementWithInterceptor(receiver, index); 1130 return receiver->GetElementWithInterceptor(receiver, index);
994 } 1131 }
995 1132
996 1133
997 Object* StubCompiler::CompileCallInitialize(Code::Flags flags) { 1134 MaybeObject* StubCompiler::CompileCallInitialize(Code::Flags flags) {
998 HandleScope scope; 1135 HandleScope scope;
999 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1136 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1000 Code::Kind kind = Code::ExtractKindFromFlags(flags); 1137 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1001 if (kind == Code::CALL_IC) { 1138 if (kind == Code::CALL_IC) {
1002 CallIC::GenerateInitialize(masm(), argc); 1139 CallIC::GenerateInitialize(masm(), argc);
1003 } else { 1140 } else {
1004 KeyedCallIC::GenerateInitialize(masm(), argc); 1141 KeyedCallIC::GenerateInitialize(masm(), argc);
1005 } 1142 }
1006 Object* result = GetCodeWithFlags(flags, "CompileCallInitialize"); 1143 Object* result;
1007 if (!result->IsFailure()) { 1144 { MaybeObject* maybe_result =
1008 Counters::call_initialize_stubs.Increment(); 1145 GetCodeWithFlags(flags, "CompileCallInitialize");
1009 Code* code = Code::cast(result); 1146 if (!maybe_result->ToObject(&result)) return maybe_result;
1010 USE(code);
1011 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG),
1012 code, code->arguments_count()));
1013 } 1147 }
1148 Counters::call_initialize_stubs.Increment();
1149 Code* code = Code::cast(result);
1150 USE(code);
1151 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG),
1152 code, code->arguments_count()));
1014 return result; 1153 return result;
1015 } 1154 }
1016 1155
1017 1156
1018 Object* StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { 1157 MaybeObject* StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) {
1019 HandleScope scope; 1158 HandleScope scope;
1020 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1159 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1021 // The code of the PreMonomorphic stub is the same as the code 1160 // The code of the PreMonomorphic stub is the same as the code
1022 // of the Initialized stub. They just differ on the code object flags. 1161 // of the Initialized stub. They just differ on the code object flags.
1023 Code::Kind kind = Code::ExtractKindFromFlags(flags); 1162 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1024 if (kind == Code::CALL_IC) { 1163 if (kind == Code::CALL_IC) {
1025 CallIC::GenerateInitialize(masm(), argc); 1164 CallIC::GenerateInitialize(masm(), argc);
1026 } else { 1165 } else {
1027 KeyedCallIC::GenerateInitialize(masm(), argc); 1166 KeyedCallIC::GenerateInitialize(masm(), argc);
1028 } 1167 }
1029 Object* result = GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); 1168 Object* result;
1030 if (!result->IsFailure()) { 1169 { MaybeObject* maybe_result =
1031 Counters::call_premonomorphic_stubs.Increment(); 1170 GetCodeWithFlags(flags, "CompileCallPreMonomorphic");
1032 Code* code = Code::cast(result); 1171 if (!maybe_result->ToObject(&result)) return maybe_result;
1033 USE(code);
1034 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG),
1035 code, code->arguments_count()));
1036 } 1172 }
1173 Counters::call_premonomorphic_stubs.Increment();
1174 Code* code = Code::cast(result);
1175 USE(code);
1176 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG),
1177 code, code->arguments_count()));
1037 return result; 1178 return result;
1038 } 1179 }
1039 1180
1040 1181
1041 Object* StubCompiler::CompileCallNormal(Code::Flags flags) { 1182 MaybeObject* StubCompiler::CompileCallNormal(Code::Flags flags) {
1042 HandleScope scope; 1183 HandleScope scope;
1043 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1184 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1044 Code::Kind kind = Code::ExtractKindFromFlags(flags); 1185 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1045 if (kind == Code::CALL_IC) { 1186 if (kind == Code::CALL_IC) {
1046 CallIC::GenerateNormal(masm(), argc); 1187 CallIC::GenerateNormal(masm(), argc);
1047 } else { 1188 } else {
1048 KeyedCallIC::GenerateNormal(masm(), argc); 1189 KeyedCallIC::GenerateNormal(masm(), argc);
1049 } 1190 }
1050 Object* result = GetCodeWithFlags(flags, "CompileCallNormal"); 1191 Object* result;
1051 if (!result->IsFailure()) { 1192 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallNormal");
1052 Counters::call_normal_stubs.Increment(); 1193 if (!maybe_result->ToObject(&result)) return maybe_result;
1053 Code* code = Code::cast(result);
1054 USE(code);
1055 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG),
1056 code, code->arguments_count()));
1057 } 1194 }
1195 Counters::call_normal_stubs.Increment();
1196 Code* code = Code::cast(result);
1197 USE(code);
1198 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG),
1199 code, code->arguments_count()));
1058 return result; 1200 return result;
1059 } 1201 }
1060 1202
1061 1203
1062 Object* StubCompiler::CompileCallMegamorphic(Code::Flags flags) { 1204 MaybeObject* StubCompiler::CompileCallMegamorphic(Code::Flags flags) {
1063 HandleScope scope; 1205 HandleScope scope;
1064 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1206 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1065 Code::Kind kind = Code::ExtractKindFromFlags(flags); 1207 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1066 if (kind == Code::CALL_IC) { 1208 if (kind == Code::CALL_IC) {
1067 CallIC::GenerateMegamorphic(masm(), argc); 1209 CallIC::GenerateMegamorphic(masm(), argc);
1068 } else { 1210 } else {
1069 KeyedCallIC::GenerateMegamorphic(masm(), argc); 1211 KeyedCallIC::GenerateMegamorphic(masm(), argc);
1070 } 1212 }
1071 1213
1072 Object* result = GetCodeWithFlags(flags, "CompileCallMegamorphic"); 1214 Object* result;
1073 if (!result->IsFailure()) { 1215 { MaybeObject* maybe_result =
1074 Counters::call_megamorphic_stubs.Increment(); 1216 GetCodeWithFlags(flags, "CompileCallMegamorphic");
1075 Code* code = Code::cast(result); 1217 if (!maybe_result->ToObject(&result)) return maybe_result;
1076 USE(code);
1077 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG),
1078 code, code->arguments_count()));
1079 } 1218 }
1219 Counters::call_megamorphic_stubs.Increment();
1220 Code* code = Code::cast(result);
1221 USE(code);
1222 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG),
1223 code, code->arguments_count()));
1080 return result; 1224 return result;
1081 } 1225 }
1082 1226
1083 1227
1084 Object* StubCompiler::CompileCallMiss(Code::Flags flags) { 1228 MaybeObject* StubCompiler::CompileCallMiss(Code::Flags flags) {
1085 HandleScope scope; 1229 HandleScope scope;
1086 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1230 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1087 Code::Kind kind = Code::ExtractKindFromFlags(flags); 1231 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1088 if (kind == Code::CALL_IC) { 1232 if (kind == Code::CALL_IC) {
1089 CallIC::GenerateMiss(masm(), argc); 1233 CallIC::GenerateMiss(masm(), argc);
1090 } else { 1234 } else {
1091 KeyedCallIC::GenerateMiss(masm(), argc); 1235 KeyedCallIC::GenerateMiss(masm(), argc);
1092 } 1236 }
1093 Object* result = GetCodeWithFlags(flags, "CompileCallMiss"); 1237 Object* result;
1094 if (!result->IsFailure()) { 1238 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallMiss");
1095 Counters::call_megamorphic_stubs.Increment(); 1239 if (!maybe_result->ToObject(&result)) return maybe_result;
1096 Code* code = Code::cast(result);
1097 USE(code);
1098 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG),
1099 code, code->arguments_count()));
1100 } 1240 }
1241 Counters::call_megamorphic_stubs.Increment();
1242 Code* code = Code::cast(result);
1243 USE(code);
1244 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG),
1245 code, code->arguments_count()));
1101 return result; 1246 return result;
1102 } 1247 }
1103 1248
1104 1249
1105 #ifdef ENABLE_DEBUGGER_SUPPORT 1250 #ifdef ENABLE_DEBUGGER_SUPPORT
1106 Object* StubCompiler::CompileCallDebugBreak(Code::Flags flags) { 1251 MaybeObject* StubCompiler::CompileCallDebugBreak(Code::Flags flags) {
1107 HandleScope scope; 1252 HandleScope scope;
1108 Debug::GenerateCallICDebugBreak(masm()); 1253 Debug::GenerateCallICDebugBreak(masm());
1109 Object* result = GetCodeWithFlags(flags, "CompileCallDebugBreak"); 1254 Object* result;
1110 if (!result->IsFailure()) { 1255 { MaybeObject* maybe_result =
1111 Code* code = Code::cast(result); 1256 GetCodeWithFlags(flags, "CompileCallDebugBreak");
1112 USE(code); 1257 if (!maybe_result->ToObject(&result)) return maybe_result;
1113 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1114 USE(kind);
1115 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_DEBUG_BREAK_TAG),
1116 code, code->arguments_count()));
1117 } 1258 }
1259 Code* code = Code::cast(result);
1260 USE(code);
1261 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1262 USE(kind);
1263 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_DEBUG_BREAK_TAG),
1264 code, code->arguments_count()));
1118 return result; 1265 return result;
1119 } 1266 }
1120 1267
1121 1268
1122 Object* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { 1269 MaybeObject* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) {
1123 HandleScope scope; 1270 HandleScope scope;
1124 // Use the same code for the the step in preparations as we do for 1271 // Use the same code for the the step in preparations as we do for
1125 // the miss case. 1272 // the miss case.
1126 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1273 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1127 Code::Kind kind = Code::ExtractKindFromFlags(flags); 1274 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1128 if (kind == Code::CALL_IC) { 1275 if (kind == Code::CALL_IC) {
1129 CallIC::GenerateMiss(masm(), argc); 1276 CallIC::GenerateMiss(masm(), argc);
1130 } else { 1277 } else {
1131 KeyedCallIC::GenerateMiss(masm(), argc); 1278 KeyedCallIC::GenerateMiss(masm(), argc);
1132 } 1279 }
1133 Object* result = GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn"); 1280 Object* result;
1134 if (!result->IsFailure()) { 1281 { MaybeObject* maybe_result =
1135 Code* code = Code::cast(result); 1282 GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn");
1136 USE(code); 1283 if (!maybe_result->ToObject(&result)) return maybe_result;
1137 PROFILE(CodeCreateEvent(
1138 CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG),
1139 code,
1140 code->arguments_count()));
1141 } 1284 }
1285 Code* code = Code::cast(result);
1286 USE(code);
1287 PROFILE(CodeCreateEvent(
1288 CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG),
1289 code,
1290 code->arguments_count()));
1142 return result; 1291 return result;
1143 } 1292 }
1144 #endif 1293 #endif
1145 1294
1146 #undef CALL_LOGGER_TAG 1295 #undef CALL_LOGGER_TAG
1147 1296
1148 Object* StubCompiler::GetCodeWithFlags(Code::Flags flags, const char* name) { 1297 MaybeObject* StubCompiler::GetCodeWithFlags(Code::Flags flags,
1298 const char* name) {
1149 // Check for allocation failures during stub compilation. 1299 // Check for allocation failures during stub compilation.
1150 if (failure_->IsFailure()) return failure_; 1300 if (failure_->IsFailure()) return failure_;
1151 1301
1152 // Create code object in the heap. 1302 // Create code object in the heap.
1153 CodeDesc desc; 1303 CodeDesc desc;
1154 masm_.GetCode(&desc); 1304 masm_.GetCode(&desc);
1155 Object* result = Heap::CreateCode(desc, flags, masm_.CodeObject()); 1305 MaybeObject* result = Heap::CreateCode(desc, flags, masm_.CodeObject());
1156 #ifdef ENABLE_DISASSEMBLER 1306 #ifdef ENABLE_DISASSEMBLER
1157 if (FLAG_print_code_stubs && !result->IsFailure()) { 1307 if (FLAG_print_code_stubs && !result->IsFailure()) {
1158 Code::cast(result)->Disassemble(name); 1308 Code::cast(result->ToObjectUnchecked())->Disassemble(name);
1159 } 1309 }
1160 #endif 1310 #endif
1161 return result; 1311 return result;
1162 } 1312 }
1163 1313
1164 1314
1165 Object* StubCompiler::GetCodeWithFlags(Code::Flags flags, String* name) { 1315 MaybeObject* StubCompiler::GetCodeWithFlags(Code::Flags flags, String* name) {
1166 if (FLAG_print_code_stubs && (name != NULL)) { 1316 if (FLAG_print_code_stubs && (name != NULL)) {
1167 return GetCodeWithFlags(flags, *name->ToCString()); 1317 return GetCodeWithFlags(flags, *name->ToCString());
1168 } 1318 }
1169 return GetCodeWithFlags(flags, reinterpret_cast<char*>(NULL)); 1319 return GetCodeWithFlags(flags, reinterpret_cast<char*>(NULL));
1170 } 1320 }
1171 1321
1172 1322
1173 void StubCompiler::LookupPostInterceptor(JSObject* holder, 1323 void StubCompiler::LookupPostInterceptor(JSObject* holder,
1174 String* name, 1324 String* name,
1175 LookupResult* lookup) { 1325 LookupResult* lookup) {
1176 holder->LocalLookupRealNamedProperty(name, lookup); 1326 holder->LocalLookupRealNamedProperty(name, lookup);
1177 if (!lookup->IsProperty()) { 1327 if (!lookup->IsProperty()) {
1178 lookup->NotFound(); 1328 lookup->NotFound();
1179 Object* proto = holder->GetPrototype(); 1329 Object* proto = holder->GetPrototype();
1180 if (proto != Heap::null_value()) { 1330 if (proto != Heap::null_value()) {
1181 proto->Lookup(name, lookup); 1331 proto->Lookup(name, lookup);
1182 } 1332 }
1183 } 1333 }
1184 } 1334 }
1185 1335
1186 1336
1187 1337
1188 Object* LoadStubCompiler::GetCode(PropertyType type, String* name) { 1338 MaybeObject* LoadStubCompiler::GetCode(PropertyType type, String* name) {
1189 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type); 1339 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type);
1190 Object* result = GetCodeWithFlags(flags, name); 1340 MaybeObject* result = GetCodeWithFlags(flags, name);
1191 if (!result->IsFailure()) { 1341 if (!result->IsFailure()) {
1192 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(result), name)); 1342 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG,
1343 Code::cast(result->ToObjectUnchecked()),
1344 name));
1193 } 1345 }
1194 return result; 1346 return result;
1195 } 1347 }
1196 1348
1197 1349
1198 Object* KeyedLoadStubCompiler::GetCode(PropertyType type, String* name) { 1350 MaybeObject* KeyedLoadStubCompiler::GetCode(PropertyType type, String* name) {
1199 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, type); 1351 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, type);
1200 Object* result = GetCodeWithFlags(flags, name); 1352 MaybeObject* result = GetCodeWithFlags(flags, name);
1201 if (!result->IsFailure()) { 1353 if (!result->IsFailure()) {
1202 PROFILE( 1354 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG,
1203 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(result), name)); 1355 Code::cast(result->ToObjectUnchecked()),
1356 name));
1204 } 1357 }
1205 return result; 1358 return result;
1206 } 1359 }
1207 1360
1208 1361
1209 Object* StoreStubCompiler::GetCode(PropertyType type, String* name) { 1362 MaybeObject* StoreStubCompiler::GetCode(PropertyType type, String* name) {
1210 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, type); 1363 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, type);
1211 Object* result = GetCodeWithFlags(flags, name); 1364 MaybeObject* result = GetCodeWithFlags(flags, name);
1212 if (!result->IsFailure()) { 1365 if (!result->IsFailure()) {
1213 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(result), name)); 1366 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG,
1367 Code::cast(result->ToObjectUnchecked()),
1368 name));
1214 } 1369 }
1215 return result; 1370 return result;
1216 } 1371 }
1217 1372
1218 1373
1219 Object* KeyedStoreStubCompiler::GetCode(PropertyType type, String* name) { 1374 MaybeObject* KeyedStoreStubCompiler::GetCode(PropertyType type, String* name) {
1220 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, type); 1375 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, type);
1221 Object* result = GetCodeWithFlags(flags, name); 1376 MaybeObject* result = GetCodeWithFlags(flags, name);
1222 if (!result->IsFailure()) { 1377 if (!result->IsFailure()) {
1223 PROFILE( 1378 PROFILE(CodeCreateEvent(Logger::KEYED_STORE_IC_TAG,
1224 CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, Code::cast(result), name)); 1379 Code::cast(result->ToObjectUnchecked()),
1380 name));
1225 } 1381 }
1226 return result; 1382 return result;
1227 } 1383 }
1228 1384
1229 1385
1230 CallStubCompiler::CallStubCompiler(int argc, 1386 CallStubCompiler::CallStubCompiler(int argc,
1231 InLoopFlag in_loop, 1387 InLoopFlag in_loop,
1232 Code::Kind kind, 1388 Code::Kind kind,
1233 InlineCacheHolderFlag cache_holder) 1389 InlineCacheHolderFlag cache_holder)
1234 : arguments_(argc) 1390 : arguments_(argc)
1235 , in_loop_(in_loop) 1391 , in_loop_(in_loop)
1236 , kind_(kind) 1392 , kind_(kind)
1237 , cache_holder_(cache_holder) { 1393 , cache_holder_(cache_holder) {
1238 } 1394 }
1239 1395
1240 1396
1241 Object* CallStubCompiler::CompileCustomCall(int generator_id, 1397 MaybeObject* CallStubCompiler::CompileCustomCall(int generator_id,
1242 Object* object, 1398 Object* object,
1243 JSObject* holder, 1399 JSObject* holder,
1244 JSGlobalPropertyCell* cell, 1400 JSGlobalPropertyCell* cell,
1245 JSFunction* function, 1401 JSFunction* function,
1246 String* fname) { 1402 String* fname) {
1247 ASSERT(generator_id >= 0 && generator_id < kNumCallGenerators); 1403 ASSERT(generator_id >= 0 && generator_id < kNumCallGenerators);
1248 switch (generator_id) { 1404 switch (generator_id) {
1249 #define CALL_GENERATOR_CASE(ignored1, ignored2, name) \ 1405 #define CALL_GENERATOR_CASE(ignored1, ignored2, name) \
1250 case k##name##CallGenerator: \ 1406 case k##name##CallGenerator: \
1251 return CallStubCompiler::Compile##name##Call(object, \ 1407 return CallStubCompiler::Compile##name##Call(object, \
1252 holder, \ 1408 holder, \
1253 cell, \ 1409 cell, \
1254 function, \ 1410 function, \
1255 fname); 1411 fname);
1256 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) 1412 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE)
1257 #undef CALL_GENERATOR_CASE 1413 #undef CALL_GENERATOR_CASE
1258 } 1414 }
1259 UNREACHABLE(); 1415 UNREACHABLE();
1260 return Heap::undefined_value(); 1416 return Heap::undefined_value();
1261 } 1417 }
1262 1418
1263 1419
1264 Object* CallStubCompiler::GetCode(PropertyType type, String* name) { 1420 MaybeObject* CallStubCompiler::GetCode(PropertyType type, String* name) {
1265 int argc = arguments_.immediate(); 1421 int argc = arguments_.immediate();
1266 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, 1422 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_,
1267 type, 1423 type,
1268 cache_holder_, 1424 cache_holder_,
1269 in_loop_, 1425 in_loop_,
1270 argc); 1426 argc);
1271 return GetCodeWithFlags(flags, name); 1427 return GetCodeWithFlags(flags, name);
1272 } 1428 }
1273 1429
1274 1430
1275 Object* CallStubCompiler::GetCode(JSFunction* function) { 1431 MaybeObject* CallStubCompiler::GetCode(JSFunction* function) {
1276 String* function_name = NULL; 1432 String* function_name = NULL;
1277 if (function->shared()->name()->IsString()) { 1433 if (function->shared()->name()->IsString()) {
1278 function_name = String::cast(function->shared()->name()); 1434 function_name = String::cast(function->shared()->name());
1279 } 1435 }
1280 return GetCode(CONSTANT_FUNCTION, function_name); 1436 return GetCode(CONSTANT_FUNCTION, function_name);
1281 } 1437 }
1282 1438
1283 1439
1284 Object* ConstructStubCompiler::GetCode() { 1440 MaybeObject* ConstructStubCompiler::GetCode() {
1285 Code::Flags flags = Code::ComputeFlags(Code::STUB); 1441 Code::Flags flags = Code::ComputeFlags(Code::STUB);
1286 Object* result = GetCodeWithFlags(flags, "ConstructStub"); 1442 Object* result;
1287 if (!result->IsFailure()) { 1443 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "ConstructStub");
1288 Code* code = Code::cast(result); 1444 if (!maybe_result->ToObject(&result)) return maybe_result;
1289 USE(code);
1290 PROFILE(CodeCreateEvent(Logger::STUB_TAG, code, "ConstructStub"));
1291 } 1445 }
1446 Code* code = Code::cast(result);
1447 USE(code);
1448 PROFILE(CodeCreateEvent(Logger::STUB_TAG, code, "ConstructStub"));
1292 return result; 1449 return result;
1293 } 1450 }
1294 1451
1295 1452
1296 CallOptimization::CallOptimization(LookupResult* lookup) { 1453 CallOptimization::CallOptimization(LookupResult* lookup) {
1297 if (!lookup->IsProperty() || !lookup->IsCacheable() || 1454 if (!lookup->IsProperty() || !lookup->IsCacheable() ||
1298 lookup->type() != CONSTANT_FUNCTION) { 1455 lookup->type() != CONSTANT_FUNCTION) {
1299 Initialize(NULL); 1456 Initialize(NULL);
1300 } else { 1457 } else {
1301 // We only optimize constant function calls. 1458 // We only optimize constant function calls.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1354 expected_receiver_type_ = 1511 expected_receiver_type_ =
1355 FunctionTemplateInfo::cast(signature->receiver()); 1512 FunctionTemplateInfo::cast(signature->receiver());
1356 } 1513 }
1357 } 1514 }
1358 1515
1359 is_simple_api_call_ = true; 1516 is_simple_api_call_ = true;
1360 } 1517 }
1361 1518
1362 1519
1363 } } // namespace v8::internal 1520 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | src/top.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698