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

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

Issue 149133004: A64: Synchronize with r17807. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/stub-cache.h ('k') | src/type-info.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 primary->value = code; 95 primary->value = code;
96 primary->map = map; 96 primary->map = map;
97 isolate()->counters()->megamorphic_stub_cache_updates()->Increment(); 97 isolate()->counters()->megamorphic_stub_cache_updates()->Increment();
98 return code; 98 return code;
99 } 99 }
100 100
101 101
102 Handle<Code> StubCache::FindIC(Handle<Name> name, 102 Handle<Code> StubCache::FindIC(Handle<Name> name,
103 Handle<Map> stub_holder_map, 103 Handle<Map> stub_holder_map,
104 Code::Kind kind, 104 Code::Kind kind,
105 Code::ExtraICState extra_state) { 105 Code::ExtraICState extra_state,
106 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, extra_state); 106 InlineCacheHolderFlag cache_holder) {
107 Code::Flags flags = Code::ComputeMonomorphicFlags(
108 kind, extra_state, cache_holder);
107 Handle<Object> probe(stub_holder_map->FindInCodeCache(*name, flags), 109 Handle<Object> probe(stub_holder_map->FindInCodeCache(*name, flags),
108 isolate_); 110 isolate_);
109 if (probe->IsCode()) return Handle<Code>::cast(probe); 111 if (probe->IsCode()) return Handle<Code>::cast(probe);
110 return Handle<Code>::null(); 112 return Handle<Code>::null();
111 } 113 }
112 114
113 115
114 Handle<Code> StubCache::FindIC(Handle<Name> name,
115 Handle<JSObject> stub_holder,
116 Code::Kind kind,
117 Code::ExtraICState extra_ic_state) {
118 return FindIC(name, Handle<Map>(stub_holder->map()), kind, extra_ic_state);
119 }
120
121
122 Handle<Code> StubCache::FindHandler(Handle<Name> name, 116 Handle<Code> StubCache::FindHandler(Handle<Name> name,
123 Handle<JSObject> receiver, 117 Handle<HeapObject> stub_holder,
124 Code::Kind kind, 118 Code::Kind kind,
119 InlineCacheHolderFlag cache_holder,
125 StrictModeFlag strict_mode) { 120 StrictModeFlag strict_mode) {
126 Code::ExtraICState extra_ic_state = Code::kNoExtraICState; 121 Code::ExtraICState extra_ic_state = Code::kNoExtraICState;
127 if (kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC) { 122 if (kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC) {
128 extra_ic_state = Code::ComputeExtraICState( 123 extra_ic_state = Code::ComputeExtraICState(
129 STANDARD_STORE, strict_mode); 124 STANDARD_STORE, strict_mode);
130 } 125 }
131 Code::Flags flags = Code::ComputeMonomorphicFlags( 126 Code::Flags flags = Code::ComputeMonomorphicFlags(
132 Code::HANDLER, extra_ic_state, Code::NORMAL, kind); 127 Code::HANDLER, extra_ic_state, cache_holder, Code::NORMAL, kind);
133 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), 128
129 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
134 isolate_); 130 isolate_);
135 if (probe->IsCode()) return Handle<Code>::cast(probe); 131 if (probe->IsCode()) return Handle<Code>::cast(probe);
136 return Handle<Code>::null(); 132 return Handle<Code>::null();
137 } 133 }
138 134
139 135
140 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<HeapObject> receiver, 136 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<Name> name,
137 Handle<Object> object,
141 Handle<Code> handler, 138 Handle<Code> handler,
142 Handle<Name> name,
143 StrictModeFlag strict_mode) { 139 StrictModeFlag strict_mode) {
144 Code::Kind kind = handler->handler_kind(); 140 Code::Kind kind = handler->handler_kind();
145 Handle<Map> map(receiver->map()); 141 // Use the same cache holder for the IC as for the handler.
146 Handle<Code> ic = FindIC(name, map, kind, strict_mode); 142 InlineCacheHolderFlag cache_holder =
143 Code::ExtractCacheHolderFromFlags(handler->flags());
144 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
145 isolate(), *object, cache_holder));
146 Handle<Map> stub_holder_map(stub_holder->map());
147 Handle<Code> ic = FindIC(
148 name, stub_holder_map, kind, strict_mode, cache_holder);
147 if (!ic.is_null()) return ic; 149 if (!ic.is_null()) return ic;
148 150
151 Handle<Map> map(object->GetMarkerMap(isolate()));
149 if (kind == Code::LOAD_IC) { 152 if (kind == Code::LOAD_IC) {
150 LoadStubCompiler ic_compiler(isolate()); 153 LoadStubCompiler ic_compiler(isolate(), cache_holder);
151 ic = ic_compiler.CompileMonomorphicIC(map, handler, name); 154 ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
152 } else if (kind == Code::KEYED_LOAD_IC) { 155 } else if (kind == Code::KEYED_LOAD_IC) {
153 KeyedLoadStubCompiler ic_compiler(isolate()); 156 KeyedLoadStubCompiler ic_compiler(isolate(), cache_holder);
154 ic = ic_compiler.CompileMonomorphicIC(map, handler, name); 157 ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
155 } else if (kind == Code::STORE_IC) { 158 } else if (kind == Code::STORE_IC) {
156 StoreStubCompiler ic_compiler(isolate(), strict_mode); 159 StoreStubCompiler ic_compiler(isolate(), strict_mode);
157 ic = ic_compiler.CompileMonomorphicIC(map, handler, name); 160 ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
158 } else { 161 } else {
159 ASSERT(kind == Code::KEYED_STORE_IC); 162 ASSERT(kind == Code::KEYED_STORE_IC);
160 KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE); 163 KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE);
161 ic = ic_compiler.CompileMonomorphicIC(map, handler, name); 164 ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
162 } 165 }
163 166
164 HeapObject::UpdateMapCodeCache(receiver, name, ic); 167 HeapObject::UpdateMapCodeCache(stub_holder, name, ic);
165 return ic; 168 return ic;
166 } 169 }
167 170
168 171
169 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, 172 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
170 Handle<JSObject> receiver) { 173 Handle<Object> object) {
174 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
175 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
176 isolate(), *object, cache_holder));
171 // If no global objects are present in the prototype chain, the load 177 // If no global objects are present in the prototype chain, the load
172 // nonexistent IC stub can be shared for all names for a given map 178 // nonexistent IC stub can be shared for all names for a given map
173 // and we use the empty string for the map cache in that case. If 179 // and we use the empty string for the map cache in that case. If
174 // there are global objects involved, we need to check global 180 // there are global objects involved, we need to check global
175 // property cells in the stub and therefore the stub will be 181 // property cells in the stub and therefore the stub will be
176 // specific to the name. 182 // specific to the name.
177 Handle<Name> cache_name = factory()->empty_string(); 183 Handle<Name> cache_name = factory()->empty_string();
178 Handle<JSObject> current; 184 Handle<JSObject> current;
179 Handle<Object> next = receiver; 185 Handle<Object> next = stub_holder;
180 Handle<JSGlobalObject> global; 186 Handle<JSGlobalObject> global;
181 do { 187 do {
182 current = Handle<JSObject>::cast(next); 188 current = Handle<JSObject>::cast(next);
183 next = Handle<Object>(current->GetPrototype(), isolate_); 189 next = Handle<Object>(current->GetPrototype(), isolate_);
184 if (current->IsJSGlobalObject()) { 190 if (current->IsJSGlobalObject()) {
185 global = Handle<JSGlobalObject>::cast(current); 191 global = Handle<JSGlobalObject>::cast(current);
186 cache_name = name; 192 cache_name = name;
187 } else if (!current->HasFastProperties()) { 193 } else if (!current->HasFastProperties()) {
188 cache_name = name; 194 cache_name = name;
189 } 195 }
190 } while (!next->IsNull()); 196 } while (!next->IsNull());
191 197
192 // Compile the stub that is either shared for all names or 198 // Compile the stub that is either shared for all names or
193 // name specific if there are global objects involved. 199 // name specific if there are global objects involved.
194 Handle<Code> handler = FindHandler(cache_name, receiver, Code::LOAD_IC); 200 Handle<Code> handler = FindHandler(
201 cache_name, stub_holder, Code::LOAD_IC, cache_holder);
195 if (!handler.is_null()) return handler; 202 if (!handler.is_null()) return handler;
196 203
197 LoadStubCompiler compiler(isolate_); 204 LoadStubCompiler compiler(isolate_, cache_holder);
198 handler = 205 handler =
199 compiler.CompileLoadNonexistent(receiver, current, cache_name, global); 206 compiler.CompileLoadNonexistent(object, current, cache_name, global);
200 HeapObject::UpdateMapCodeCache(receiver, cache_name, handler); 207 HeapObject::UpdateMapCodeCache(stub_holder, cache_name, handler);
201 return handler; 208 return handler;
202 } 209 }
203 210
204 211
205 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { 212 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) {
206 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); 213 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
207 Handle<Name> name = 214 Handle<Name> name =
208 isolate()->factory()->KeyedLoadElementMonomorphic_string(); 215 isolate()->factory()->KeyedLoadElementMonomorphic_string();
209 216
210 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); 217 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) 257 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
251 258
252 Handle<Code> StubCache::ComputeCallConstant(int argc, 259 Handle<Code> StubCache::ComputeCallConstant(int argc,
253 Code::Kind kind, 260 Code::Kind kind,
254 Code::ExtraICState extra_state, 261 Code::ExtraICState extra_state,
255 Handle<Name> name, 262 Handle<Name> name,
256 Handle<Object> object, 263 Handle<Object> object,
257 Handle<JSObject> holder, 264 Handle<JSObject> holder,
258 Handle<JSFunction> function) { 265 Handle<JSFunction> function) {
259 // Compute the check type and the map. 266 // Compute the check type and the map.
260 InlineCacheHolderFlag cache_holder = 267 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
261 IC::GetCodeCacheForObject(*object, *holder); 268 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
262 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
263 isolate_, *object, cache_holder)); 269 isolate_, *object, cache_holder));
264 270
265 // Compute check type based on receiver/holder. 271 // Compute check type based on receiver/holder.
266 CheckType check = RECEIVER_MAP_CHECK; 272 CheckType check = RECEIVER_MAP_CHECK;
267 if (object->IsString()) { 273 if (object->IsString()) {
268 check = STRING_CHECK; 274 check = STRING_CHECK;
269 } else if (object->IsSymbol()) { 275 } else if (object->IsSymbol()) {
270 check = SYMBOL_CHECK; 276 check = SYMBOL_CHECK;
271 } else if (object->IsNumber()) { 277 } else if (object->IsNumber()) {
272 check = NUMBER_CHECK; 278 check = NUMBER_CHECK;
273 } else if (object->IsBoolean()) { 279 } else if (object->IsBoolean()) {
274 check = BOOLEAN_CHECK; 280 check = BOOLEAN_CHECK;
275 } 281 }
276 282
277 if (check != RECEIVER_MAP_CHECK && 283 if (check != RECEIVER_MAP_CHECK &&
278 !function->IsBuiltin() && 284 !function->IsBuiltin() &&
279 function->shared()->is_classic_mode()) { 285 function->shared()->is_classic_mode()) {
280 // Calling non-strict non-builtins with a value as the receiver 286 // Calling non-strict non-builtins with a value as the receiver
281 // requires boxing. 287 // requires boxing.
282 return Handle<Code>::null(); 288 return Handle<Code>::null();
283 } 289 }
284 290
285 Code::Flags flags = Code::ComputeMonomorphicFlags( 291 Code::Flags flags = Code::ComputeMonomorphicFlags(
286 kind, extra_state, Code::CONSTANT, argc, cache_holder); 292 kind, extra_state, cache_holder, Code::CONSTANT, argc);
287 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), 293 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
288 isolate_); 294 isolate_);
289 if (probe->IsCode()) return Handle<Code>::cast(probe); 295 if (probe->IsCode()) return Handle<Code>::cast(probe);
290 296
291 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); 297 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
292 Handle<Code> code = 298 Handle<Code> code =
293 compiler.CompileCallConstant(object, holder, name, check, function); 299 compiler.CompileCallConstant(object, holder, name, check, function);
294 code->set_check_type(check); 300 code->set_check_type(check);
295 ASSERT(flags == code->flags()); 301 ASSERT(flags == code->flags());
296 PROFILE(isolate_, 302 PROFILE(isolate_,
297 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 303 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
298 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 304 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
299 305
300 if (CallStubCompiler::CanBeCached(function)) { 306 if (CallStubCompiler::CanBeCached(function)) {
301 HeapObject::UpdateMapCodeCache(stub_holder, name, code); 307 HeapObject::UpdateMapCodeCache(stub_holder, name, code);
302 } 308 }
303 return code; 309 return code;
304 } 310 }
305 311
306 312
307 Handle<Code> StubCache::ComputeCallField(int argc, 313 Handle<Code> StubCache::ComputeCallField(int argc,
308 Code::Kind kind, 314 Code::Kind kind,
309 Code::ExtraICState extra_state, 315 Code::ExtraICState extra_state,
310 Handle<Name> name, 316 Handle<Name> name,
311 Handle<Object> object, 317 Handle<Object> object,
312 Handle<JSObject> holder, 318 Handle<JSObject> holder,
313 PropertyIndex index) { 319 PropertyIndex index) {
314 // Compute the check type and the map. 320 // Compute the check type and the map.
315 InlineCacheHolderFlag cache_holder = 321 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
316 IC::GetCodeCacheForObject(*object, *holder); 322 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
317 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
318 isolate_, *object, cache_holder)); 323 isolate_, *object, cache_holder));
319 324
320 // TODO(1233596): We cannot do receiver map check for non-JS objects 325 // TODO(1233596): We cannot do receiver map check for non-JS objects
321 // because they may be represented as immediates without a 326 // because they may be represented as immediates without a
322 // map. Instead, we check against the map in the holder. 327 // map. Instead, we check against the map in the holder.
323 if (object->IsNumber() || object->IsSymbol() || 328 if (object->IsNumber() || object->IsSymbol() ||
324 object->IsBoolean() || object->IsString()) { 329 object->IsBoolean() || object->IsString()) {
325 object = holder; 330 object = holder;
326 } 331 }
327 332
328 Code::Flags flags = Code::ComputeMonomorphicFlags( 333 Code::Flags flags = Code::ComputeMonomorphicFlags(
329 kind, extra_state, Code::FIELD, argc, cache_holder); 334 kind, extra_state, cache_holder, Code::FIELD, argc);
330 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), 335 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
331 isolate_); 336 isolate_);
332 if (probe->IsCode()) return Handle<Code>::cast(probe); 337 if (probe->IsCode()) return Handle<Code>::cast(probe);
333 338
334 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); 339 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
335 Handle<Code> code = 340 Handle<Code> code =
336 compiler.CompileCallField(Handle<JSObject>::cast(object), 341 compiler.CompileCallField(Handle<JSObject>::cast(object),
337 holder, index, name); 342 holder, index, name);
338 ASSERT(flags == code->flags()); 343 ASSERT(flags == code->flags());
339 PROFILE(isolate_, 344 PROFILE(isolate_,
340 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 345 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
341 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 346 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
342 HeapObject::UpdateMapCodeCache(stub_holder, name, code); 347 HeapObject::UpdateMapCodeCache(stub_holder, name, code);
343 return code; 348 return code;
344 } 349 }
345 350
346 351
347 Handle<Code> StubCache::ComputeCallInterceptor(int argc, 352 Handle<Code> StubCache::ComputeCallInterceptor(int argc,
348 Code::Kind kind, 353 Code::Kind kind,
349 Code::ExtraICState extra_state, 354 Code::ExtraICState extra_state,
350 Handle<Name> name, 355 Handle<Name> name,
351 Handle<Object> object, 356 Handle<Object> object,
352 Handle<JSObject> holder) { 357 Handle<JSObject> holder) {
353 // Compute the check type and the map. 358 // Compute the check type and the map.
354 InlineCacheHolderFlag cache_holder = 359 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
355 IC::GetCodeCacheForObject(*object, *holder); 360 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
356 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
357 isolate_, *object, cache_holder)); 361 isolate_, *object, cache_holder));
358 362
359 // TODO(1233596): We cannot do receiver map check for non-JS objects 363 // TODO(1233596): We cannot do receiver map check for non-JS objects
360 // because they may be represented as immediates without a 364 // because they may be represented as immediates without a
361 // map. Instead, we check against the map in the holder. 365 // map. Instead, we check against the map in the holder.
362 if (object->IsNumber() || object->IsSymbol() || 366 if (object->IsNumber() || object->IsSymbol() ||
363 object->IsBoolean() || object->IsString()) { 367 object->IsBoolean() || object->IsString()) {
364 object = holder; 368 object = holder;
365 } 369 }
366 370
367 Code::Flags flags = Code::ComputeMonomorphicFlags( 371 Code::Flags flags = Code::ComputeMonomorphicFlags(
368 kind, extra_state, Code::INTERCEPTOR, argc, cache_holder); 372 kind, extra_state, cache_holder, Code::INTERCEPTOR, argc);
369 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), 373 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
370 isolate_); 374 isolate_);
371 if (probe->IsCode()) return Handle<Code>::cast(probe); 375 if (probe->IsCode()) return Handle<Code>::cast(probe);
372 376
373 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder); 377 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
374 Handle<Code> code = 378 Handle<Code> code =
375 compiler.CompileCallInterceptor(Handle<JSObject>::cast(object), 379 compiler.CompileCallInterceptor(Handle<JSObject>::cast(object),
376 holder, name); 380 holder, name);
377 ASSERT(flags == code->flags()); 381 ASSERT(flags == code->flags());
378 PROFILE(isolate(), 382 PROFILE(isolate(),
379 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 383 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
380 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 384 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
381 HeapObject::UpdateMapCodeCache(stub_holder, name, code); 385 HeapObject::UpdateMapCodeCache(stub_holder, name, code);
382 return code; 386 return code;
383 } 387 }
384 388
385 389
386 Handle<Code> StubCache::ComputeCallGlobal(int argc, 390 Handle<Code> StubCache::ComputeCallGlobal(int argc,
387 Code::Kind kind, 391 Code::Kind kind,
388 Code::ExtraICState extra_state, 392 Code::ExtraICState extra_state,
389 Handle<Name> name, 393 Handle<Name> name,
390 Handle<JSObject> receiver, 394 Handle<JSObject> receiver,
391 Handle<GlobalObject> holder, 395 Handle<GlobalObject> holder,
392 Handle<PropertyCell> cell, 396 Handle<PropertyCell> cell,
393 Handle<JSFunction> function) { 397 Handle<JSFunction> function) {
394 Code::Flags flags = Code::ComputeMonomorphicFlags( 398 Code::Flags flags = Code::ComputeMonomorphicFlags(
395 kind, extra_state, Code::NORMAL, argc); 399 kind, extra_state, OWN_MAP, Code::NORMAL, argc);
396 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), 400 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
397 isolate_); 401 isolate_);
398 if (probe->IsCode()) return Handle<Code>::cast(probe); 402 if (probe->IsCode()) return Handle<Code>::cast(probe);
399 403
400 CallStubCompiler compiler(isolate(), argc, kind, extra_state); 404 CallStubCompiler compiler(isolate(), argc, kind, extra_state);
401 Handle<Code> code = 405 Handle<Code> code =
402 compiler.CompileCallGlobal(receiver, holder, cell, function, name); 406 compiler.CompileCallGlobal(receiver, holder, cell, function, name);
403 ASSERT(flags == code->flags()); 407 ASSERT(flags == code->flags());
404 PROFILE(isolate(), 408 PROFILE(isolate(),
405 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 409 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 return isolate->heap()->no_interceptor_result_sentinel(); 823 return isolate->heap()->no_interceptor_result_sentinel();
820 } 824 }
821 825
822 826
823 static MaybeObject* ThrowReferenceError(Isolate* isolate, Name* name) { 827 static MaybeObject* ThrowReferenceError(Isolate* isolate, Name* name) {
824 // If the load is non-contextual, just return the undefined result. 828 // If the load is non-contextual, just return the undefined result.
825 // Note that both keyed and non-keyed loads may end up here, so we 829 // Note that both keyed and non-keyed loads may end up here, so we
826 // can't use either LoadIC or KeyedLoadIC constructors. 830 // can't use either LoadIC or KeyedLoadIC constructors.
827 HandleScope scope(isolate); 831 HandleScope scope(isolate);
828 IC ic(IC::NO_EXTRA_FRAME, isolate); 832 IC ic(IC::NO_EXTRA_FRAME, isolate);
829 ASSERT(ic.target()->is_load_stub() || ic.target()->is_keyed_load_stub()); 833 ASSERT(ic.IsLoadStub());
830 if (!ic.SlowIsUndeclaredGlobal()) return isolate->heap()->undefined_value(); 834 if (!ic.SlowIsUndeclaredGlobal()) return isolate->heap()->undefined_value();
831 835
832 // Throw a reference error. 836 // Throw a reference error.
833 Handle<Name> name_handle(name); 837 Handle<Name> name_handle(name);
834 Handle<Object> error = 838 Handle<Object> error =
835 isolate->factory()->NewReferenceError("not_defined", 839 isolate->factory()->NewReferenceError("not_defined",
836 HandleVector(&name_handle, 1)); 840 HandleVector(&name_handle, 1));
837 return isolate->Throw(*error); 841 return isolate->Throw(*error);
838 } 842 }
839 843
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 #undef CALL_LOGGER_TAG 1093 #undef CALL_LOGGER_TAG
1090 1094
1091 1095
1092 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, 1096 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
1093 const char* name) { 1097 const char* name) {
1094 // Create code object in the heap. 1098 // Create code object in the heap.
1095 CodeDesc desc; 1099 CodeDesc desc;
1096 masm_.GetCode(&desc); 1100 masm_.GetCode(&desc);
1097 Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject()); 1101 Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject());
1098 #ifdef ENABLE_DISASSEMBLER 1102 #ifdef ENABLE_DISASSEMBLER
1099 if (FLAG_print_code_stubs) { 1103 if (FLAG_print_code_stubs) code->Disassemble(name);
1100 CodeTracer::Scope trace_scope(isolate()->GetCodeTracer());
1101 code->Disassemble(name, trace_scope.file());
1102 }
1103 #endif 1104 #endif
1104 return code; 1105 return code;
1105 } 1106 }
1106 1107
1107 1108
1108 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, 1109 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
1109 Handle<Name> name) { 1110 Handle<Name> name) {
1110 return (FLAG_print_code_stubs && !name.is_null() && name->IsString()) 1111 return (FLAG_print_code_stubs && !name.is_null() && name->IsString())
1111 ? GetCodeWithFlags(flags, *Handle<String>::cast(name)->ToCString()) 1112 ? GetCodeWithFlags(flags, *Handle<String>::cast(name)->ToCString())
1112 : GetCodeWithFlags(flags, NULL); 1113 : GetCodeWithFlags(flags, NULL);
1113 } 1114 }
1114 1115
1115 1116
1116 void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder, 1117 void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder,
1117 Handle<Name> name, 1118 Handle<Name> name,
1118 LookupResult* lookup) { 1119 LookupResult* lookup) {
1119 holder->LocalLookupRealNamedProperty(*name, lookup); 1120 holder->LocalLookupRealNamedProperty(*name, lookup);
1120 if (lookup->IsFound()) return; 1121 if (lookup->IsFound()) return;
1121 if (holder->GetPrototype()->IsNull()) return; 1122 if (holder->GetPrototype()->IsNull()) return;
1122 holder->GetPrototype()->Lookup(*name, lookup); 1123 holder->GetPrototype()->Lookup(*name, lookup);
1123 } 1124 }
1124 1125
1125 1126
1126 #define __ ACCESS_MASM(masm()) 1127 #define __ ACCESS_MASM(masm())
1127 1128
1128 1129
1129 Register LoadStubCompiler::HandlerFrontendHeader( 1130 Register LoadStubCompiler::HandlerFrontendHeader(
1130 Handle<JSObject> object, 1131 Handle<Object> object,
1131 Register object_reg, 1132 Register object_reg,
1132 Handle<JSObject> holder, 1133 Handle<JSObject> holder,
1133 Handle<Name> name, 1134 Handle<Name> name,
1134 Label* miss) { 1135 Label* miss) {
1135 return CheckPrototypes(object, object_reg, holder, 1136 Handle<JSObject> receiver;
1137 PrototypeCheckType check_type = CHECK_ALL_MAPS;
1138 int function_index = -1;
1139 if (object->IsJSObject()) {
1140 receiver = Handle<JSObject>::cast(object);
1141 check_type = SKIP_RECEIVER;
1142 } else {
1143 if (object->IsString()) {
1144 function_index = Context::STRING_FUNCTION_INDEX;
1145 } else if (object->IsSymbol()) {
1146 function_index = Context::SYMBOL_FUNCTION_INDEX;
1147 } else if (object->IsNumber()) {
1148 function_index = Context::NUMBER_FUNCTION_INDEX;
1149 } else {
1150 ASSERT(object->IsBoolean());
1151 // Booleans use the generic oddball map, so an additional check is
1152 // needed to ensure the receiver is really a boolean.
1153 GenerateBooleanCheck(object_reg, miss);
1154 function_index = Context::BOOLEAN_FUNCTION_INDEX;
1155 }
1156
1157 GenerateDirectLoadGlobalFunctionPrototype(
1158 masm(), function_index, scratch1(), miss);
1159 receiver = handle(JSObject::cast(object->GetPrototype(isolate())));
1160 object_reg = scratch1();
1161 }
1162
1163 // Check that the maps starting from the prototype haven't changed.
1164 return CheckPrototypes(receiver, object_reg, holder,
1136 scratch1(), scratch2(), scratch3(), 1165 scratch1(), scratch2(), scratch3(),
1137 name, miss, SKIP_RECEIVER); 1166 name, miss, check_type);
1138 } 1167 }
1139 1168
1140 1169
1141 // HandlerFrontend for store uses the name register. It has to be restored 1170 // HandlerFrontend for store uses the name register. It has to be restored
1142 // before a miss. 1171 // before a miss.
1143 Register StoreStubCompiler::HandlerFrontendHeader( 1172 Register StoreStubCompiler::HandlerFrontendHeader(
1144 Handle<JSObject> object, 1173 Handle<Object> object,
1145 Register object_reg, 1174 Register object_reg,
1146 Handle<JSObject> holder, 1175 Handle<JSObject> holder,
1147 Handle<Name> name, 1176 Handle<Name> name,
1148 Label* miss) { 1177 Label* miss) {
1149 return CheckPrototypes(object, object_reg, holder, 1178 return CheckPrototypes(Handle<JSObject>::cast(object), object_reg, holder,
1150 this->name(), scratch1(), scratch2(), 1179 this->name(), scratch1(), scratch2(),
1151 name, miss, SKIP_RECEIVER); 1180 name, miss, SKIP_RECEIVER);
1152 } 1181 }
1153 1182
1154 1183
1155 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<JSObject> object, 1184 bool BaseLoadStoreStubCompiler::HasHeapNumberMap(MapHandleList* receiver_maps) {
1185 for (int i = 0; i < receiver_maps->length(); ++i) {
1186 Handle<Map> map = receiver_maps->at(i);
1187 if (map.is_identical_to(isolate()->factory()->heap_number_map())) {
1188 return true;
1189 }
1190 }
1191 return false;
1192 }
1193
1194
1195 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<Object> object,
1156 Register object_reg, 1196 Register object_reg,
1157 Handle<JSObject> holder, 1197 Handle<JSObject> holder,
1158 Handle<Name> name, 1198 Handle<Name> name) {
1159 Label* success) {
1160 Label miss; 1199 Label miss;
1161 1200
1162 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); 1201 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
1163 1202
1164 HandlerFrontendFooter(name, success, &miss); 1203 HandlerFrontendFooter(name, &miss);
1204
1165 return reg; 1205 return reg;
1166 } 1206 }
1167 1207
1168 1208
1169 void LoadStubCompiler::NonexistentHandlerFrontend( 1209 void LoadStubCompiler::NonexistentHandlerFrontend(
1170 Handle<JSObject> object, 1210 Handle<Object> object,
1171 Handle<JSObject> last, 1211 Handle<JSObject> last,
1172 Handle<Name> name, 1212 Handle<Name> name,
1173 Label* success,
1174 Handle<JSGlobalObject> global) { 1213 Handle<JSGlobalObject> global) {
1175 Label miss; 1214 Label miss;
1176 1215
1177 Register holder = 1216 Register holder = HandlerFrontendHeader(
1178 HandlerFrontendHeader(object, receiver(), last, name, &miss); 1217 object, receiver(), last, name, &miss);
1179 1218
1180 if (!last->HasFastProperties() && 1219 if (!last->HasFastProperties() &&
1181 !last->IsJSGlobalObject() && 1220 !last->IsJSGlobalObject() &&
1182 !last->IsJSGlobalProxy()) { 1221 !last->IsJSGlobalProxy()) {
1183 if (!name->IsUniqueName()) { 1222 if (!name->IsUniqueName()) {
1184 ASSERT(name->IsString()); 1223 ASSERT(name->IsString());
1185 name = factory()->InternalizeString(Handle<String>::cast(name)); 1224 name = factory()->InternalizeString(Handle<String>::cast(name));
1186 } 1225 }
1187 ASSERT(last->property_dictionary()->FindEntry(*name) == 1226 ASSERT(last->property_dictionary()->FindEntry(*name) ==
1188 NameDictionary::kNotFound); 1227 NameDictionary::kNotFound);
1189 GenerateDictionaryNegativeLookup(masm(), &miss, holder, name, 1228 GenerateDictionaryNegativeLookup(masm(), &miss, holder, name,
1190 scratch2(), scratch3()); 1229 scratch2(), scratch3());
1191 } 1230 }
1192 1231
1193 // If the last object in the prototype chain is a global object, 1232 // If the last object in the prototype chain is a global object,
1194 // check that the global property cell is empty. 1233 // check that the global property cell is empty.
1195 if (!global.is_null()) { 1234 if (!global.is_null()) {
1196 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); 1235 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
1197 } 1236 }
1198 1237
1199 HandlerFrontendFooter(name, success, &miss); 1238 HandlerFrontendFooter(name, &miss);
1200 } 1239 }
1201 1240
1202 1241
1203 Handle<Code> LoadStubCompiler::CompileLoadField( 1242 Handle<Code> LoadStubCompiler::CompileLoadField(
1204 Handle<JSObject> object, 1243 Handle<Object> object,
1205 Handle<JSObject> holder, 1244 Handle<JSObject> holder,
1206 Handle<Name> name, 1245 Handle<Name> name,
1207 PropertyIndex field, 1246 PropertyIndex field,
1208 Representation representation) { 1247 Representation representation) {
1209 Label miss; 1248 Label miss;
1210 1249
1211 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss); 1250 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss);
1212 1251
1213 GenerateLoadField(reg, holder, field, representation); 1252 GenerateLoadField(reg, holder, field, representation);
1214 1253
1215 __ bind(&miss); 1254 __ bind(&miss);
1216 TailCallBuiltin(masm(), MissBuiltin(kind())); 1255 TailCallBuiltin(masm(), MissBuiltin(kind()));
1217 1256
1218 // Return the generated code. 1257 // Return the generated code.
1219 return GetCode(kind(), Code::FIELD, name); 1258 return GetCode(kind(), Code::FIELD, name);
1220 } 1259 }
1221 1260
1222 1261
1223 Handle<Code> LoadStubCompiler::CompileLoadConstant( 1262 Handle<Code> LoadStubCompiler::CompileLoadConstant(
1224 Handle<JSObject> object, 1263 Handle<Object> object,
1225 Handle<JSObject> holder, 1264 Handle<JSObject> holder,
1226 Handle<Name> name, 1265 Handle<Name> name,
1227 Handle<Object> value) { 1266 Handle<Object> value) {
1228 Label success; 1267 HandlerFrontend(object, receiver(), holder, name);
1229 HandlerFrontend(object, receiver(), holder, name, &success);
1230 __ bind(&success);
1231 GenerateLoadConstant(value); 1268 GenerateLoadConstant(value);
1232 1269
1233 // Return the generated code. 1270 // Return the generated code.
1234 return GetCode(kind(), Code::CONSTANT, name); 1271 return GetCode(kind(), Code::CONSTANT, name);
1235 } 1272 }
1236 1273
1237 1274
1238 Handle<Code> LoadStubCompiler::CompileLoadCallback( 1275 Handle<Code> LoadStubCompiler::CompileLoadCallback(
1239 Handle<JSObject> object, 1276 Handle<Object> object,
1240 Handle<JSObject> holder, 1277 Handle<JSObject> holder,
1241 Handle<Name> name, 1278 Handle<Name> name,
1242 Handle<ExecutableAccessorInfo> callback) { 1279 Handle<ExecutableAccessorInfo> callback) {
1243 Label success;
1244
1245 Register reg = CallbackHandlerFrontend( 1280 Register reg = CallbackHandlerFrontend(
1246 object, receiver(), holder, name, &success, callback); 1281 object, receiver(), holder, name, callback);
1247 __ bind(&success);
1248 GenerateLoadCallback(reg, callback); 1282 GenerateLoadCallback(reg, callback);
1249 1283
1250 // Return the generated code. 1284 // Return the generated code.
1251 return GetCode(kind(), Code::CALLBACKS, name); 1285 return GetCode(kind(), Code::CALLBACKS, name);
1252 } 1286 }
1253 1287
1254 1288
1255 Handle<Code> LoadStubCompiler::CompileLoadCallback( 1289 Handle<Code> LoadStubCompiler::CompileLoadCallback(
1256 Handle<JSObject> object, 1290 Handle<Object> object,
1257 Handle<JSObject> holder, 1291 Handle<JSObject> holder,
1258 Handle<Name> name, 1292 Handle<Name> name,
1259 const CallOptimization& call_optimization) { 1293 const CallOptimization& call_optimization) {
1260 ASSERT(call_optimization.is_simple_api_call()); 1294 ASSERT(call_optimization.is_simple_api_call());
1261 Label success;
1262
1263 Handle<JSFunction> callback = call_optimization.constant_function(); 1295 Handle<JSFunction> callback = call_optimization.constant_function();
1264 CallbackHandlerFrontend( 1296 CallbackHandlerFrontend(object, receiver(), holder, name, callback);
1265 object, receiver(), holder, name, &success, callback);
1266 __ bind(&success);
1267 GenerateLoadCallback(call_optimization); 1297 GenerateLoadCallback(call_optimization);
1268 1298
1269 // Return the generated code. 1299 // Return the generated code.
1270 return GetCode(kind(), Code::CALLBACKS, name); 1300 return GetCode(kind(), Code::CALLBACKS, name);
1271 } 1301 }
1272 1302
1273 1303
1274 Handle<Code> LoadStubCompiler::CompileLoadInterceptor( 1304 Handle<Code> LoadStubCompiler::CompileLoadInterceptor(
1275 Handle<JSObject> object, 1305 Handle<Object> object,
1276 Handle<JSObject> holder, 1306 Handle<JSObject> holder,
1277 Handle<Name> name) { 1307 Handle<Name> name) {
1278 Label success;
1279
1280 LookupResult lookup(isolate()); 1308 LookupResult lookup(isolate());
1281 LookupPostInterceptor(holder, name, &lookup); 1309 LookupPostInterceptor(holder, name, &lookup);
1282 1310
1283 Register reg = HandlerFrontend(object, receiver(), holder, name, &success); 1311 Register reg = HandlerFrontend(object, receiver(), holder, name);
1284 __ bind(&success);
1285 // TODO(368): Compile in the whole chain: all the interceptors in 1312 // TODO(368): Compile in the whole chain: all the interceptors in
1286 // prototypes and ultimate answer. 1313 // prototypes and ultimate answer.
1287 GenerateLoadInterceptor(reg, object, holder, &lookup, name); 1314 GenerateLoadInterceptor(reg, object, holder, &lookup, name);
1288 1315
1289 // Return the generated code. 1316 // Return the generated code.
1290 return GetCode(kind(), Code::INTERCEPTOR, name); 1317 return GetCode(kind(), Code::INTERCEPTOR, name);
1291 } 1318 }
1292 1319
1293 1320
1294 void LoadStubCompiler::GenerateLoadPostInterceptor( 1321 void LoadStubCompiler::GenerateLoadPostInterceptor(
1295 Register interceptor_reg, 1322 Register interceptor_reg,
1296 Handle<JSObject> interceptor_holder, 1323 Handle<JSObject> interceptor_holder,
1297 Handle<Name> name, 1324 Handle<Name> name,
1298 LookupResult* lookup) { 1325 LookupResult* lookup) {
1299 Label success;
1300 Handle<JSObject> holder(lookup->holder()); 1326 Handle<JSObject> holder(lookup->holder());
1301 if (lookup->IsField()) { 1327 if (lookup->IsField()) {
1302 PropertyIndex field = lookup->GetFieldIndex(); 1328 PropertyIndex field = lookup->GetFieldIndex();
1303 if (interceptor_holder.is_identical_to(holder)) { 1329 if (interceptor_holder.is_identical_to(holder)) {
1304 GenerateLoadField( 1330 GenerateLoadField(
1305 interceptor_reg, holder, field, lookup->representation()); 1331 interceptor_reg, holder, field, lookup->representation());
1306 } else { 1332 } else {
1307 // We found FIELD property in prototype chain of interceptor's holder. 1333 // We found FIELD property in prototype chain of interceptor's holder.
1308 // Retrieve a field from field's holder. 1334 // Retrieve a field from field's holder.
1309 Register reg = HandlerFrontend( 1335 Register reg = HandlerFrontend(
1310 interceptor_holder, interceptor_reg, holder, name, &success); 1336 interceptor_holder, interceptor_reg, holder, name);
1311 __ bind(&success);
1312 GenerateLoadField( 1337 GenerateLoadField(
1313 reg, holder, field, lookup->representation()); 1338 reg, holder, field, lookup->representation());
1314 } 1339 }
1315 } else { 1340 } else {
1316 // We found CALLBACKS property in prototype chain of interceptor's 1341 // We found CALLBACKS property in prototype chain of interceptor's
1317 // holder. 1342 // holder.
1318 ASSERT(lookup->type() == CALLBACKS); 1343 ASSERT(lookup->type() == CALLBACKS);
1319 Handle<ExecutableAccessorInfo> callback( 1344 Handle<ExecutableAccessorInfo> callback(
1320 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); 1345 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
1321 ASSERT(callback->getter() != NULL); 1346 ASSERT(callback->getter() != NULL);
1322 1347
1323 Register reg = CallbackHandlerFrontend( 1348 Register reg = CallbackHandlerFrontend(
1324 interceptor_holder, interceptor_reg, holder, name, &success, callback); 1349 interceptor_holder, interceptor_reg, holder, name, callback);
1325 __ bind(&success);
1326 GenerateLoadCallback(reg, callback); 1350 GenerateLoadCallback(reg, callback);
1327 } 1351 }
1328 } 1352 }
1329 1353
1330 1354
1331 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC( 1355 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC(
1332 Handle<Map> receiver_map, 1356 Handle<Map> receiver_map,
1333 Handle<Code> handler, 1357 Handle<Code> handler,
1334 Handle<Name> name) { 1358 Handle<Name> name) {
1335 MapHandleList receiver_maps(1); 1359 MapHandleList receiver_maps(1);
1336 receiver_maps.Add(receiver_map); 1360 receiver_maps.Add(receiver_map);
1337 CodeHandleList handlers(1); 1361 CodeHandleList handlers(1);
1338 handlers.Add(handler); 1362 handlers.Add(handler);
1339 Code::StubType type = handler->type(); 1363 Code::StubType type = handler->type();
1340 return CompilePolymorphicIC(&receiver_maps, &handlers, name, type, PROPERTY); 1364 return CompilePolymorphicIC(&receiver_maps, &handlers, name, type, PROPERTY);
1341 } 1365 }
1342 1366
1343 1367
1344 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( 1368 Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
1345 Handle<JSObject> object, 1369 Handle<Object> object,
1346 Handle<JSObject> holder, 1370 Handle<JSObject> holder,
1347 Handle<Name> name, 1371 Handle<Name> name,
1348 Handle<JSFunction> getter) { 1372 Handle<JSFunction> getter) {
1349 Label success; 1373 HandlerFrontend(object, receiver(), holder, name);
1350 HandlerFrontend(object, receiver(), holder, name, &success);
1351
1352 __ bind(&success);
1353 GenerateLoadViaGetter(masm(), receiver(), getter); 1374 GenerateLoadViaGetter(masm(), receiver(), getter);
1354 1375
1355 // Return the generated code. 1376 // Return the generated code.
1356 return GetCode(kind(), Code::CALLBACKS, name); 1377 return GetCode(kind(), Code::CALLBACKS, name);
1357 } 1378 }
1358 1379
1359 1380
1360 Handle<Code> StoreStubCompiler::CompileStoreTransition( 1381 Handle<Code> StoreStubCompiler::CompileStoreTransition(
1361 Handle<JSObject> object, 1382 Handle<JSObject> object,
1362 LookupResult* lookup, 1383 LookupResult* lookup,
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 // Return the generated code. 1456 // Return the generated code.
1436 return GetCode(kind(), Code::FIELD, name); 1457 return GetCode(kind(), Code::FIELD, name);
1437 } 1458 }
1438 1459
1439 1460
1440 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( 1461 Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
1441 Handle<JSObject> object, 1462 Handle<JSObject> object,
1442 Handle<JSObject> holder, 1463 Handle<JSObject> holder,
1443 Handle<Name> name, 1464 Handle<Name> name,
1444 Handle<JSFunction> setter) { 1465 Handle<JSFunction> setter) {
1445 Label success; 1466 HandlerFrontend(object, receiver(), holder, name);
1446 HandlerFrontend(object, receiver(), holder, name, &success);
1447
1448 __ bind(&success);
1449 GenerateStoreViaSetter(masm(), setter); 1467 GenerateStoreViaSetter(masm(), setter);
1450 1468
1451 return GetCode(kind(), Code::CALLBACKS, name); 1469 return GetCode(kind(), Code::CALLBACKS, name);
1452 } 1470 }
1453 1471
1454 1472
1455 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( 1473 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
1456 Handle<Map> receiver_map) { 1474 Handle<Map> receiver_map) {
1457 ElementsKind elements_kind = receiver_map->elements_kind(); 1475 ElementsKind elements_kind = receiver_map->elements_kind();
1458 if (receiver_map->has_fast_elements() || 1476 if (receiver_map->has_fast_elements() ||
1459 receiver_map->has_external_array_elements()) { 1477 receiver_map->has_external_array_elements()) {
1460 Handle<Code> stub = KeyedLoadFastElementStub( 1478 Handle<Code> stub = KeyedLoadFastElementStub(
1461 receiver_map->instance_type() == JS_ARRAY_TYPE, 1479 receiver_map->instance_type() == JS_ARRAY_TYPE,
1462 elements_kind).GetCode(isolate()); 1480 elements_kind).GetCode(isolate());
1463 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK); 1481 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
1464 } else { 1482 } else {
1465 Handle<Code> stub = 1483 Handle<Code> stub = FLAG_compiled_keyed_dictionary_loads
1466 KeyedLoadDictionaryElementStub().GetCode(isolate()); 1484 ? KeyedLoadDictionaryElementStub().GetCode(isolate())
1485 : KeyedLoadDictionaryElementPlatformStub().GetCode(isolate());
1467 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK); 1486 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
1468 } 1487 }
1469 1488
1470 TailCallBuiltin(masm(), Builtins::kKeyedLoadIC_Miss); 1489 TailCallBuiltin(masm(), Builtins::kKeyedLoadIC_Miss);
1471 1490
1472 // Return the generated code. 1491 // Return the generated code.
1473 return GetICCode(kind(), Code::NORMAL, factory()->empty_string()); 1492 return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
1474 } 1493 }
1475 1494
1476 1495
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1548 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); 1567 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
1549 JitEvent(name, code); 1568 JitEvent(name, code);
1550 return code; 1569 return code;
1551 } 1570 }
1552 1571
1553 1572
1554 Handle<Code> BaseLoadStoreStubCompiler::GetCode(Code::Kind kind, 1573 Handle<Code> BaseLoadStoreStubCompiler::GetCode(Code::Kind kind,
1555 Code::StubType type, 1574 Code::StubType type,
1556 Handle<Name> name) { 1575 Handle<Name> name) {
1557 Code::Flags flags = Code::ComputeFlags( 1576 Code::Flags flags = Code::ComputeFlags(
1558 Code::HANDLER, MONOMORPHIC, extra_state(), type, kind); 1577 Code::HANDLER, MONOMORPHIC, extra_state(), type, kind, cache_holder_);
1559 Handle<Code> code = GetCodeWithFlags(flags, name); 1578 Handle<Code> code = GetCodeWithFlags(flags, name);
1560 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); 1579 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
1561 JitEvent(name, code); 1580 JitEvent(name, code);
1562 return code; 1581 return code;
1563 } 1582 }
1564 1583
1565 1584
1566 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps, 1585 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps,
1567 CodeHandleList* handlers) { 1586 CodeHandleList* handlers) {
1568 for (int i = 0; i < receiver_maps->length(); ++i) { 1587 for (int i = 0; i < receiver_maps->length(); ++i) {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1716 holder, 1735 holder,
1717 cell, 1736 cell,
1718 function, 1737 function,
1719 fname); 1738 fname);
1720 } 1739 }
1721 1740
1722 1741
1723 Handle<Code> CallStubCompiler::GetCode(Code::StubType type, 1742 Handle<Code> CallStubCompiler::GetCode(Code::StubType type,
1724 Handle<Name> name) { 1743 Handle<Name> name) {
1725 int argc = arguments_.immediate(); 1744 int argc = arguments_.immediate();
1726 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, 1745 Code::Flags flags = Code::ComputeMonomorphicFlags(
1727 extra_state_, 1746 kind_, extra_state_, cache_holder_, type, argc);
1728 type,
1729 argc,
1730 cache_holder_);
1731 return GetCodeWithFlags(flags, name); 1747 return GetCodeWithFlags(flags, name);
1732 } 1748 }
1733 1749
1734 1750
1735 Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) { 1751 Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) {
1736 Handle<String> function_name; 1752 Handle<String> function_name;
1737 if (function->shared()->name()->IsString()) { 1753 if (function->shared()->name()->IsString()) {
1738 function_name = Handle<String>(String::cast(function->shared()->name())); 1754 function_name = Handle<String>(String::cast(function->shared()->name()));
1739 } 1755 }
1740 return GetCode(Code::CONSTANT, function_name); 1756 return GetCode(Code::CONSTANT, function_name);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1808 Handle<FunctionTemplateInfo>( 1824 Handle<FunctionTemplateInfo>(
1809 FunctionTemplateInfo::cast(signature->receiver())); 1825 FunctionTemplateInfo::cast(signature->receiver()));
1810 } 1826 }
1811 } 1827 }
1812 1828
1813 is_simple_api_call_ = true; 1829 is_simple_api_call_ = true;
1814 } 1830 }
1815 1831
1816 1832
1817 } } // namespace v8::internal 1833 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | src/type-info.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698