OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 *secondary = *primary; | 102 *secondary = *primary; |
103 } | 103 } |
104 | 104 |
105 // Update primary cache. | 105 // Update primary cache. |
106 primary->key = name; | 106 primary->key = name; |
107 primary->value = code; | 107 primary->value = code; |
108 return code; | 108 return code; |
109 } | 109 } |
110 | 110 |
111 | 111 |
112 MaybeObject* StubCache::ComputeLoadNonexistent(String* name, | 112 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name, |
113 JSObject* receiver) { | 113 Handle<JSObject> receiver) { |
114 ASSERT(receiver->IsGlobalObject() || receiver->HasFastProperties()); | 114 ASSERT(receiver->IsGlobalObject() || receiver->HasFastProperties()); |
115 // If no global objects are present in the prototype chain, the load | 115 // If no global objects are present in the prototype chain, the load |
116 // nonexistent IC stub can be shared for all names for a given map | 116 // nonexistent IC stub can be shared for all names for a given map |
117 // and we use the empty string for the map cache in that case. If | 117 // and we use the empty string for the map cache in that case. If |
118 // there are global objects involved, we need to check global | 118 // there are global objects involved, we need to check global |
119 // property cells in the stub and therefore the stub will be | 119 // property cells in the stub and therefore the stub will be |
120 // specific to the name. | 120 // specific to the name. |
121 String* cache_name = heap()->empty_string(); | 121 Handle<String> cache_name = factory()->empty_string(); |
122 if (receiver->IsGlobalObject()) cache_name = name; | 122 if (receiver->IsGlobalObject()) cache_name = name; |
123 JSObject* last = receiver; | 123 Handle<JSObject> last = receiver; |
124 while (last->GetPrototype() != heap()->null_value()) { | 124 while (last->GetPrototype() != heap()->null_value()) { |
125 last = JSObject::cast(last->GetPrototype()); | 125 last = Handle<JSObject>(JSObject::cast(last->GetPrototype())); |
126 if (last->IsGlobalObject()) cache_name = name; | 126 if (last->IsGlobalObject()) cache_name = name; |
127 } | 127 } |
128 // Compile the stub that is either shared for all names or | 128 // Compile the stub that is either shared for all names or |
129 // name specific if there are global objects involved. | 129 // name specific if there are global objects involved. |
130 Code::Flags flags = | 130 Code::Flags flags = |
131 Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT); | 131 Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT); |
132 Object* code = receiver->map()->FindInCodeCache(cache_name, flags); | 132 Handle<Object> probe(receiver->map()->FindInCodeCache(*cache_name, flags)); |
133 if (code->IsUndefined()) { | 133 if (probe->IsCode()) return Handle<Code>::cast(probe); |
134 LoadStubCompiler compiler; | 134 |
135 { MaybeObject* maybe_code = | 135 LoadStubCompiler compiler(isolate_); |
136 compiler.CompileLoadNonexistent(cache_name, receiver, last); | 136 Handle<Code> code = |
137 if (!maybe_code->ToObject(&code)) return maybe_code; | 137 compiler.CompileLoadNonexistent(cache_name, receiver, last); |
138 } | 138 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *cache_name)); |
139 PROFILE(isolate_, | 139 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *cache_name, *code)); |
140 CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), cache_name)); | 140 JSObject::UpdateMapCodeCache(receiver, cache_name, code); |
141 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, cache_name, Code::cast(code))); | 141 return code; |
142 Object* result; | 142 } |
143 { MaybeObject* maybe_result = | 143 |
144 receiver->UpdateMapCodeCache(cache_name, Code::cast(code)); | 144 |
145 if (!maybe_result->ToObject(&result)) return maybe_result; | 145 Handle<Code> StubCache::ComputeLoadField(Handle<String> name, |
146 } | 146 Handle<JSObject> receiver, |
147 } | 147 Handle<JSObject> holder, |
148 return code; | |
149 } | |
150 | |
151 | |
152 MaybeObject* StubCache::ComputeLoadField(String* name, | |
153 JSObject* receiver, | |
154 JSObject* holder, | |
155 int field_index) { | 148 int field_index) { |
156 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | 149 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); |
157 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD); | 150 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD); |
158 Object* code = receiver->map()->FindInCodeCache(name, flags); | 151 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
159 if (code->IsUndefined()) { | 152 if (probe->IsCode()) return Handle<Code>::cast(probe); |
160 LoadStubCompiler compiler; | 153 |
161 { MaybeObject* maybe_code = | 154 LoadStubCompiler compiler(isolate_); |
162 compiler.CompileLoadField(receiver, holder, field_index, name); | 155 Handle<Code> code = |
163 if (!maybe_code->ToObject(&code)) return maybe_code; | 156 compiler.CompileLoadField(receiver, holder, field_index, name); |
164 } | 157 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
165 PROFILE(isolate_, | 158 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
166 CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); | 159 JSObject::UpdateMapCodeCache(receiver, name, code); |
167 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, name, Code::cast(code))); | 160 return code; |
168 Object* result; | 161 } |
169 { MaybeObject* maybe_result = | 162 |
170 receiver->UpdateMapCodeCache(name, Code::cast(code)); | 163 |
171 if (!maybe_result->ToObject(&result)) return maybe_result; | 164 Handle<Code> LoadStubCompiler::CompileLoadCallback( |
172 } | 165 Handle<String> name, |
173 } | 166 Handle<JSObject> object, |
174 return code; | 167 Handle<JSObject> holder, |
175 } | 168 Handle<AccessorInfo> callback) { |
176 | 169 CALL_HEAP_FUNCTION(isolate(), |
177 | 170 (set_failure(NULL), |
178 MaybeObject* StubCache::ComputeLoadCallback(String* name, | 171 CompileLoadCallback(*name, *object, *holder, *callback)), |
179 JSObject* receiver, | 172 Code); |
180 JSObject* holder, | 173 } |
181 AccessorInfo* callback) { | 174 |
| 175 |
| 176 Handle<Code> StubCache::ComputeLoadCallback(Handle<String> name, |
| 177 Handle<JSObject> receiver, |
| 178 Handle<JSObject> holder, |
| 179 Handle<AccessorInfo> callback) { |
182 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); | 180 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); |
183 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | 181 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); |
184 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS); | 182 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS); |
185 Object* code = receiver->map()->FindInCodeCache(name, flags); | 183 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
186 if (code->IsUndefined()) { | 184 if (probe->IsCode()) return Handle<Code>::cast(probe); |
187 LoadStubCompiler compiler; | 185 |
188 { MaybeObject* maybe_code = | 186 LoadStubCompiler compiler(isolate_); |
189 compiler.CompileLoadCallback(name, receiver, holder, callback); | 187 Handle<Code> code = |
190 if (!maybe_code->ToObject(&code)) return maybe_code; | 188 compiler.CompileLoadCallback(name, receiver, holder, callback); |
191 } | 189 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
192 PROFILE(isolate_, | 190 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
193 CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); | 191 JSObject::UpdateMapCodeCache(receiver, name, code); |
194 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, name, Code::cast(code))); | 192 return code; |
195 Object* result; | 193 } |
196 { MaybeObject* maybe_result = | 194 |
197 receiver->UpdateMapCodeCache(name, Code::cast(code)); | 195 |
198 if (!maybe_result->ToObject(&result)) return maybe_result; | 196 Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name, |
199 } | 197 Handle<JSObject> receiver, |
200 } | 198 Handle<JSObject> holder, |
201 return code; | 199 Handle<Object> value) { |
202 } | 200 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); |
203 | |
204 | |
205 MaybeObject* StubCache::ComputeLoadConstant(String* name, | |
206 JSObject* receiver, | |
207 JSObject* holder, | |
208 Object* value) { | |
209 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | |
210 Code::Flags flags = | 201 Code::Flags flags = |
211 Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION); | 202 Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION); |
212 Object* code = receiver->map()->FindInCodeCache(name, flags); | 203 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
213 if (code->IsUndefined()) { | 204 if (probe->IsCode()) return Handle<Code>::cast(probe); |
214 LoadStubCompiler compiler; | 205 |
215 { MaybeObject* maybe_code = | 206 LoadStubCompiler compiler(isolate_); |
216 compiler.CompileLoadConstant(receiver, holder, value, name); | 207 Handle<Code> code = |
217 if (!maybe_code->ToObject(&code)) return maybe_code; | 208 compiler.CompileLoadConstant(receiver, holder, value, name); |
218 } | 209 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
219 PROFILE(isolate_, | 210 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
220 CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); | 211 JSObject::UpdateMapCodeCache(receiver, name, code); |
221 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, name, Code::cast(code))); | 212 return code; |
222 Object* result; | 213 } |
223 { MaybeObject* maybe_result = | 214 |
224 receiver->UpdateMapCodeCache(name, Code::cast(code)); | 215 |
225 if (!maybe_result->ToObject(&result)) return maybe_result; | 216 Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> object, |
226 } | 217 Handle<JSObject> holder, |
227 } | 218 Handle<String> name) { |
228 return code; | 219 CALL_HEAP_FUNCTION(isolate(), |
229 } | 220 (set_failure(NULL), |
230 | 221 CompileLoadInterceptor(*object, *holder, *name)), |
231 | 222 Code); |
232 MaybeObject* StubCache::ComputeLoadInterceptor(String* name, | 223 } |
233 JSObject* receiver, | 224 |
234 JSObject* holder) { | 225 |
235 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | 226 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name, |
| 227 Handle<JSObject> receiver, |
| 228 Handle<JSObject> holder) { |
| 229 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); |
236 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR); | 230 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR); |
237 Object* code = receiver->map()->FindInCodeCache(name, flags); | 231 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
238 if (code->IsUndefined()) { | 232 if (probe->IsCode()) return Handle<Code>::cast(probe); |
239 LoadStubCompiler compiler; | 233 |
240 { MaybeObject* maybe_code = | 234 LoadStubCompiler compiler(isolate_); |
241 compiler.CompileLoadInterceptor(receiver, holder, name); | 235 Handle<Code> code = |
242 if (!maybe_code->ToObject(&code)) return maybe_code; | 236 compiler.CompileLoadInterceptor(receiver, holder, name); |
243 } | 237 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
244 PROFILE(isolate_, | 238 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
245 CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); | 239 JSObject::UpdateMapCodeCache(receiver, name, code); |
246 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, name, Code::cast(code))); | 240 return code; |
247 Object* result; | 241 } |
248 { MaybeObject* maybe_result = | 242 |
249 receiver->UpdateMapCodeCache(name, Code::cast(code)); | 243 |
250 if (!maybe_result->ToObject(&result)) return maybe_result; | 244 Handle<Code> StubCache::ComputeLoadNormal() { |
251 } | 245 return isolate_->builtins()->LoadIC_Normal(); |
252 } | 246 } |
253 return code; | 247 |
254 } | 248 |
255 | 249 Handle<Code> StubCache::ComputeLoadGlobal(Handle<String> name, |
256 | 250 Handle<JSObject> receiver, |
257 MaybeObject* StubCache::ComputeLoadNormal() { | 251 Handle<GlobalObject> holder, |
258 return isolate_->builtins()->builtin(Builtins::kLoadIC_Normal); | 252 Handle<JSGlobalPropertyCell> cell, |
259 } | |
260 | |
261 | |
262 MaybeObject* StubCache::ComputeLoadGlobal(String* name, | |
263 JSObject* receiver, | |
264 GlobalObject* holder, | |
265 JSGlobalPropertyCell* cell, | |
266 bool is_dont_delete) { | 253 bool is_dont_delete) { |
267 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | 254 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); |
268 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL); | 255 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL); |
269 Object* code = receiver->map()->FindInCodeCache(name, flags); | 256 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
270 if (code->IsUndefined()) { | 257 if (probe->IsCode()) return Handle<Code>::cast(probe); |
271 LoadStubCompiler compiler; | 258 |
272 { MaybeObject* maybe_code = compiler.CompileLoadGlobal(receiver, | 259 LoadStubCompiler compiler(isolate_); |
273 holder, | 260 Handle<Code> code = |
274 cell, | 261 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete); |
275 name, | 262 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
276 is_dont_delete); | 263 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
277 if (!maybe_code->ToObject(&code)) return maybe_code; | 264 JSObject::UpdateMapCodeCache(receiver, name, code); |
278 } | 265 return code; |
279 PROFILE(isolate_, | 266 } |
280 CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); | 267 |
281 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, name, Code::cast(code))); | 268 |
282 Object* result; | 269 Handle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name, |
283 { MaybeObject* maybe_result = | 270 Handle<JSObject> receiver, |
284 receiver->UpdateMapCodeCache(name, Code::cast(code)); | 271 Handle<JSObject> holder, |
285 if (!maybe_result->ToObject(&result)) return maybe_result; | |
286 } | |
287 } | |
288 return code; | |
289 } | |
290 | |
291 | |
292 MaybeObject* StubCache::ComputeKeyedLoadField(String* name, | |
293 JSObject* receiver, | |
294 JSObject* holder, | |
295 int field_index) { | 272 int field_index) { |
296 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | 273 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); |
297 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD); | 274 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD); |
298 Object* code = receiver->map()->FindInCodeCache(name, flags); | 275 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
299 if (code->IsUndefined()) { | 276 if (probe->IsCode()) return Handle<Code>::cast(probe); |
300 KeyedLoadStubCompiler compiler; | 277 |
301 { MaybeObject* maybe_code = | 278 KeyedLoadStubCompiler compiler(isolate_); |
302 compiler.CompileLoadField(name, receiver, holder, field_index); | 279 Handle<Code> code = |
303 if (!maybe_code->ToObject(&code)) return maybe_code; | 280 compiler.CompileLoadField(name, receiver, holder, field_index); |
304 } | 281 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); |
305 PROFILE(isolate_, | 282 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); |
306 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); | 283 JSObject::UpdateMapCodeCache(receiver, name, code); |
307 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name, Code::cast(code))); | 284 return code; |
308 Object* result; | 285 } |
309 { MaybeObject* maybe_result = | 286 |
310 receiver->UpdateMapCodeCache(name, Code::cast(code)); | 287 |
311 if (!maybe_result->ToObject(&result)) return maybe_result; | 288 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name, |
312 } | 289 Handle<JSObject> receiver, |
313 } | 290 Handle<JSObject> holder, |
314 return code; | 291 Handle<Object> value) { |
315 } | 292 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); |
316 | |
317 | |
318 MaybeObject* StubCache::ComputeKeyedLoadConstant(String* name, | |
319 JSObject* receiver, | |
320 JSObject* holder, | |
321 Object* value) { | |
322 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | |
323 Code::Flags flags = | 293 Code::Flags flags = |
324 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION); | 294 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION); |
325 Object* code = receiver->map()->FindInCodeCache(name, flags); | 295 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
326 if (code->IsUndefined()) { | 296 if (probe->IsCode()) return Handle<Code>::cast(probe); |
327 KeyedLoadStubCompiler compiler; | 297 |
328 { MaybeObject* maybe_code = | 298 KeyedLoadStubCompiler compiler(isolate_); |
329 compiler.CompileLoadConstant(name, receiver, holder, value); | 299 Handle<Code> code = |
330 if (!maybe_code->ToObject(&code)) return maybe_code; | 300 compiler.CompileLoadConstant(name, receiver, holder, value); |
331 } | 301 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); |
332 PROFILE(isolate_, | 302 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); |
333 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); | 303 JSObject::UpdateMapCodeCache(receiver, name, code); |
334 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name, Code::cast(code))); | 304 return code; |
335 Object* result; | 305 } |
336 { MaybeObject* maybe_result = | 306 |
337 receiver->UpdateMapCodeCache(name, Code::cast(code)); | 307 |
338 if (!maybe_result->ToObject(&result)) return maybe_result; | 308 Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor( |
339 } | 309 Handle<JSObject> object, |
340 } | 310 Handle<JSObject> holder, |
341 return code; | 311 Handle<String> name) { |
342 } | 312 CALL_HEAP_FUNCTION(isolate(), |
343 | 313 (set_failure(NULL), |
344 | 314 CompileLoadInterceptor(*object, *holder, *name)), |
345 MaybeObject* StubCache::ComputeKeyedLoadInterceptor(String* name, | 315 Code); |
346 JSObject* receiver, | 316 } |
347 JSObject* holder) { | 317 |
348 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | 318 |
| 319 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name, |
| 320 Handle<JSObject> receiver, |
| 321 Handle<JSObject> holder) { |
| 322 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); |
349 Code::Flags flags = | 323 Code::Flags flags = |
350 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR); | 324 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR); |
351 Object* code = receiver->map()->FindInCodeCache(name, flags); | 325 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
352 if (code->IsUndefined()) { | 326 if (probe->IsCode()) return Handle<Code>::cast(probe); |
353 KeyedLoadStubCompiler compiler; | 327 |
354 { MaybeObject* maybe_code = | 328 KeyedLoadStubCompiler compiler(isolate_); |
355 compiler.CompileLoadInterceptor(receiver, holder, name); | 329 Handle<Code> code = compiler.CompileLoadInterceptor(receiver, holder, name); |
356 if (!maybe_code->ToObject(&code)) return maybe_code; | 330 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); |
357 } | 331 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); |
358 PROFILE(isolate_, | 332 JSObject::UpdateMapCodeCache(receiver, name, code); |
359 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); | 333 return code; |
360 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name, Code::cast(code))); | 334 } |
361 Object* result; | 335 |
362 { MaybeObject* maybe_result = | 336 |
363 receiver->UpdateMapCodeCache(name, Code::cast(code)); | 337 Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback( |
364 if (!maybe_result->ToObject(&result)) return maybe_result; | 338 Handle<String> name, |
365 } | 339 Handle<JSObject> object, |
366 } | 340 Handle<JSObject> holder, |
367 return code; | 341 Handle<AccessorInfo> callback) { |
368 } | 342 CALL_HEAP_FUNCTION(isolate(), |
369 | 343 (set_failure(NULL), |
370 | 344 CompileLoadCallback(*name, *object, *holder, *callback)), |
371 MaybeObject* StubCache::ComputeKeyedLoadCallback(String* name, | 345 Code); |
372 JSObject* receiver, | 346 } |
373 JSObject* holder, | 347 |
374 AccessorInfo* callback) { | 348 |
375 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | 349 Handle<Code> StubCache::ComputeKeyedLoadCallback( |
| 350 Handle<String> name, |
| 351 Handle<JSObject> receiver, |
| 352 Handle<JSObject> holder, |
| 353 Handle<AccessorInfo> callback) { |
| 354 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); |
376 Code::Flags flags = | 355 Code::Flags flags = |
377 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); | 356 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); |
378 Object* code = receiver->map()->FindInCodeCache(name, flags); | 357 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
379 if (code->IsUndefined()) { | 358 if (probe->IsCode()) return Handle<Code>::cast(probe); |
380 KeyedLoadStubCompiler compiler; | 359 |
381 { MaybeObject* maybe_code = | 360 KeyedLoadStubCompiler compiler(isolate_); |
382 compiler.CompileLoadCallback(name, receiver, holder, callback); | 361 Handle<Code> code = |
383 if (!maybe_code->ToObject(&code)) return maybe_code; | 362 compiler.CompileLoadCallback(name, receiver, holder, callback); |
384 } | 363 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); |
385 PROFILE(isolate_, | 364 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); |
386 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); | 365 JSObject::UpdateMapCodeCache(receiver, name, code); |
387 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name, Code::cast(code))); | 366 return code; |
388 Object* result; | 367 } |
389 { MaybeObject* maybe_result = | 368 |
390 receiver->UpdateMapCodeCache(name, Code::cast(code)); | 369 |
391 if (!maybe_result->ToObject(&result)) return maybe_result; | 370 Handle<Code> StubCache::ComputeKeyedLoadArrayLength(Handle<String> name, |
392 } | 371 Handle<JSArray> receiver) { |
393 } | |
394 return code; | |
395 } | |
396 | |
397 | |
398 | |
399 MaybeObject* StubCache::ComputeKeyedLoadArrayLength(String* name, | |
400 JSArray* receiver) { | |
401 Code::Flags flags = | 372 Code::Flags flags = |
402 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); | 373 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); |
403 ASSERT(receiver->IsJSObject()); | 374 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
404 Object* code = receiver->map()->FindInCodeCache(name, flags); | 375 if (probe->IsCode()) return Handle<Code>::cast(probe); |
405 if (code->IsUndefined()) { | 376 |
406 KeyedLoadStubCompiler compiler; | 377 KeyedLoadStubCompiler compiler(isolate_); |
407 { MaybeObject* maybe_code = compiler.CompileLoadArrayLength(name); | 378 Handle<Code> code = compiler.CompileLoadArrayLength(name); |
408 if (!maybe_code->ToObject(&code)) return maybe_code; | 379 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); |
409 } | 380 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); |
410 PROFILE(isolate_, | 381 JSObject::UpdateMapCodeCache(receiver, name, code); |
411 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); | 382 return code; |
412 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name, Code::cast(code))); | 383 } |
413 Object* result; | 384 |
414 { MaybeObject* maybe_result = | 385 |
415 receiver->UpdateMapCodeCache(name, Code::cast(code)); | 386 Handle<Code> StubCache::ComputeKeyedLoadStringLength(Handle<String> name, |
416 if (!maybe_result->ToObject(&result)) return maybe_result; | 387 Handle<String> receiver) { |
417 } | |
418 } | |
419 return code; | |
420 } | |
421 | |
422 | |
423 MaybeObject* StubCache::ComputeKeyedLoadStringLength(String* name, | |
424 String* receiver) { | |
425 Code::Flags flags = | 388 Code::Flags flags = |
426 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); | 389 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); |
427 Map* map = receiver->map(); | 390 Handle<Map> map(receiver->map()); |
428 Object* code = map->FindInCodeCache(name, flags); | 391 Handle<Object> probe(map->FindInCodeCache(*name, flags)); |
429 if (code->IsUndefined()) { | 392 if (probe->IsCode()) return Handle<Code>::cast(probe); |
430 KeyedLoadStubCompiler compiler; | 393 |
431 { MaybeObject* maybe_code = compiler.CompileLoadStringLength(name); | 394 KeyedLoadStubCompiler compiler(isolate_); |
432 if (!maybe_code->ToObject(&code)) return maybe_code; | 395 Handle<Code> code = compiler.CompileLoadStringLength(name); |
433 } | 396 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); |
434 PROFILE(isolate_, | 397 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); |
435 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); | 398 Map::UpdateCodeCache(map, name, code); |
436 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name, Code::cast(code))); | 399 return code; |
437 Object* result; | 400 } |
438 { MaybeObject* maybe_result = map->UpdateCodeCache(name, Code::cast(code)); | 401 |
439 if (!maybe_result->ToObject(&result)) return maybe_result; | 402 |
440 } | 403 Handle<Code> StubCache::ComputeKeyedLoadFunctionPrototype( |
441 } | 404 Handle<String> name, |
442 return code; | 405 Handle<JSFunction> receiver) { |
443 } | |
444 | |
445 | |
446 MaybeObject* StubCache::ComputeKeyedLoadFunctionPrototype( | |
447 String* name, | |
448 JSFunction* receiver) { | |
449 Code::Flags flags = | 406 Code::Flags flags = |
450 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); | 407 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); |
451 Object* code = receiver->map()->FindInCodeCache(name, flags); | 408 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
452 if (code->IsUndefined()) { | 409 if (probe->IsCode()) return Handle<Code>::cast(probe); |
453 KeyedLoadStubCompiler compiler; | 410 |
454 { MaybeObject* maybe_code = compiler.CompileLoadFunctionPrototype(name); | 411 KeyedLoadStubCompiler compiler(isolate_); |
455 if (!maybe_code->ToObject(&code)) return maybe_code; | 412 Handle<Code> code = compiler.CompileLoadFunctionPrototype(name); |
456 } | 413 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); |
457 PROFILE(isolate_, | 414 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); |
458 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); | 415 JSObject::UpdateMapCodeCache(receiver, name, code); |
459 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name, Code::cast(code))); | 416 return code; |
460 Object* result; | 417 } |
461 { MaybeObject* maybe_result = | 418 |
462 receiver->UpdateMapCodeCache(name, Code::cast(code)); | 419 |
463 if (!maybe_result->ToObject(&result)) return maybe_result; | 420 Handle<Code> StubCache::ComputeStoreField(Handle<String> name, |
464 } | 421 Handle<JSObject> receiver, |
465 } | |
466 return code; | |
467 } | |
468 | |
469 | |
470 MaybeObject* StubCache::ComputeStoreField(String* name, | |
471 JSObject* receiver, | |
472 int field_index, | 422 int field_index, |
473 Map* transition, | 423 Handle<Map> transition, |
474 StrictModeFlag strict_mode) { | 424 StrictModeFlag strict_mode) { |
475 PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION; | 425 PropertyType type = (transition.is_null()) ? FIELD : MAP_TRANSITION; |
476 Code::Flags flags = Code::ComputeMonomorphicFlags( | 426 Code::Flags flags = Code::ComputeMonomorphicFlags( |
477 Code::STORE_IC, type, strict_mode); | 427 Code::STORE_IC, type, strict_mode); |
478 Object* code = receiver->map()->FindInCodeCache(name, flags); | 428 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
479 if (code->IsUndefined()) { | 429 if (probe->IsCode()) return Handle<Code>::cast(probe); |
480 StoreStubCompiler compiler(strict_mode); | 430 |
481 { MaybeObject* maybe_code = | 431 StoreStubCompiler compiler(isolate_, strict_mode); |
482 compiler.CompileStoreField(receiver, field_index, transition, name); | 432 Handle<Code> code = |
483 if (!maybe_code->ToObject(&code)) return maybe_code; | 433 compiler.CompileStoreField(receiver, field_index, transition, name); |
484 } | 434 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); |
485 PROFILE(isolate_, | 435 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); |
486 CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); | 436 JSObject::UpdateMapCodeCache(receiver, name, code); |
487 GDBJIT(AddCode(GDBJITInterface::STORE_IC, name, Code::cast(code))); | 437 return code; |
488 Object* result; | 438 } |
489 { MaybeObject* maybe_result = | 439 |
490 receiver->UpdateMapCodeCache(name, Code::cast(code)); | 440 |
491 if (!maybe_result->ToObject(&result)) return maybe_result; | 441 Handle<Code> StubCache::ComputeKeyedLoadOrStoreElement( |
492 } | 442 Handle<JSObject> receiver, |
493 } | |
494 return code; | |
495 } | |
496 | |
497 | |
498 MaybeObject* StubCache::ComputeKeyedLoadOrStoreElement( | |
499 JSObject* receiver, | |
500 KeyedIC::StubKind stub_kind, | 443 KeyedIC::StubKind stub_kind, |
501 StrictModeFlag strict_mode) { | 444 StrictModeFlag strict_mode) { |
502 Code::Flags flags = | 445 Code::Flags flags = |
503 Code::ComputeMonomorphicFlags( | 446 Code::ComputeMonomorphicFlags( |
504 stub_kind == KeyedIC::LOAD ? Code::KEYED_LOAD_IC | 447 stub_kind == KeyedIC::LOAD ? Code::KEYED_LOAD_IC |
505 : Code::KEYED_STORE_IC, | 448 : Code::KEYED_STORE_IC, |
506 NORMAL, | 449 NORMAL, |
507 strict_mode); | 450 strict_mode); |
508 String* name = NULL; | 451 Handle<String> name; |
509 switch (stub_kind) { | 452 switch (stub_kind) { |
510 case KeyedIC::LOAD: | 453 case KeyedIC::LOAD: |
511 name = isolate()->heap()->KeyedLoadElementMonomorphic_symbol(); | 454 name = isolate()->factory()->KeyedLoadElementMonomorphic_symbol(); |
512 break; | 455 break; |
513 case KeyedIC::STORE_NO_TRANSITION: | 456 case KeyedIC::STORE_NO_TRANSITION: |
514 name = isolate()->heap()->KeyedStoreElementMonomorphic_symbol(); | 457 name = isolate()->factory()->KeyedStoreElementMonomorphic_symbol(); |
515 break; | 458 break; |
516 default: | 459 default: |
517 UNREACHABLE(); | 460 UNREACHABLE(); |
518 break; | 461 break; |
519 } | 462 } |
520 Object* maybe_code = receiver->map()->FindInCodeCache(name, flags); | 463 Handle<Map> receiver_map(receiver->map()); |
521 if (!maybe_code->IsUndefined()) return Code::cast(maybe_code); | 464 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags)); |
| 465 if (probe->IsCode()) return Handle<Code>::cast(probe); |
522 | 466 |
523 Map* receiver_map = receiver->map(); | 467 Handle<Code> code; |
524 MaybeObject* maybe_new_code = NULL; | |
525 switch (stub_kind) { | 468 switch (stub_kind) { |
526 case KeyedIC::LOAD: { | 469 case KeyedIC::LOAD: { |
527 KeyedLoadStubCompiler compiler; | 470 KeyedLoadStubCompiler compiler(isolate_); |
528 maybe_new_code = compiler.CompileLoadElement(receiver_map); | 471 code = compiler.CompileLoadElement(receiver_map); |
529 break; | 472 break; |
530 } | 473 } |
531 case KeyedIC::STORE_NO_TRANSITION: { | 474 case KeyedIC::STORE_NO_TRANSITION: { |
532 KeyedStoreStubCompiler compiler(strict_mode); | 475 KeyedStoreStubCompiler compiler(isolate_, strict_mode); |
533 maybe_new_code = compiler.CompileStoreElement(receiver_map); | 476 code = compiler.CompileStoreElement(receiver_map); |
534 break; | 477 break; |
535 } | 478 } |
536 default: | 479 default: |
537 UNREACHABLE(); | 480 UNREACHABLE(); |
538 break; | 481 break; |
539 } | 482 } |
540 Code* code = NULL; | 483 |
541 if (!maybe_new_code->To(&code)) return maybe_new_code; | 484 ASSERT(!code.is_null()); |
542 | 485 |
543 if (stub_kind == KeyedIC::LOAD) { | 486 if (stub_kind == KeyedIC::LOAD) { |
544 PROFILE(isolate_, | 487 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, 0)); |
545 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, | |
546 Code::cast(code), 0)); | |
547 } else { | 488 } else { |
548 PROFILE(isolate_, | 489 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, 0)); |
549 CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, | |
550 Code::cast(code), 0)); | |
551 } | 490 } |
552 ASSERT(code->IsCode()); | 491 JSObject::UpdateMapCodeCache(receiver, name, code); |
553 Object* result; | |
554 { MaybeObject* maybe_result = | |
555 receiver->UpdateMapCodeCache(name, Code::cast(code)); | |
556 if (!maybe_result->ToObject(&result)) return maybe_result; | |
557 } | |
558 return code; | 492 return code; |
559 } | 493 } |
560 | 494 |
561 | 495 |
562 MaybeObject* StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) { | 496 Handle<Code> StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) { |
563 return isolate_->builtins()->builtin((strict_mode == kStrictMode) | 497 return (strict_mode == kStrictMode) |
564 ? Builtins::kStoreIC_Normal_Strict | 498 ? isolate_->builtins()->Builtins::StoreIC_Normal_Strict() |
565 : Builtins::kStoreIC_Normal); | 499 : isolate_->builtins()->Builtins::StoreIC_Normal(); |
566 } | 500 } |
567 | 501 |
568 | 502 |
569 MaybeObject* StubCache::ComputeStoreGlobal(String* name, | 503 Handle<Code> StubCache::ComputeStoreGlobal(Handle<String> name, |
570 GlobalObject* receiver, | 504 Handle<GlobalObject> receiver, |
571 JSGlobalPropertyCell* cell, | 505 Handle<JSGlobalPropertyCell> cell, |
572 StrictModeFlag strict_mode) { | 506 StrictModeFlag strict_mode) { |
573 Code::Flags flags = Code::ComputeMonomorphicFlags( | 507 Code::Flags flags = Code::ComputeMonomorphicFlags( |
574 Code::STORE_IC, NORMAL, strict_mode); | 508 Code::STORE_IC, NORMAL, strict_mode); |
575 Object* code = receiver->map()->FindInCodeCache(name, flags); | 509 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
576 if (code->IsUndefined()) { | 510 if (probe->IsCode()) return Handle<Code>::cast(probe); |
577 StoreStubCompiler compiler(strict_mode); | 511 |
578 { MaybeObject* maybe_code = | 512 StoreStubCompiler compiler(isolate_, strict_mode); |
579 compiler.CompileStoreGlobal(receiver, cell, name); | 513 Handle<Code> code = compiler.CompileStoreGlobal(receiver, cell, name); |
580 if (!maybe_code->ToObject(&code)) return maybe_code; | 514 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); |
581 } | 515 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); |
582 PROFILE(isolate_, | 516 JSObject::UpdateMapCodeCache(receiver, name, code); |
583 CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); | |
584 GDBJIT(AddCode(GDBJITInterface::STORE_IC, name, Code::cast(code))); | |
585 Object* result; | |
586 { MaybeObject* maybe_result = | |
587 receiver->UpdateMapCodeCache(name, Code::cast(code)); | |
588 if (!maybe_result->ToObject(&result)) return maybe_result; | |
589 } | |
590 } | |
591 return code; | 517 return code; |
592 } | 518 } |
593 | 519 |
594 | 520 |
595 MaybeObject* StubCache::ComputeStoreCallback( | 521 Handle<Code> StubCache::ComputeStoreCallback(Handle<String> name, |
596 String* name, | 522 Handle<JSObject> receiver, |
597 JSObject* receiver, | 523 Handle<AccessorInfo> callback, |
598 AccessorInfo* callback, | 524 StrictModeFlag strict_mode) { |
599 StrictModeFlag strict_mode) { | |
600 ASSERT(v8::ToCData<Address>(callback->setter()) != 0); | 525 ASSERT(v8::ToCData<Address>(callback->setter()) != 0); |
601 Code::Flags flags = Code::ComputeMonomorphicFlags( | 526 Code::Flags flags = Code::ComputeMonomorphicFlags( |
602 Code::STORE_IC, CALLBACKS, strict_mode); | 527 Code::STORE_IC, CALLBACKS, strict_mode); |
603 Object* code = receiver->map()->FindInCodeCache(name, flags); | 528 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
604 if (code->IsUndefined()) { | 529 if (probe->IsCode()) return Handle<Code>::cast(probe); |
605 StoreStubCompiler compiler(strict_mode); | 530 |
606 { MaybeObject* maybe_code = | 531 StoreStubCompiler compiler(isolate_, strict_mode); |
607 compiler.CompileStoreCallback(receiver, callback, name); | 532 Handle<Code> code = compiler.CompileStoreCallback(receiver, callback, name); |
608 if (!maybe_code->ToObject(&code)) return maybe_code; | 533 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); |
609 } | 534 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); |
610 PROFILE(isolate_, | 535 JSObject::UpdateMapCodeCache(receiver, name, code); |
611 CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); | |
612 GDBJIT(AddCode(GDBJITInterface::STORE_IC, name, Code::cast(code))); | |
613 Object* result; | |
614 { MaybeObject* maybe_result = | |
615 receiver->UpdateMapCodeCache(name, Code::cast(code)); | |
616 if (!maybe_result->ToObject(&result)) return maybe_result; | |
617 } | |
618 } | |
619 return code; | 536 return code; |
620 } | 537 } |
621 | 538 |
622 | 539 |
623 MaybeObject* StubCache::ComputeStoreInterceptor( | 540 Handle<Code> StubCache::ComputeStoreInterceptor(Handle<String> name, |
624 String* name, | 541 Handle<JSObject> receiver, |
625 JSObject* receiver, | 542 StrictModeFlag strict_mode) { |
626 StrictModeFlag strict_mode) { | |
627 Code::Flags flags = Code::ComputeMonomorphicFlags( | 543 Code::Flags flags = Code::ComputeMonomorphicFlags( |
628 Code::STORE_IC, INTERCEPTOR, strict_mode); | 544 Code::STORE_IC, INTERCEPTOR, strict_mode); |
629 Object* code = receiver->map()->FindInCodeCache(name, flags); | 545 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
630 if (code->IsUndefined()) { | 546 if (probe->IsCode()) return Handle<Code>::cast(probe); |
631 StoreStubCompiler compiler(strict_mode); | 547 |
632 { MaybeObject* maybe_code = | 548 StoreStubCompiler compiler(isolate_, strict_mode); |
633 compiler.CompileStoreInterceptor(receiver, name); | 549 Handle<Code> code = compiler.CompileStoreInterceptor(receiver, name); |
634 if (!maybe_code->ToObject(&code)) return maybe_code; | 550 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); |
635 } | 551 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); |
636 PROFILE(isolate_, | 552 JSObject::UpdateMapCodeCache(receiver, name, code); |
637 CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); | 553 return code; |
638 GDBJIT(AddCode(GDBJITInterface::STORE_IC, name, Code::cast(code))); | 554 } |
639 Object* result; | 555 |
640 { MaybeObject* maybe_result = | 556 Handle<Code> StubCache::ComputeKeyedStoreField(Handle<String> name, |
641 receiver->UpdateMapCodeCache(name, Code::cast(code)); | 557 Handle<JSObject> receiver, |
642 if (!maybe_result->ToObject(&result)) return maybe_result; | 558 int field_index, |
643 } | 559 Handle<Map> transition, |
644 } | 560 StrictModeFlag strict_mode) { |
| 561 PropertyType type = (transition.is_null()) ? FIELD : MAP_TRANSITION; |
| 562 Code::Flags flags = Code::ComputeMonomorphicFlags( |
| 563 Code::KEYED_STORE_IC, type, strict_mode); |
| 564 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); |
| 565 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 566 |
| 567 KeyedStoreStubCompiler compiler(isolate(), strict_mode); |
| 568 Handle<Code> code = |
| 569 compiler.CompileStoreField(receiver, field_index, transition, name); |
| 570 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name)); |
| 571 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code)); |
| 572 JSObject::UpdateMapCodeCache(receiver, name, code); |
645 return code; | 573 return code; |
646 } | 574 } |
647 | 575 |
648 | 576 |
649 MaybeObject* StubCache::ComputeKeyedStoreField(String* name, | |
650 JSObject* receiver, | |
651 int field_index, | |
652 Map* transition, | |
653 StrictModeFlag strict_mode) { | |
654 PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION; | |
655 Code::Flags flags = Code::ComputeMonomorphicFlags( | |
656 Code::KEYED_STORE_IC, type, strict_mode); | |
657 Object* code = receiver->map()->FindInCodeCache(name, flags); | |
658 if (code->IsUndefined()) { | |
659 KeyedStoreStubCompiler compiler(strict_mode); | |
660 { MaybeObject* maybe_code = | |
661 compiler.CompileStoreField(receiver, field_index, transition, name); | |
662 if (!maybe_code->ToObject(&code)) return maybe_code; | |
663 } | |
664 PROFILE(isolate(), | |
665 CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, | |
666 Code::cast(code), name)); | |
667 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, name, Code::cast(code))); | |
668 Object* result; | |
669 { MaybeObject* maybe_result = | |
670 receiver->UpdateMapCodeCache(name, Code::cast(code)); | |
671 if (!maybe_result->ToObject(&result)) return maybe_result; | |
672 } | |
673 } | |
674 return code; | |
675 } | |
676 | |
677 #define CALL_LOGGER_TAG(kind, type) \ | 577 #define CALL_LOGGER_TAG(kind, type) \ |
678 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) | 578 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) |
679 | 579 |
680 MaybeObject* StubCache::ComputeCallConstant(int argc, | 580 Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object, |
| 581 Handle<JSObject> holder, |
| 582 Handle<JSFunction> function, |
| 583 Handle<String> name, |
| 584 CheckType check) { |
| 585 CALL_HEAP_FUNCTION( |
| 586 isolate(), |
| 587 (set_failure(NULL), |
| 588 CompileCallConstant(*object, *holder, *function, *name, check)), |
| 589 Code); |
| 590 } |
| 591 |
| 592 |
| 593 Handle<Code> StubCache::ComputeCallConstant(int argc, |
681 Code::Kind kind, | 594 Code::Kind kind, |
682 Code::ExtraICState extra_ic_state, | 595 Code::ExtraICState extra_state, |
683 String* name, | 596 Handle<String> name, |
684 Object* object, | 597 Handle<Object> object, |
685 JSObject* holder, | 598 Handle<JSObject> holder, |
686 JSFunction* function) { | 599 Handle<JSFunction> function) { |
687 // Compute the check type and the map. | 600 // Compute the check type and the map. |
688 InlineCacheHolderFlag cache_holder = | 601 InlineCacheHolderFlag cache_holder = |
689 IC::GetCodeCacheForObject(object, holder); | 602 IC::GetCodeCacheForObject(*object, *holder); |
690 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); | 603 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); |
691 | 604 |
692 // Compute check type based on receiver/holder. | 605 // Compute check type based on receiver/holder. |
693 CheckType check = RECEIVER_MAP_CHECK; | 606 CheckType check = RECEIVER_MAP_CHECK; |
694 if (object->IsString()) { | 607 if (object->IsString()) { |
695 check = STRING_CHECK; | 608 check = STRING_CHECK; |
696 } else if (object->IsNumber()) { | 609 } else if (object->IsNumber()) { |
697 check = NUMBER_CHECK; | 610 check = NUMBER_CHECK; |
698 } else if (object->IsBoolean()) { | 611 } else if (object->IsBoolean()) { |
699 check = BOOLEAN_CHECK; | 612 check = BOOLEAN_CHECK; |
700 } | 613 } |
701 | 614 |
702 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, | 615 Code::Flags flags = |
703 CONSTANT_FUNCTION, | 616 Code::ComputeMonomorphicFlags(kind, CONSTANT_FUNCTION, extra_state, |
704 extra_ic_state, | 617 cache_holder, argc); |
705 cache_holder, | 618 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags)); |
706 argc); | 619 if (probe->IsCode()) return Handle<Code>::cast(probe); |
707 Object* code = map_holder->map()->FindInCodeCache(name, flags); | 620 |
708 if (code->IsUndefined()) { | 621 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); |
709 // If the function hasn't been compiled yet, we cannot do it now | 622 Handle<Code> code = |
710 // because it may cause GC. To avoid this issue, we return an | 623 compiler.CompileCallConstant(object, holder, function, name, check); |
711 // internal error which will make sure we do not update any | 624 code->set_check_type(check); |
712 // caches. | 625 ASSERT_EQ(flags, code->flags()); |
713 if (!function->is_compiled()) return Failure::InternalError(); | 626 PROFILE(isolate_, |
714 // Compile the stub - only create stubs for fully compiled functions. | 627 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
715 CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder); | 628 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); |
716 { MaybeObject* maybe_code = | 629 JSObject::UpdateMapCodeCache(map_holder, name, code); |
717 compiler.CompileCallConstant(object, holder, function, name, check); | |
718 if (!maybe_code->ToObject(&code)) return maybe_code; | |
719 } | |
720 Code::cast(code)->set_check_type(check); | |
721 ASSERT_EQ(flags, Code::cast(code)->flags()); | |
722 PROFILE(isolate_, | |
723 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | |
724 Code::cast(code), name)); | |
725 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); | |
726 Object* result; | |
727 { MaybeObject* maybe_result = | |
728 map_holder->UpdateMapCodeCache(name, Code::cast(code)); | |
729 if (!maybe_result->ToObject(&result)) return maybe_result; | |
730 } | |
731 } | |
732 return code; | 630 return code; |
733 } | 631 } |
734 | 632 |
735 | 633 |
736 MaybeObject* StubCache::ComputeCallField(int argc, | 634 Handle<Code> StubCache::ComputeCallField(int argc, |
737 Code::Kind kind, | 635 Code::Kind kind, |
738 Code::ExtraICState extra_ic_state, | 636 Code::ExtraICState extra_state, |
739 String* name, | 637 Handle<String> name, |
740 Object* object, | 638 Handle<Object> object, |
741 JSObject* holder, | 639 Handle<JSObject> holder, |
742 int index) { | 640 int index) { |
743 // Compute the check type and the map. | 641 // Compute the check type and the map. |
744 InlineCacheHolderFlag cache_holder = | 642 InlineCacheHolderFlag cache_holder = |
745 IC::GetCodeCacheForObject(object, holder); | 643 IC::GetCodeCacheForObject(*object, *holder); |
746 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); | 644 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); |
747 | 645 |
748 // TODO(1233596): We cannot do receiver map check for non-JS objects | 646 // TODO(1233596): We cannot do receiver map check for non-JS objects |
749 // because they may be represented as immediates without a | 647 // because they may be represented as immediates without a |
750 // map. Instead, we check against the map in the holder. | 648 // map. Instead, we check against the map in the holder. |
751 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { | 649 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { |
752 object = holder; | 650 object = holder; |
753 } | 651 } |
754 | 652 |
755 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, | 653 Code::Flags flags = |
756 FIELD, | 654 Code::ComputeMonomorphicFlags(kind, FIELD, extra_state, |
757 extra_ic_state, | 655 cache_holder, argc); |
758 cache_holder, | 656 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags)); |
759 argc); | 657 if (probe->IsCode()) return Handle<Code>::cast(probe); |
760 Object* code = map_holder->map()->FindInCodeCache(name, flags); | 658 |
761 if (code->IsUndefined()) { | 659 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); |
762 CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder); | 660 Handle<Code> code = |
763 { MaybeObject* maybe_code = | 661 compiler.CompileCallField(Handle<JSObject>::cast(object), |
764 compiler.CompileCallField(JSObject::cast(object), | 662 holder, index, name); |
765 holder, | 663 ASSERT_EQ(flags, code->flags()); |
766 index, | 664 PROFILE(isolate_, |
767 name); | 665 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
768 if (!maybe_code->ToObject(&code)) return maybe_code; | 666 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); |
769 } | 667 JSObject::UpdateMapCodeCache(map_holder, name, code); |
770 ASSERT_EQ(flags, Code::cast(code)->flags()); | |
771 PROFILE(isolate_, | |
772 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | |
773 Code::cast(code), name)); | |
774 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); | |
775 Object* result; | |
776 { MaybeObject* maybe_result = | |
777 map_holder->UpdateMapCodeCache(name, Code::cast(code)); | |
778 if (!maybe_result->ToObject(&result)) return maybe_result; | |
779 } | |
780 } | |
781 return code; | 668 return code; |
782 } | 669 } |
783 | 670 |
784 | 671 |
785 MaybeObject* StubCache::ComputeCallInterceptor( | 672 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, |
786 int argc, | 673 Handle<JSObject> holder, |
787 Code::Kind kind, | 674 Handle<String> name) { |
788 Code::ExtraICState extra_ic_state, | 675 CALL_HEAP_FUNCTION( |
789 String* name, | 676 isolate(), |
790 Object* object, | 677 (set_failure(NULL), CompileCallInterceptor(*object, *holder, *name)), |
791 JSObject* holder) { | 678 Code); |
| 679 } |
| 680 |
| 681 |
| 682 Handle<Code> StubCache::ComputeCallInterceptor(int argc, |
| 683 Code::Kind kind, |
| 684 Code::ExtraICState extra_state, |
| 685 Handle<String> name, |
| 686 Handle<Object> object, |
| 687 Handle<JSObject> holder) { |
792 // Compute the check type and the map. | 688 // Compute the check type and the map. |
793 InlineCacheHolderFlag cache_holder = | 689 InlineCacheHolderFlag cache_holder = |
794 IC::GetCodeCacheForObject(object, holder); | 690 IC::GetCodeCacheForObject(*object, *holder); |
795 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); | 691 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); |
796 | 692 |
797 // TODO(1233596): We cannot do receiver map check for non-JS objects | 693 // TODO(1233596): We cannot do receiver map check for non-JS objects |
798 // because they may be represented as immediates without a | 694 // because they may be represented as immediates without a |
799 // map. Instead, we check against the map in the holder. | 695 // map. Instead, we check against the map in the holder. |
800 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { | 696 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { |
801 object = holder; | 697 object = holder; |
802 } | 698 } |
803 | 699 |
804 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, | 700 Code::Flags flags = |
805 INTERCEPTOR, | 701 Code::ComputeMonomorphicFlags(kind, INTERCEPTOR, extra_state, |
806 extra_ic_state, | 702 cache_holder, argc); |
807 cache_holder, | 703 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags)); |
808 argc); | 704 if (probe->IsCode()) return Handle<Code>::cast(probe); |
809 Object* code = map_holder->map()->FindInCodeCache(name, flags); | 705 |
810 if (code->IsUndefined()) { | 706 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder); |
811 CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder); | 707 Handle<Code> code = |
812 { MaybeObject* maybe_code = | 708 compiler.CompileCallInterceptor(Handle<JSObject>::cast(object), |
813 compiler.CompileCallInterceptor(JSObject::cast(object), holder, name); | 709 holder, name); |
814 if (!maybe_code->ToObject(&code)) return maybe_code; | 710 ASSERT_EQ(flags, code->flags()); |
815 } | 711 PROFILE(isolate(), |
816 ASSERT_EQ(flags, Code::cast(code)->flags()); | 712 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
817 PROFILE(isolate(), | 713 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); |
818 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | 714 JSObject::UpdateMapCodeCache(map_holder, name, code); |
819 Code::cast(code), name)); | 715 return code; |
820 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); | 716 } |
821 Object* result; | 717 |
822 { MaybeObject* maybe_result = | 718 |
823 map_holder->UpdateMapCodeCache(name, Code::cast(code)); | 719 Handle<Code> CallStubCompiler::CompileCallGlobal( |
824 if (!maybe_result->ToObject(&result)) return maybe_result; | 720 Handle<JSObject> object, |
825 } | 721 Handle<GlobalObject> holder, |
826 } | 722 Handle<JSGlobalPropertyCell> cell, |
827 return code; | 723 Handle<JSFunction> function, |
828 } | 724 Handle<String> name) { |
829 | 725 CALL_HEAP_FUNCTION( |
830 | 726 isolate(), |
831 MaybeObject* StubCache::ComputeCallNormal(int argc, | 727 (set_failure(NULL), |
| 728 CompileCallGlobal(*object, *holder, *cell, *function, *name)), |
| 729 Code); |
| 730 } |
| 731 |
| 732 |
| 733 Handle<Code> StubCache::ComputeCallGlobal(int argc, |
832 Code::Kind kind, | 734 Code::Kind kind, |
833 Code::ExtraICState extra_ic_state, | 735 Code::ExtraICState extra_state, |
834 String* name, | 736 Handle<String> name, |
835 JSObject* receiver) { | 737 Handle<JSObject> receiver, |
836 Object* code; | 738 Handle<GlobalObject> holder, |
837 { MaybeObject* maybe_code = ComputeCallNormal(argc, kind, extra_ic_state); | 739 Handle<JSGlobalPropertyCell> cell, |
838 if (!maybe_code->ToObject(&code)) return maybe_code; | 740 Handle<JSFunction> function) { |
839 } | |
840 return code; | |
841 } | |
842 | |
843 | |
844 MaybeObject* StubCache::ComputeCallGlobal(int argc, | |
845 Code::Kind kind, | |
846 Code::ExtraICState extra_ic_state, | |
847 String* name, | |
848 JSObject* receiver, | |
849 GlobalObject* holder, | |
850 JSGlobalPropertyCell* cell, | |
851 JSFunction* function) { | |
852 InlineCacheHolderFlag cache_holder = | 741 InlineCacheHolderFlag cache_holder = |
853 IC::GetCodeCacheForObject(receiver, holder); | 742 IC::GetCodeCacheForObject(*receiver, *holder); |
854 JSObject* map_holder = IC::GetCodeCacheHolder(receiver, cache_holder); | 743 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); |
855 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, | 744 Code::Flags flags = |
856 NORMAL, | 745 Code::ComputeMonomorphicFlags(kind, NORMAL, extra_state, |
857 extra_ic_state, | 746 cache_holder, argc); |
858 cache_holder, | 747 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags)); |
859 argc); | 748 if (probe->IsCode()) return Handle<Code>::cast(probe); |
860 Object* code = map_holder->map()->FindInCodeCache(name, flags); | 749 |
861 if (code->IsUndefined()) { | 750 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder); |
862 // If the function hasn't been compiled yet, we cannot do it now | 751 Handle<Code> code = |
863 // because it may cause GC. To avoid this issue, we return an | 752 compiler.CompileCallGlobal(receiver, holder, cell, function, name); |
864 // internal error which will make sure we do not update any | 753 ASSERT_EQ(flags, code->flags()); |
865 // caches. | 754 PROFILE(isolate(), |
866 if (!function->is_compiled()) return Failure::InternalError(); | 755 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
867 CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder); | 756 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); |
868 { MaybeObject* maybe_code = | 757 JSObject::UpdateMapCodeCache(map_holder, name, code); |
869 compiler.CompileCallGlobal(receiver, holder, cell, function, name); | 758 return code; |
870 if (!maybe_code->ToObject(&code)) return maybe_code; | 759 } |
871 } | 760 |
872 ASSERT_EQ(flags, Code::cast(code)->flags()); | 761 |
873 PROFILE(isolate(), | 762 static void FillCache(Isolate* isolate, Handle<Code> code) { |
874 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | 763 Handle<NumberDictionary> dictionary = |
875 Code::cast(code), name)); | 764 NumberDictionarySet(isolate->factory()->non_monomorphic_cache(), |
876 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); | 765 code->flags(), |
877 Object* result; | 766 code, |
878 { MaybeObject* maybe_result = | 767 PropertyDetails(NONE, NORMAL)); |
879 map_holder->UpdateMapCodeCache(name, Code::cast(code)); | 768 isolate->heap()->public_set_non_monomorphic_cache(*dictionary); |
880 if (!maybe_result->ToObject(&result)) return maybe_result; | |
881 } | |
882 } | |
883 return code; | |
884 } | |
885 | |
886 | |
887 static Object* GetProbeValue(Isolate* isolate, Code::Flags flags) { | |
888 // Use raw_unchecked... so we don't get assert failures during GC. | |
889 NumberDictionary* dictionary = | |
890 isolate->heap()->raw_unchecked_non_monomorphic_cache(); | |
891 int entry = dictionary->FindEntry(isolate, flags); | |
892 if (entry != -1) return dictionary->ValueAt(entry); | |
893 return isolate->heap()->raw_unchecked_undefined_value(); | |
894 } | |
895 | |
896 | |
897 MUST_USE_RESULT static MaybeObject* ProbeCache(Isolate* isolate, | |
898 Code::Flags flags) { | |
899 Heap* heap = isolate->heap(); | |
900 Object* probe = GetProbeValue(isolate, flags); | |
901 if (probe != heap->undefined_value()) return probe; | |
902 // Seed the cache with an undefined value to make sure that any | |
903 // generated code object can always be inserted into the cache | |
904 // without causing allocation failures. | |
905 Object* result; | |
906 { MaybeObject* maybe_result = | |
907 heap->non_monomorphic_cache()->AtNumberPut(flags, | |
908 heap->undefined_value()); | |
909 if (!maybe_result->ToObject(&result)) return maybe_result; | |
910 } | |
911 heap->public_set_non_monomorphic_cache(NumberDictionary::cast(result)); | |
912 return probe; | |
913 } | |
914 | |
915 | |
916 static MaybeObject* FillCache(Isolate* isolate, MaybeObject* maybe_code) { | |
917 Object* code; | |
918 if (maybe_code->ToObject(&code)) { | |
919 if (code->IsCode()) { | |
920 Heap* heap = isolate->heap(); | |
921 int entry = heap->non_monomorphic_cache()->FindEntry( | |
922 Code::cast(code)->flags()); | |
923 // The entry must be present see comment in ProbeCache. | |
924 ASSERT(entry != -1); | |
925 ASSERT(heap->non_monomorphic_cache()->ValueAt(entry) == | |
926 heap->undefined_value()); | |
927 heap->non_monomorphic_cache()->ValueAtPut(entry, code); | |
928 CHECK(GetProbeValue(isolate, Code::cast(code)->flags()) == code); | |
929 } | |
930 } | |
931 return maybe_code; | |
932 } | 769 } |
933 | 770 |
934 | 771 |
935 Code* StubCache::FindCallInitialize(int argc, | 772 Code* StubCache::FindCallInitialize(int argc, |
936 RelocInfo::Mode mode, | 773 RelocInfo::Mode mode, |
937 Code::Kind kind) { | 774 Code::Kind kind) { |
938 Code::ExtraICState extra_state = | 775 Code::ExtraICState extra_state = |
939 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | | 776 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | |
940 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); | 777 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); |
941 Code::Flags flags = Code::ComputeFlags(kind, | 778 Code::Flags flags = |
942 UNINITIALIZED, | 779 Code::ComputeFlags(kind, UNINITIALIZED, extra_state, NORMAL, argc); |
943 extra_state, | 780 |
944 NORMAL, | 781 // Use raw_unchecked... so we don't get assert failures during GC. |
945 argc); | 782 NumberDictionary* dictionary = |
946 Object* result = ProbeCache(isolate(), flags)->ToObjectUnchecked(); | 783 isolate()->heap()->raw_unchecked_non_monomorphic_cache(); |
947 ASSERT(result != heap()->undefined_value()); | 784 int entry = dictionary->FindEntry(isolate(), flags); |
| 785 ASSERT(entry != -1); |
| 786 Object* code = dictionary->ValueAt(entry); |
948 // This might be called during the marking phase of the collector | 787 // This might be called during the marking phase of the collector |
949 // hence the unchecked cast. | 788 // hence the unchecked cast. |
950 return reinterpret_cast<Code*>(result); | 789 return reinterpret_cast<Code*>(code); |
951 } | 790 } |
952 | 791 |
953 | 792 |
954 MaybeObject* StubCache::ComputeCallInitialize(int argc, | 793 Handle<Code> StubCache::ComputeCallInitialize(int argc, |
955 RelocInfo::Mode mode, | 794 RelocInfo::Mode mode, |
956 Code::Kind kind) { | 795 Code::Kind kind) { |
957 Code::ExtraICState extra_state = | 796 Code::ExtraICState extra_state = |
958 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | | 797 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | |
959 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); | 798 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); |
960 Code::Flags flags = Code::ComputeFlags(kind, | 799 Code::Flags flags = |
961 UNINITIALIZED, | 800 Code::ComputeFlags(kind, UNINITIALIZED, extra_state, NORMAL, argc); |
962 extra_state, | 801 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache(); |
963 NORMAL, | 802 int entry = cache->FindEntry(isolate_, flags); |
964 argc); | 803 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
965 Object* probe; | 804 |
966 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 805 StubCompiler compiler(isolate_); |
967 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 806 Handle<Code> code = compiler.CompileCallInitialize(flags); |
968 } | 807 FillCache(isolate_, code); |
969 if (!probe->IsUndefined()) return probe; | 808 return code; |
970 StubCompiler compiler; | 809 } |
971 return FillCache(isolate_, compiler.CompileCallInitialize(flags)); | 810 |
972 } | 811 |
973 | 812 Handle<Code> StubCache::ComputeCallInitialize(int argc, RelocInfo::Mode mode) { |
974 | 813 return ComputeCallInitialize(argc, mode, Code::CALL_IC); |
975 Handle<Code> StubCache::ComputeCallInitialize(int argc, | |
976 RelocInfo::Mode mode) { | |
977 CALL_HEAP_FUNCTION(isolate_, | |
978 ComputeCallInitialize(argc, mode, Code::CALL_IC), | |
979 Code); | |
980 } | 814 } |
981 | 815 |
982 | 816 |
983 Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc) { | 817 Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc) { |
984 CALL_HEAP_FUNCTION( | 818 return ComputeCallInitialize(argc, RelocInfo::CODE_TARGET, |
985 isolate_, | 819 Code::KEYED_CALL_IC); |
986 ComputeCallInitialize(argc, RelocInfo::CODE_TARGET, Code::KEYED_CALL_IC), | 820 } |
987 Code); | 821 |
988 } | 822 |
989 | 823 Handle<Code> StubCache::ComputeCallPreMonomorphic( |
990 | |
991 MaybeObject* StubCache::ComputeCallPreMonomorphic( | |
992 int argc, | 824 int argc, |
993 Code::Kind kind, | 825 Code::Kind kind, |
994 Code::ExtraICState extra_ic_state) { | 826 Code::ExtraICState extra_state) { |
995 Code::Flags flags = Code::ComputeFlags(kind, | 827 Code::Flags flags = |
996 PREMONOMORPHIC, | 828 Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, NORMAL, argc); |
997 extra_ic_state, | 829 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache(); |
998 NORMAL, | 830 int entry = cache->FindEntry(isolate_, flags); |
999 argc); | 831 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
1000 Object* probe; | 832 |
1001 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 833 StubCompiler compiler(isolate_); |
1002 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 834 Handle<Code> code = compiler.CompileCallPreMonomorphic(flags); |
1003 } | 835 FillCache(isolate_, code); |
1004 if (!probe->IsUndefined()) return probe; | 836 return code; |
1005 StubCompiler compiler; | 837 } |
1006 return FillCache(isolate_, compiler.CompileCallPreMonomorphic(flags)); | 838 |
1007 } | 839 |
1008 | 840 Handle<Code> StubCache::ComputeCallNormal(int argc, |
1009 | |
1010 MaybeObject* StubCache::ComputeCallNormal(int argc, | |
1011 Code::Kind kind, | 841 Code::Kind kind, |
1012 Code::ExtraICState extra_ic_state) { | 842 Code::ExtraICState extra_state) { |
1013 Code::Flags flags = Code::ComputeFlags(kind, | 843 Code::Flags flags = |
1014 MONOMORPHIC, | 844 Code::ComputeFlags(kind, MONOMORPHIC, extra_state, NORMAL, argc); |
1015 extra_ic_state, | 845 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache(); |
1016 NORMAL, | 846 int entry = cache->FindEntry(isolate_, flags); |
1017 argc); | 847 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
1018 Object* probe; | 848 |
1019 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 849 StubCompiler compiler(isolate_); |
1020 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 850 Handle<Code> code = compiler.CompileCallNormal(flags); |
1021 } | 851 FillCache(isolate_, code); |
1022 if (!probe->IsUndefined()) return probe; | 852 return code; |
1023 StubCompiler compiler; | 853 } |
1024 return FillCache(isolate_, compiler.CompileCallNormal(flags)); | 854 |
1025 } | 855 |
1026 | 856 Handle<Code> StubCache::ComputeCallArguments(int argc, Code::Kind kind) { |
1027 | |
1028 MaybeObject* StubCache::ComputeCallArguments(int argc, Code::Kind kind) { | |
1029 ASSERT(kind == Code::KEYED_CALL_IC); | 857 ASSERT(kind == Code::KEYED_CALL_IC); |
1030 Code::Flags flags = Code::ComputeFlags(kind, | 858 Code::Flags flags = |
1031 MEGAMORPHIC, | 859 Code::ComputeFlags(kind, MEGAMORPHIC, Code::kNoExtraICState, |
1032 Code::kNoExtraICState, | 860 NORMAL, argc); |
1033 NORMAL, | 861 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache(); |
1034 argc); | 862 int entry = cache->FindEntry(isolate_, flags); |
1035 Object* probe; | 863 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
1036 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 864 |
1037 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 865 StubCompiler compiler(isolate_); |
1038 } | 866 Handle<Code> code = compiler.CompileCallArguments(flags); |
1039 if (!probe->IsUndefined()) return probe; | 867 FillCache(isolate_, code); |
1040 StubCompiler compiler; | 868 return code; |
1041 return FillCache(isolate_, compiler.CompileCallArguments(flags)); | 869 } |
1042 } | 870 |
1043 | 871 |
1044 | 872 Handle<Code> StubCache::ComputeCallMegamorphic( |
1045 MaybeObject* StubCache::ComputeCallMegamorphic( | |
1046 int argc, | 873 int argc, |
1047 Code::Kind kind, | 874 Code::Kind kind, |
1048 Code::ExtraICState extra_ic_state) { | 875 Code::ExtraICState extra_state) { |
1049 Code::Flags flags = Code::ComputeFlags(kind, | 876 Code::Flags flags = |
1050 MEGAMORPHIC, | 877 Code::ComputeFlags(kind, MEGAMORPHIC, extra_state, |
1051 extra_ic_state, | 878 NORMAL, argc); |
1052 NORMAL, | 879 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache(); |
1053 argc); | 880 int entry = cache->FindEntry(isolate_, flags); |
1054 Object* probe; | 881 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
1055 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 882 |
1056 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 883 StubCompiler compiler(isolate_); |
1057 } | 884 Handle<Code> code = compiler.CompileCallMegamorphic(flags); |
1058 if (!probe->IsUndefined()) return probe; | 885 FillCache(isolate_, code); |
1059 StubCompiler compiler; | 886 return code; |
1060 return FillCache(isolate_, compiler.CompileCallMegamorphic(flags)); | 887 } |
1061 } | 888 |
1062 | 889 |
1063 | 890 Handle<Code> StubCache::ComputeCallMiss(int argc, |
1064 MaybeObject* StubCache::ComputeCallMiss(int argc, | |
1065 Code::Kind kind, | 891 Code::Kind kind, |
1066 Code::ExtraICState extra_ic_state) { | 892 Code::ExtraICState extra_state) { |
1067 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs | 893 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs |
1068 // and monomorphic stubs are not mixed up together in the stub cache. | 894 // and monomorphic stubs are not mixed up together in the stub cache. |
1069 Code::Flags flags = Code::ComputeFlags(kind, | 895 Code::Flags flags = |
1070 MONOMORPHIC_PROTOTYPE_FAILURE, | 896 Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state, |
1071 extra_ic_state, | 897 NORMAL, argc, OWN_MAP); |
1072 NORMAL, | 898 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache(); |
1073 argc, | 899 int entry = cache->FindEntry(isolate_, flags); |
1074 OWN_MAP); | 900 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
1075 Object* probe; | 901 |
1076 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 902 StubCompiler compiler(isolate_); |
1077 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 903 Handle<Code> code = compiler.CompileCallMiss(flags); |
1078 } | 904 FillCache(isolate_, code); |
1079 if (!probe->IsUndefined()) return probe; | 905 return code; |
1080 StubCompiler compiler; | 906 } |
1081 return FillCache(isolate_, compiler.CompileCallMiss(flags)); | 907 |
| 908 |
| 909 // The CallStubCompiler needs a version of ComputeCallMiss that does not |
| 910 // perform GC. This function is temporary, because the stub cache but not |
| 911 // yet the stub compiler uses handles. |
| 912 MaybeObject* StubCache::TryComputeCallMiss(int argc, |
| 913 Code::Kind kind, |
| 914 Code::ExtraICState extra_state) { |
| 915 Code::Flags flags = |
| 916 Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state, |
| 917 NORMAL, argc, OWN_MAP); |
| 918 NumberDictionary* cache = isolate_->heap()->non_monomorphic_cache(); |
| 919 int entry = cache->FindEntry(isolate_, flags); |
| 920 if (entry != -1) return cache->ValueAt(entry); |
| 921 |
| 922 StubCompiler compiler(isolate_); |
| 923 Code* code = NULL; |
| 924 MaybeObject* maybe_code = compiler.TryCompileCallMiss(flags); |
| 925 if (!maybe_code->To(&code)) return maybe_code; |
| 926 |
| 927 NumberDictionary* new_cache = NULL; |
| 928 MaybeObject* maybe_new_cache = cache->AtNumberPut(flags, code); |
| 929 if (!maybe_new_cache->To(&new_cache)) return maybe_new_cache; |
| 930 isolate_->heap()->public_set_non_monomorphic_cache(new_cache); |
| 931 |
| 932 return code; |
1082 } | 933 } |
1083 | 934 |
1084 | 935 |
1085 #ifdef ENABLE_DEBUGGER_SUPPORT | 936 #ifdef ENABLE_DEBUGGER_SUPPORT |
1086 MaybeObject* StubCache::ComputeCallDebugBreak( | 937 Handle<Code> StubCache::ComputeCallDebugBreak(int argc, |
1087 int argc, | 938 Code::Kind kind) { |
1088 Code::Kind kind) { | |
1089 // Extra IC state is irrelevant for debug break ICs. They jump to | 939 // Extra IC state is irrelevant for debug break ICs. They jump to |
1090 // the actual call ic to carry out the work. | 940 // the actual call ic to carry out the work. |
1091 Code::Flags flags = Code::ComputeFlags(kind, | 941 Code::Flags flags = |
1092 DEBUG_BREAK, | 942 Code::ComputeFlags(kind, DEBUG_BREAK, Code::kNoExtraICState, |
1093 Code::kNoExtraICState, | 943 NORMAL, argc); |
1094 NORMAL, | 944 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache(); |
1095 argc); | 945 int entry = cache->FindEntry(isolate_, flags); |
1096 Object* probe; | 946 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
1097 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 947 |
1098 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 948 StubCompiler compiler(isolate_); |
1099 } | 949 Handle<Code> code = compiler.CompileCallDebugBreak(flags); |
1100 if (!probe->IsUndefined()) return probe; | 950 FillCache(isolate_, code); |
1101 StubCompiler compiler; | 951 return code; |
1102 return FillCache(isolate_, compiler.CompileCallDebugBreak(flags)); | 952 } |
1103 } | 953 |
1104 | 954 |
1105 | 955 Handle<Code> StubCache::ComputeCallDebugPrepareStepIn(int argc, |
1106 MaybeObject* StubCache::ComputeCallDebugPrepareStepIn( | 956 Code::Kind kind) { |
1107 int argc, | |
1108 Code::Kind kind) { | |
1109 // Extra IC state is irrelevant for debug break ICs. They jump to | 957 // Extra IC state is irrelevant for debug break ICs. They jump to |
1110 // the actual call ic to carry out the work. | 958 // the actual call ic to carry out the work. |
1111 Code::Flags flags = Code::ComputeFlags(kind, | 959 Code::Flags flags = |
1112 DEBUG_PREPARE_STEP_IN, | 960 Code::ComputeFlags(kind, DEBUG_PREPARE_STEP_IN, Code::kNoExtraICState, |
1113 Code::kNoExtraICState, | 961 NORMAL, argc); |
1114 NORMAL, | 962 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache(); |
1115 argc); | 963 int entry = cache->FindEntry(isolate_, flags); |
1116 Object* probe; | 964 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
1117 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); | 965 |
1118 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 966 StubCompiler compiler(isolate_); |
1119 } | 967 Handle<Code> code = compiler.CompileCallDebugPrepareStepIn(flags); |
1120 if (!probe->IsUndefined()) return probe; | 968 FillCache(isolate_, code); |
1121 StubCompiler compiler; | 969 return code; |
1122 return FillCache(isolate_, compiler.CompileCallDebugPrepareStepIn(flags)); | |
1123 } | 970 } |
1124 #endif | 971 #endif |
1125 | 972 |
1126 | 973 |
1127 void StubCache::Clear() { | 974 void StubCache::Clear() { |
1128 Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal); | 975 Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal); |
1129 for (int i = 0; i < kPrimaryTableSize; i++) { | 976 for (int i = 0; i < kPrimaryTableSize; i++) { |
1130 primary_[i].key = heap()->empty_string(); | 977 primary_[i].key = heap()->empty_string(); |
1131 primary_[i].value = empty; | 978 primary_[i].value = empty; |
1132 } | 979 } |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1377 | 1224 |
1378 | 1225 |
1379 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) { | 1226 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) { |
1380 JSObject* receiver = JSObject::cast(args[0]); | 1227 JSObject* receiver = JSObject::cast(args[0]); |
1381 ASSERT(args.smi_at(1) >= 0); | 1228 ASSERT(args.smi_at(1) >= 0); |
1382 uint32_t index = args.smi_at(1); | 1229 uint32_t index = args.smi_at(1); |
1383 return receiver->GetElementWithInterceptor(receiver, index); | 1230 return receiver->GetElementWithInterceptor(receiver, index); |
1384 } | 1231 } |
1385 | 1232 |
1386 | 1233 |
1387 MaybeObject* StubCompiler::CompileCallInitialize(Code::Flags flags) { | 1234 Handle<Code> StubCompiler::CompileCallInitialize(Code::Flags flags) { |
1388 HandleScope scope(isolate()); | |
1389 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1235 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1390 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1236 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
1391 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); | 1237 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); |
1392 if (kind == Code::CALL_IC) { | 1238 if (kind == Code::CALL_IC) { |
1393 CallIC::GenerateInitialize(masm(), argc, extra_ic_state); | 1239 CallIC::GenerateInitialize(masm(), argc, extra_state); |
1394 } else { | 1240 } else { |
1395 KeyedCallIC::GenerateInitialize(masm(), argc); | 1241 KeyedCallIC::GenerateInitialize(masm(), argc); |
1396 } | 1242 } |
1397 Object* result; | 1243 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallInitialize"); |
1398 { MaybeObject* maybe_result = | |
1399 GetCodeWithFlags(flags, "CompileCallInitialize"); | |
1400 if (!maybe_result->ToObject(&result)) return maybe_result; | |
1401 } | |
1402 isolate()->counters()->call_initialize_stubs()->Increment(); | 1244 isolate()->counters()->call_initialize_stubs()->Increment(); |
1403 Code* code = Code::cast(result); | |
1404 USE(code); | |
1405 PROFILE(isolate(), | 1245 PROFILE(isolate(), |
1406 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG), | 1246 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG), |
1407 code, code->arguments_count())); | 1247 *code, code->arguments_count())); |
1408 GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, Code::cast(code))); | 1248 GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, *code)); |
1409 return result; | 1249 return code; |
1410 } | 1250 } |
1411 | 1251 |
1412 | 1252 |
1413 MaybeObject* StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { | 1253 Handle<Code> StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { |
1414 HandleScope scope(isolate()); | |
1415 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1254 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1416 // The code of the PreMonomorphic stub is the same as the code | 1255 // The code of the PreMonomorphic stub is the same as the code |
1417 // of the Initialized stub. They just differ on the code object flags. | 1256 // of the Initialized stub. They just differ on the code object flags. |
1418 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1257 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
1419 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); | 1258 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); |
1420 if (kind == Code::CALL_IC) { | 1259 if (kind == Code::CALL_IC) { |
1421 CallIC::GenerateInitialize(masm(), argc, extra_ic_state); | 1260 CallIC::GenerateInitialize(masm(), argc, extra_state); |
1422 } else { | 1261 } else { |
1423 KeyedCallIC::GenerateInitialize(masm(), argc); | 1262 KeyedCallIC::GenerateInitialize(masm(), argc); |
1424 } | 1263 } |
1425 Object* result; | 1264 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); |
1426 { MaybeObject* maybe_result = | |
1427 GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); | |
1428 if (!maybe_result->ToObject(&result)) return maybe_result; | |
1429 } | |
1430 isolate()->counters()->call_premonomorphic_stubs()->Increment(); | 1265 isolate()->counters()->call_premonomorphic_stubs()->Increment(); |
1431 Code* code = Code::cast(result); | |
1432 USE(code); | |
1433 PROFILE(isolate(), | 1266 PROFILE(isolate(), |
1434 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG), | 1267 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG), |
1435 code, code->arguments_count())); | 1268 *code, code->arguments_count())); |
1436 GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, Code::cast(code))); | 1269 GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, *code)); |
1437 return result; | 1270 return code; |
1438 } | 1271 } |
1439 | 1272 |
1440 | 1273 |
1441 MaybeObject* StubCompiler::CompileCallNormal(Code::Flags flags) { | 1274 Handle<Code> StubCompiler::CompileCallNormal(Code::Flags flags) { |
1442 HandleScope scope(isolate()); | |
1443 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1275 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1444 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1276 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
1445 if (kind == Code::CALL_IC) { | 1277 if (kind == Code::CALL_IC) { |
1446 // Call normal is always with a explict receiver. | 1278 // Call normal is always with a explict receiver. |
1447 ASSERT(!CallIC::Contextual::decode( | 1279 ASSERT(!CallIC::Contextual::decode( |
1448 Code::ExtractExtraICStateFromFlags(flags))); | 1280 Code::ExtractExtraICStateFromFlags(flags))); |
1449 CallIC::GenerateNormal(masm(), argc); | 1281 CallIC::GenerateNormal(masm(), argc); |
1450 } else { | 1282 } else { |
1451 KeyedCallIC::GenerateNormal(masm(), argc); | 1283 KeyedCallIC::GenerateNormal(masm(), argc); |
1452 } | 1284 } |
1453 Object* result; | 1285 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallNormal"); |
1454 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallNormal"); | |
1455 if (!maybe_result->ToObject(&result)) return maybe_result; | |
1456 } | |
1457 isolate()->counters()->call_normal_stubs()->Increment(); | 1286 isolate()->counters()->call_normal_stubs()->Increment(); |
1458 Code* code = Code::cast(result); | |
1459 USE(code); | |
1460 PROFILE(isolate(), | 1287 PROFILE(isolate(), |
1461 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG), | 1288 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG), |
1462 code, code->arguments_count())); | 1289 *code, code->arguments_count())); |
1463 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, Code::cast(code))); | 1290 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, *code)); |
1464 return result; | 1291 return code; |
1465 } | 1292 } |
1466 | 1293 |
1467 | 1294 |
1468 MaybeObject* StubCompiler::CompileCallMegamorphic(Code::Flags flags) { | 1295 Handle<Code> StubCompiler::CompileCallMegamorphic(Code::Flags flags) { |
| 1296 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 1297 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1298 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); |
| 1299 if (kind == Code::CALL_IC) { |
| 1300 CallIC::GenerateMegamorphic(masm(), argc, extra_state); |
| 1301 } else { |
| 1302 KeyedCallIC::GenerateMegamorphic(masm(), argc); |
| 1303 } |
| 1304 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMegamorphic"); |
| 1305 isolate()->counters()->call_megamorphic_stubs()->Increment(); |
| 1306 PROFILE(isolate(), |
| 1307 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), |
| 1308 *code, code->arguments_count())); |
| 1309 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code)); |
| 1310 return code; |
| 1311 } |
| 1312 |
| 1313 |
| 1314 Handle<Code> StubCompiler::CompileCallArguments(Code::Flags flags) { |
| 1315 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 1316 KeyedCallIC::GenerateNonStrictArguments(masm(), argc); |
| 1317 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallArguments"); |
| 1318 PROFILE(isolate(), |
| 1319 CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags), |
| 1320 CALL_MEGAMORPHIC_TAG), |
| 1321 *code, code->arguments_count())); |
| 1322 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code)); |
| 1323 return code; |
| 1324 } |
| 1325 |
| 1326 |
| 1327 Handle<Code> StubCompiler::CompileCallMiss(Code::Flags flags) { |
| 1328 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 1329 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1330 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); |
| 1331 if (kind == Code::CALL_IC) { |
| 1332 CallIC::GenerateMiss(masm(), argc, extra_state); |
| 1333 } else { |
| 1334 KeyedCallIC::GenerateMiss(masm(), argc); |
| 1335 } |
| 1336 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMiss"); |
| 1337 isolate()->counters()->call_megamorphic_stubs()->Increment(); |
| 1338 PROFILE(isolate(), |
| 1339 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG), |
| 1340 *code, code->arguments_count())); |
| 1341 GDBJIT(AddCode(GDBJITInterface::CALL_MISS, *code)); |
| 1342 return code; |
| 1343 } |
| 1344 |
| 1345 |
| 1346 // TODO(kmillikin): This annoying raw pointer implementation should be |
| 1347 // eliminated when the stub compiler no longer needs it. |
| 1348 MaybeObject* StubCompiler::TryCompileCallMiss(Code::Flags flags) { |
1469 HandleScope scope(isolate()); | 1349 HandleScope scope(isolate()); |
1470 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1350 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1471 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1351 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
1472 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); | 1352 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); |
1473 if (kind == Code::CALL_IC) { | 1353 if (kind == Code::CALL_IC) { |
1474 CallIC::GenerateMegamorphic(masm(), argc, extra_ic_state); | 1354 CallIC::GenerateMiss(masm(), argc, extra_state); |
1475 } else { | |
1476 KeyedCallIC::GenerateMegamorphic(masm(), argc); | |
1477 } | |
1478 Object* result; | |
1479 { MaybeObject* maybe_result = | |
1480 GetCodeWithFlags(flags, "CompileCallMegamorphic"); | |
1481 if (!maybe_result->ToObject(&result)) return maybe_result; | |
1482 } | |
1483 isolate()->counters()->call_megamorphic_stubs()->Increment(); | |
1484 Code* code = Code::cast(result); | |
1485 USE(code); | |
1486 PROFILE(isolate(), | |
1487 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), | |
1488 code, code->arguments_count())); | |
1489 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, Code::cast(code))); | |
1490 return result; | |
1491 } | |
1492 | |
1493 | |
1494 MaybeObject* StubCompiler::CompileCallArguments(Code::Flags flags) { | |
1495 HandleScope scope(isolate()); | |
1496 int argc = Code::ExtractArgumentsCountFromFlags(flags); | |
1497 KeyedCallIC::GenerateNonStrictArguments(masm(), argc); | |
1498 Code::Kind kind = Code::ExtractKindFromFlags(flags); | |
1499 Object* result; | |
1500 { MaybeObject* maybe_result = | |
1501 GetCodeWithFlags(flags, "CompileCallArguments"); | |
1502 if (!maybe_result->ToObject(&result)) return maybe_result; | |
1503 } | |
1504 Code* code = Code::cast(result); | |
1505 USE(code); | |
1506 PROFILE(isolate(), | |
1507 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), | |
1508 code, code->arguments_count())); | |
1509 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, Code::cast(code))); | |
1510 return result; | |
1511 } | |
1512 | |
1513 | |
1514 MaybeObject* StubCompiler::CompileCallMiss(Code::Flags flags) { | |
1515 HandleScope scope(isolate()); | |
1516 int argc = Code::ExtractArgumentsCountFromFlags(flags); | |
1517 Code::Kind kind = Code::ExtractKindFromFlags(flags); | |
1518 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); | |
1519 if (kind == Code::CALL_IC) { | |
1520 CallIC::GenerateMiss(masm(), argc, extra_ic_state); | |
1521 } else { | 1355 } else { |
1522 KeyedCallIC::GenerateMiss(masm(), argc); | 1356 KeyedCallIC::GenerateMiss(masm(), argc); |
1523 } | 1357 } |
1524 Object* result; | 1358 Object* result; |
1525 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallMiss"); | 1359 { MaybeObject* maybe_result = TryGetCodeWithFlags(flags, "CompileCallMiss"); |
1526 if (!maybe_result->ToObject(&result)) return maybe_result; | 1360 if (!maybe_result->ToObject(&result)) return maybe_result; |
1527 } | 1361 } |
1528 isolate()->counters()->call_megamorphic_stubs()->Increment(); | 1362 isolate()->counters()->call_megamorphic_stubs()->Increment(); |
1529 Code* code = Code::cast(result); | 1363 Code* code = Code::cast(result); |
1530 USE(code); | 1364 USE(code); |
1531 PROFILE(isolate(), | 1365 PROFILE(isolate(), |
1532 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG), | 1366 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG), |
1533 code, code->arguments_count())); | 1367 code, code->arguments_count())); |
1534 GDBJIT(AddCode(GDBJITInterface::CALL_MISS, Code::cast(code))); | 1368 GDBJIT(AddCode(GDBJITInterface::CALL_MISS, Code::cast(code))); |
1535 return result; | 1369 return result; |
1536 } | 1370 } |
1537 | 1371 |
1538 | 1372 |
1539 #ifdef ENABLE_DEBUGGER_SUPPORT | 1373 #ifdef ENABLE_DEBUGGER_SUPPORT |
1540 MaybeObject* StubCompiler::CompileCallDebugBreak(Code::Flags flags) { | 1374 Handle<Code> StubCompiler::CompileCallDebugBreak(Code::Flags flags) { |
1541 HandleScope scope(isolate()); | |
1542 Debug::GenerateCallICDebugBreak(masm()); | 1375 Debug::GenerateCallICDebugBreak(masm()); |
1543 Object* result; | 1376 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugBreak"); |
1544 { MaybeObject* maybe_result = | |
1545 GetCodeWithFlags(flags, "CompileCallDebugBreak"); | |
1546 if (!maybe_result->ToObject(&result)) return maybe_result; | |
1547 } | |
1548 Code* code = Code::cast(result); | |
1549 USE(code); | |
1550 Code::Kind kind = Code::ExtractKindFromFlags(flags); | |
1551 USE(kind); | |
1552 PROFILE(isolate(), | 1377 PROFILE(isolate(), |
1553 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_DEBUG_BREAK_TAG), | 1378 CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags), |
1554 code, code->arguments_count())); | 1379 CALL_DEBUG_BREAK_TAG), |
1555 return result; | 1380 *code, code->arguments_count())); |
| 1381 return code; |
1556 } | 1382 } |
1557 | 1383 |
1558 | 1384 |
1559 MaybeObject* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { | 1385 Handle<Code> StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { |
1560 HandleScope scope(isolate()); | 1386 // Use the same code for the the step in preparations as we do for the |
1561 // Use the same code for the the step in preparations as we do for | 1387 // miss case. |
1562 // the miss case. | |
1563 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1388 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
1564 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1389 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
1565 if (kind == Code::CALL_IC) { | 1390 if (kind == Code::CALL_IC) { |
1566 // For the debugger extra ic state is irrelevant. | 1391 // For the debugger extra ic state is irrelevant. |
1567 CallIC::GenerateMiss(masm(), argc, Code::kNoExtraICState); | 1392 CallIC::GenerateMiss(masm(), argc, Code::kNoExtraICState); |
1568 } else { | 1393 } else { |
1569 KeyedCallIC::GenerateMiss(masm(), argc); | 1394 KeyedCallIC::GenerateMiss(masm(), argc); |
1570 } | 1395 } |
1571 Object* result; | 1396 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn"); |
1572 { MaybeObject* maybe_result = | |
1573 GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn"); | |
1574 if (!maybe_result->ToObject(&result)) return maybe_result; | |
1575 } | |
1576 Code* code = Code::cast(result); | |
1577 USE(code); | |
1578 PROFILE(isolate(), | 1397 PROFILE(isolate(), |
1579 CodeCreateEvent( | 1398 CodeCreateEvent( |
1580 CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG), | 1399 CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG), |
1581 code, | 1400 *code, |
1582 code->arguments_count())); | 1401 code->arguments_count())); |
1583 return result; | 1402 return code; |
1584 } | 1403 } |
1585 #endif | 1404 #endif // ENABLE_DEBUGGER_SUPPORT |
1586 | 1405 |
1587 #undef CALL_LOGGER_TAG | 1406 #undef CALL_LOGGER_TAG |
1588 | 1407 |
1589 MaybeObject* StubCompiler::GetCodeWithFlags(Code::Flags flags, | 1408 |
| 1409 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, |
1590 const char* name) { | 1410 const char* name) { |
| 1411 // Create code object in the heap. |
| 1412 CodeDesc desc; |
| 1413 masm_.GetCode(&desc); |
| 1414 Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject()); |
| 1415 #ifdef ENABLE_DISASSEMBLER |
| 1416 if (FLAG_print_code_stubs) code->Disassemble(name); |
| 1417 #endif |
| 1418 return code; |
| 1419 } |
| 1420 |
| 1421 |
| 1422 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, |
| 1423 Handle<String> name) { |
| 1424 return (FLAG_print_code_stubs && !name.is_null()) |
| 1425 ? GetCodeWithFlags(flags, *name->ToCString()) |
| 1426 : GetCodeWithFlags(flags, reinterpret_cast<char*>(NULL)); |
| 1427 } |
| 1428 |
| 1429 |
| 1430 MaybeObject* StubCompiler::TryGetCodeWithFlags(Code::Flags flags, |
| 1431 const char* name) { |
1591 // Check for allocation failures during stub compilation. | 1432 // Check for allocation failures during stub compilation. |
1592 if (failure_->IsFailure()) return failure_; | 1433 if (failure_->IsFailure()) return failure_; |
1593 | 1434 |
1594 // Create code object in the heap. | 1435 // Create code object in the heap. |
1595 CodeDesc desc; | 1436 CodeDesc desc; |
1596 masm_.GetCode(&desc); | 1437 masm_.GetCode(&desc); |
1597 MaybeObject* result = heap()->CreateCode(desc, flags, masm_.CodeObject()); | 1438 MaybeObject* result = heap()->CreateCode(desc, flags, masm_.CodeObject()); |
1598 #ifdef ENABLE_DISASSEMBLER | 1439 #ifdef ENABLE_DISASSEMBLER |
1599 if (FLAG_print_code_stubs && !result->IsFailure()) { | 1440 if (FLAG_print_code_stubs && !result->IsFailure()) { |
1600 Code::cast(result->ToObjectUnchecked())->Disassemble(name); | 1441 Code::cast(result->ToObjectUnchecked())->Disassemble(name); |
1601 } | 1442 } |
1602 #endif | 1443 #endif |
1603 return result; | 1444 return result; |
1604 } | 1445 } |
1605 | 1446 |
1606 | 1447 |
1607 MaybeObject* StubCompiler::GetCodeWithFlags(Code::Flags flags, String* name) { | 1448 MaybeObject* StubCompiler::TryGetCodeWithFlags(Code::Flags flags, |
1608 if (FLAG_print_code_stubs && (name != NULL)) { | 1449 String* name) { |
1609 return GetCodeWithFlags(flags, *name->ToCString()); | 1450 if (FLAG_print_code_stubs && name != NULL) { |
| 1451 return TryGetCodeWithFlags(flags, *name->ToCString()); |
1610 } | 1452 } |
1611 return GetCodeWithFlags(flags, reinterpret_cast<char*>(NULL)); | 1453 return TryGetCodeWithFlags(flags, reinterpret_cast<char*>(NULL)); |
1612 } | 1454 } |
1613 | 1455 |
1614 | 1456 |
1615 void StubCompiler::LookupPostInterceptor(JSObject* holder, | 1457 void StubCompiler::LookupPostInterceptor(JSObject* holder, |
1616 String* name, | 1458 String* name, |
1617 LookupResult* lookup) { | 1459 LookupResult* lookup) { |
1618 holder->LocalLookupRealNamedProperty(name, lookup); | 1460 holder->LocalLookupRealNamedProperty(name, lookup); |
1619 if (!lookup->IsProperty()) { | 1461 if (!lookup->IsProperty()) { |
1620 lookup->NotFound(); | 1462 lookup->NotFound(); |
1621 Object* proto = holder->GetPrototype(); | 1463 Object* proto = holder->GetPrototype(); |
1622 if (!proto->IsNull()) { | 1464 if (!proto->IsNull()) { |
1623 proto->Lookup(name, lookup); | 1465 proto->Lookup(name, lookup); |
1624 } | 1466 } |
1625 } | 1467 } |
1626 } | 1468 } |
1627 | 1469 |
1628 | 1470 |
| 1471 Handle<Code> LoadStubCompiler::GetCode(PropertyType type, Handle<String> name) { |
| 1472 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type); |
| 1473 Handle<Code> code = GetCodeWithFlags(flags, name); |
| 1474 PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
| 1475 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
| 1476 return code; |
| 1477 } |
1629 | 1478 |
1630 MaybeObject* LoadStubCompiler::GetCode(PropertyType type, String* name) { | 1479 |
| 1480 // TODO(ulan): Eliminate this function when the stub cache is fully |
| 1481 // handlified. |
| 1482 MaybeObject* LoadStubCompiler::TryGetCode(PropertyType type, String* name) { |
1631 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type); | 1483 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type); |
1632 MaybeObject* result = GetCodeWithFlags(flags, name); | 1484 MaybeObject* result = TryGetCodeWithFlags(flags, name); |
1633 if (!result->IsFailure()) { | 1485 if (!result->IsFailure()) { |
1634 PROFILE(isolate(), | 1486 PROFILE(isolate(), |
1635 CodeCreateEvent(Logger::LOAD_IC_TAG, | 1487 CodeCreateEvent(Logger::LOAD_IC_TAG, |
1636 Code::cast(result->ToObjectUnchecked()), | 1488 Code::cast(result->ToObjectUnchecked()), |
1637 name)); | 1489 name)); |
1638 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, | 1490 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, |
1639 name, | 1491 name, |
1640 Code::cast(result->ToObjectUnchecked()))); | 1492 Code::cast(result->ToObjectUnchecked()))); |
1641 } | 1493 } |
1642 return result; | 1494 return result; |
1643 } | 1495 } |
1644 | 1496 |
1645 | 1497 |
1646 MaybeObject* KeyedLoadStubCompiler::GetCode(PropertyType type, | 1498 Handle<Code> KeyedLoadStubCompiler::GetCode(PropertyType type, |
| 1499 Handle<String> name, |
| 1500 InlineCacheState state) { |
| 1501 Code::Flags flags = Code::ComputeFlags( |
| 1502 Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type); |
| 1503 Handle<Code> code = GetCodeWithFlags(flags, name); |
| 1504 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); |
| 1505 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
| 1506 return code; |
| 1507 } |
| 1508 |
| 1509 // TODO(ulan): Eliminate this function when the stub cache is fully |
| 1510 // handlified. |
| 1511 MaybeObject* KeyedLoadStubCompiler::TryGetCode(PropertyType type, |
1647 String* name, | 1512 String* name, |
1648 InlineCacheState state) { | 1513 InlineCacheState state) { |
1649 Code::Flags flags = Code::ComputeFlags( | 1514 Code::Flags flags = Code::ComputeFlags( |
1650 Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type); | 1515 Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type); |
1651 MaybeObject* result = GetCodeWithFlags(flags, name); | 1516 MaybeObject* result = TryGetCodeWithFlags(flags, name); |
1652 if (!result->IsFailure()) { | 1517 if (!result->IsFailure()) { |
1653 PROFILE(isolate(), | 1518 PROFILE(isolate(), |
1654 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, | 1519 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, |
1655 Code::cast(result->ToObjectUnchecked()), | 1520 Code::cast(result->ToObjectUnchecked()), |
1656 name)); | 1521 name)); |
1657 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, | 1522 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, |
1658 name, | 1523 name, |
1659 Code::cast(result->ToObjectUnchecked()))); | 1524 Code::cast(result->ToObjectUnchecked()))); |
1660 } | 1525 } |
1661 return result; | 1526 return result; |
1662 } | 1527 } |
1663 | 1528 |
1664 | 1529 |
1665 MaybeObject* StoreStubCompiler::GetCode(PropertyType type, String* name) { | 1530 Handle<Code> StoreStubCompiler::GetCode(PropertyType type, |
| 1531 Handle<String> name) { |
1666 Code::Flags flags = | 1532 Code::Flags flags = |
1667 Code::ComputeMonomorphicFlags(Code::STORE_IC, type, strict_mode_); | 1533 Code::ComputeMonomorphicFlags(Code::STORE_IC, type, strict_mode_); |
1668 MaybeObject* result = GetCodeWithFlags(flags, name); | 1534 Handle<Code> code = GetCodeWithFlags(flags, name); |
1669 if (!result->IsFailure()) { | 1535 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); |
1670 PROFILE(isolate(), | 1536 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); |
1671 CodeCreateEvent(Logger::STORE_IC_TAG, | 1537 return code; |
1672 Code::cast(result->ToObjectUnchecked()), | |
1673 name)); | |
1674 GDBJIT(AddCode(GDBJITInterface::STORE_IC, | |
1675 name, | |
1676 Code::cast(result->ToObjectUnchecked()))); | |
1677 } | |
1678 return result; | |
1679 } | 1538 } |
1680 | 1539 |
1681 | 1540 |
1682 MaybeObject* KeyedStoreStubCompiler::GetCode(PropertyType type, | 1541 Handle<Code> KeyedStoreStubCompiler::GetCode(PropertyType type, |
1683 String* name, | 1542 Handle<String> name, |
1684 InlineCacheState state) { | 1543 InlineCacheState state) { |
1685 Code::Flags flags = | 1544 Code::Flags flags = |
1686 Code::ComputeFlags(Code::KEYED_STORE_IC, state, strict_mode_, type); | 1545 Code::ComputeFlags(Code::KEYED_STORE_IC, state, strict_mode_, type); |
1687 MaybeObject* result = GetCodeWithFlags(flags, name); | 1546 Handle<Code> code = GetCodeWithFlags(flags, name); |
1688 if (!result->IsFailure()) { | 1547 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name)); |
1689 PROFILE(isolate(), | 1548 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code)); |
1690 CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, | 1549 return code; |
1691 Code::cast(result->ToObjectUnchecked()), | |
1692 name)); | |
1693 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, | |
1694 name, | |
1695 Code::cast(result->ToObjectUnchecked()))); | |
1696 } | |
1697 return result; | |
1698 } | 1550 } |
1699 | 1551 |
1700 | 1552 |
1701 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement( | 1553 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement( |
1702 MacroAssembler* masm) { | 1554 MacroAssembler* masm) { |
1703 KeyedStoreIC::GenerateSlow(masm); | 1555 KeyedStoreIC::GenerateSlow(masm); |
1704 } | 1556 } |
1705 | 1557 |
1706 | 1558 |
1707 CallStubCompiler::CallStubCompiler(int argc, | 1559 CallStubCompiler::CallStubCompiler(Isolate* isolate, |
| 1560 int argc, |
1708 Code::Kind kind, | 1561 Code::Kind kind, |
1709 Code::ExtraICState extra_ic_state, | 1562 Code::ExtraICState extra_state, |
1710 InlineCacheHolderFlag cache_holder) | 1563 InlineCacheHolderFlag cache_holder) |
1711 : arguments_(argc), | 1564 : StubCompiler(isolate), |
| 1565 arguments_(argc), |
1712 kind_(kind), | 1566 kind_(kind), |
1713 extra_ic_state_(extra_ic_state), | 1567 extra_state_(extra_state), |
1714 cache_holder_(cache_holder) { | 1568 cache_holder_(cache_holder) { |
1715 } | 1569 } |
1716 | 1570 |
1717 | 1571 |
1718 bool CallStubCompiler::HasCustomCallGenerator(JSFunction* function) { | 1572 bool CallStubCompiler::HasCustomCallGenerator(JSFunction* function) { |
1719 SharedFunctionInfo* info = function->shared(); | 1573 SharedFunctionInfo* info = function->shared(); |
1720 if (info->HasBuiltinFunctionId()) { | 1574 if (info->HasBuiltinFunctionId()) { |
1721 BuiltinFunctionId id = info->builtin_function_id(); | 1575 BuiltinFunctionId id = info->builtin_function_id(); |
1722 #define CALL_GENERATOR_CASE(name) if (id == k##name) return true; | 1576 #define CALL_GENERATOR_CASE(name) if (id == k##name) return true; |
1723 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) | 1577 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1756 ASSERT(optimization.is_simple_api_call()); | 1610 ASSERT(optimization.is_simple_api_call()); |
1757 return CompileFastApiCall(optimization, | 1611 return CompileFastApiCall(optimization, |
1758 object, | 1612 object, |
1759 holder, | 1613 holder, |
1760 cell, | 1614 cell, |
1761 function, | 1615 function, |
1762 fname); | 1616 fname); |
1763 } | 1617 } |
1764 | 1618 |
1765 | 1619 |
1766 MaybeObject* CallStubCompiler::GetCode(PropertyType type, String* name) { | 1620 Handle<Code> CallStubCompiler::GetCode(PropertyType type, Handle<String> name) { |
1767 int argc = arguments_.immediate(); | 1621 int argc = arguments_.immediate(); |
1768 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, | 1622 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, |
1769 type, | 1623 type, |
1770 extra_ic_state_, | 1624 extra_state_, |
1771 cache_holder_, | 1625 cache_holder_, |
1772 argc); | 1626 argc); |
1773 return GetCodeWithFlags(flags, name); | 1627 return GetCodeWithFlags(flags, name); |
1774 } | 1628 } |
1775 | 1629 |
1776 | 1630 |
1777 MaybeObject* CallStubCompiler::GetCode(JSFunction* function) { | 1631 Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) { |
| 1632 Handle<String> function_name; |
| 1633 if (function->shared()->name()->IsString()) { |
| 1634 function_name = Handle<String>(String::cast(function->shared()->name())); |
| 1635 } |
| 1636 return GetCode(CONSTANT_FUNCTION, function_name); |
| 1637 } |
| 1638 |
| 1639 |
| 1640 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 1641 // handlified. |
| 1642 MaybeObject* CallStubCompiler::TryGetCode(PropertyType type, String* name) { |
| 1643 int argc = arguments_.immediate(); |
| 1644 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, |
| 1645 type, |
| 1646 extra_state_, |
| 1647 cache_holder_, |
| 1648 argc); |
| 1649 return TryGetCodeWithFlags(flags, name); |
| 1650 } |
| 1651 |
| 1652 |
| 1653 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 1654 // handlified. |
| 1655 MaybeObject* CallStubCompiler::TryGetCode(JSFunction* function) { |
1778 String* function_name = NULL; | 1656 String* function_name = NULL; |
1779 if (function->shared()->name()->IsString()) { | 1657 if (function->shared()->name()->IsString()) { |
1780 function_name = String::cast(function->shared()->name()); | 1658 function_name = String::cast(function->shared()->name()); |
1781 } | 1659 } |
1782 return GetCode(CONSTANT_FUNCTION, function_name); | 1660 return TryGetCode(CONSTANT_FUNCTION, function_name); |
1783 } | 1661 } |
1784 | 1662 |
1785 | 1663 |
1786 MaybeObject* ConstructStubCompiler::GetCode() { | 1664 MaybeObject* ConstructStubCompiler::GetCode() { |
1787 Code::Flags flags = Code::ComputeFlags(Code::STUB); | 1665 Code::Flags flags = Code::ComputeFlags(Code::STUB); |
1788 Object* result; | 1666 Object* result; |
1789 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "ConstructStub"); | 1667 { MaybeObject* maybe_result = TryGetCodeWithFlags(flags, "ConstructStub"); |
1790 if (!maybe_result->ToObject(&result)) return maybe_result; | 1668 if (!maybe_result->ToObject(&result)) return maybe_result; |
1791 } | 1669 } |
1792 Code* code = Code::cast(result); | 1670 Code* code = Code::cast(result); |
1793 USE(code); | 1671 USE(code); |
1794 PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, code, "ConstructStub")); | 1672 PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, code, "ConstructStub")); |
1795 GDBJIT(AddCode(GDBJITInterface::STUB, "ConstructStub", Code::cast(code))); | 1673 GDBJIT(AddCode(GDBJITInterface::STUB, "ConstructStub", Code::cast(code))); |
1796 return result; | 1674 return result; |
1797 } | 1675 } |
1798 | 1676 |
1799 | 1677 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1858 expected_receiver_type_ = | 1736 expected_receiver_type_ = |
1859 FunctionTemplateInfo::cast(signature->receiver()); | 1737 FunctionTemplateInfo::cast(signature->receiver()); |
1860 } | 1738 } |
1861 } | 1739 } |
1862 | 1740 |
1863 is_simple_api_call_ = true; | 1741 is_simple_api_call_ = true; |
1864 } | 1742 } |
1865 | 1743 |
1866 | 1744 |
1867 } } // namespace v8::internal | 1745 } } // namespace v8::internal |
OLD | NEW |