v8  3.11.10(node0.8.26)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
stub-cache.cc
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include "v8.h"
29 
30 #include "api.h"
31 #include "arguments.h"
32 #include "ast.h"
33 #include "code-stubs.h"
34 #include "gdb-jit.h"
35 #include "ic-inl.h"
36 #include "stub-cache.h"
37 #include "vm-state-inl.h"
38 
39 namespace v8 {
40 namespace internal {
41 
42 // -----------------------------------------------------------------------
43 // StubCache implementation.
44 
45 
46 StubCache::StubCache(Isolate* isolate, Zone* zone)
47  : isolate_(isolate), zone_(zone) {
48  ASSERT(isolate == Isolate::Current());
49 }
50 
51 
52 void StubCache::Initialize() {
53  ASSERT(IsPowerOf2(kPrimaryTableSize));
54  ASSERT(IsPowerOf2(kSecondaryTableSize));
55  Clear();
56 }
57 
58 
59 Code* StubCache::Set(String* name, Map* map, Code* code) {
60  // Get the flags from the code.
61  Code::Flags flags = Code::RemoveTypeFromFlags(code->flags());
62 
63  // Validate that the name does not move on scavenge, and that we
64  // can use identity checks instead of string equality checks.
65  ASSERT(!heap()->InNewSpace(name));
66  ASSERT(name->IsSymbol());
67 
68  // The state bits are not important to the hash function because
69  // the stub cache only contains monomorphic stubs. Make sure that
70  // the bits are the least significant so they will be the ones
71  // masked out.
72  ASSERT(Code::ExtractICStateFromFlags(flags) == MONOMORPHIC);
73  STATIC_ASSERT((Code::ICStateField::kMask & 1) == 1);
74 
75  // Make sure that the code type is not included in the hash.
76  ASSERT(Code::ExtractTypeFromFlags(flags) == 0);
77 
78  // Compute the primary entry.
79  int primary_offset = PrimaryOffset(name, flags, map);
80  Entry* primary = entry(primary_, primary_offset);
81  Code* old_code = primary->value;
82 
83  // If the primary entry has useful data in it, we retire it to the
84  // secondary cache before overwriting it.
85  if (old_code != isolate_->builtins()->builtin(Builtins::kIllegal)) {
86  Map* old_map = primary->map;
87  Code::Flags old_flags = Code::RemoveTypeFromFlags(old_code->flags());
88  int seed = PrimaryOffset(primary->key, old_flags, old_map);
89  int secondary_offset = SecondaryOffset(primary->key, old_flags, seed);
90  Entry* secondary = entry(secondary_, secondary_offset);
91  *secondary = *primary;
92  }
93 
94  // Update primary cache.
95  primary->key = name;
96  primary->value = code;
97  primary->map = map;
98  isolate()->counters()->megamorphic_stub_cache_updates()->Increment();
99  return code;
100 }
101 
102 
103 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name,
104  Handle<JSObject> receiver) {
105  ASSERT(receiver->IsGlobalObject() || receiver->HasFastProperties());
106  // If no global objects are present in the prototype chain, the load
107  // nonexistent IC stub can be shared for all names for a given map
108  // and we use the empty string for the map cache in that case. If
109  // there are global objects involved, we need to check global
110  // property cells in the stub and therefore the stub will be
111  // specific to the name.
112  Handle<String> cache_name = factory()->empty_string();
113  if (receiver->IsGlobalObject()) cache_name = name;
114  Handle<JSObject> last = receiver;
115  while (last->GetPrototype() != heap()->null_value()) {
116  last = Handle<JSObject>(JSObject::cast(last->GetPrototype()));
117  if (last->IsGlobalObject()) cache_name = name;
118  }
119  // Compile the stub that is either shared for all names or
120  // name specific if there are global objects involved.
122  Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT);
123  Handle<Object> probe(receiver->map()->FindInCodeCache(*cache_name, flags));
124  if (probe->IsCode()) return Handle<Code>::cast(probe);
125 
126  LoadStubCompiler compiler(isolate_);
127  Handle<Code> code =
128  compiler.CompileLoadNonexistent(cache_name, receiver, last);
129  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *cache_name));
130  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *cache_name, *code));
131  JSObject::UpdateMapCodeCache(receiver, cache_name, code);
132  return code;
133 }
134 
135 
136 Handle<Code> StubCache::ComputeLoadField(Handle<String> name,
137  Handle<JSObject> receiver,
138  Handle<JSObject> holder,
139  int field_index) {
140  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
141  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD);
142  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
143  if (probe->IsCode()) return Handle<Code>::cast(probe);
144 
145  LoadStubCompiler compiler(isolate_);
146  Handle<Code> code =
147  compiler.CompileLoadField(receiver, holder, field_index, name);
148  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
149  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
150  JSObject::UpdateMapCodeCache(receiver, name, code);
151  return code;
152 }
153 
154 
155 Handle<Code> StubCache::ComputeLoadCallback(Handle<String> name,
156  Handle<JSObject> receiver,
157  Handle<JSObject> holder,
158  Handle<AccessorInfo> callback) {
159  ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
160  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
161  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS);
162  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
163  if (probe->IsCode()) return Handle<Code>::cast(probe);
164 
165  LoadStubCompiler compiler(isolate_);
166  Handle<Code> code =
167  compiler.CompileLoadCallback(name, receiver, holder, callback);
168  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
169  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
170  JSObject::UpdateMapCodeCache(receiver, name, code);
171  return code;
172 }
173 
174 
175 Handle<Code> StubCache::ComputeLoadViaGetter(Handle<String> name,
176  Handle<JSObject> receiver,
177  Handle<JSObject> holder,
178  Handle<JSFunction> getter) {
179  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
180  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS);
181  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
182  if (probe->IsCode()) return Handle<Code>::cast(probe);
183 
184  LoadStubCompiler compiler(isolate_);
185  Handle<Code> code =
186  compiler.CompileLoadViaGetter(name, receiver, holder, getter);
187  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
188  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
189  JSObject::UpdateMapCodeCache(receiver, name, code);
190  return code;
191 }
192 
193 
194 Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name,
195  Handle<JSObject> receiver,
196  Handle<JSObject> holder,
197  Handle<JSFunction> value) {
198  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
200  Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION);
201  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
202  if (probe->IsCode()) return Handle<Code>::cast(probe);
203 
204  LoadStubCompiler compiler(isolate_);
205  Handle<Code> code =
206  compiler.CompileLoadConstant(receiver, holder, value, name);
207  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
208  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
209  JSObject::UpdateMapCodeCache(receiver, name, code);
210  return code;
211 }
212 
213 
214 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name,
215  Handle<JSObject> receiver,
216  Handle<JSObject> holder) {
217  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
218  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR);
219  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
220  if (probe->IsCode()) return Handle<Code>::cast(probe);
221 
222  LoadStubCompiler compiler(isolate_);
223  Handle<Code> code =
224  compiler.CompileLoadInterceptor(receiver, holder, name);
225  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
226  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
227  JSObject::UpdateMapCodeCache(receiver, name, code);
228  return code;
229 }
230 
231 
232 Handle<Code> StubCache::ComputeLoadNormal() {
233  return isolate_->builtins()->LoadIC_Normal();
234 }
235 
236 
237 Handle<Code> StubCache::ComputeLoadGlobal(Handle<String> name,
238  Handle<JSObject> receiver,
239  Handle<GlobalObject> holder,
241  bool is_dont_delete) {
242  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
243  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
244  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
245  if (probe->IsCode()) return Handle<Code>::cast(probe);
246 
247  LoadStubCompiler compiler(isolate_);
248  Handle<Code> code =
249  compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete);
250  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
251  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
252  JSObject::UpdateMapCodeCache(receiver, name, code);
253  return code;
254 }
255 
256 
257 Handle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name,
258  Handle<JSObject> receiver,
259  Handle<JSObject> holder,
260  int field_index) {
261  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
262  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD);
263  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
264  if (probe->IsCode()) return Handle<Code>::cast(probe);
265 
266  KeyedLoadStubCompiler compiler(isolate_);
267  Handle<Code> code =
268  compiler.CompileLoadField(name, receiver, holder, field_index);
269  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
270  GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
271  JSObject::UpdateMapCodeCache(receiver, name, code);
272  return code;
273 }
274 
275 
276 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name,
277  Handle<JSObject> receiver,
278  Handle<JSObject> holder,
279  Handle<JSFunction> value) {
280  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
282  Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION);
283  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
284  if (probe->IsCode()) return Handle<Code>::cast(probe);
285 
286  KeyedLoadStubCompiler compiler(isolate_);
287  Handle<Code> code =
288  compiler.CompileLoadConstant(name, receiver, holder, value);
289  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
290  GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
291  JSObject::UpdateMapCodeCache(receiver, name, code);
292  return code;
293 }
294 
295 
296 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name,
297  Handle<JSObject> receiver,
298  Handle<JSObject> holder) {
299  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
301  Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR);
302  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
303  if (probe->IsCode()) return Handle<Code>::cast(probe);
304 
305  KeyedLoadStubCompiler compiler(isolate_);
306  Handle<Code> code = compiler.CompileLoadInterceptor(receiver, holder, name);
307  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
308  GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
309  JSObject::UpdateMapCodeCache(receiver, name, code);
310  return code;
311 }
312 
313 
314 Handle<Code> StubCache::ComputeKeyedLoadCallback(
316  Handle<JSObject> receiver,
317  Handle<JSObject> holder,
318  Handle<AccessorInfo> callback) {
319  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
321  Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
322  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
323  if (probe->IsCode()) return Handle<Code>::cast(probe);
324 
325  KeyedLoadStubCompiler compiler(isolate_);
326  Handle<Code> code =
327  compiler.CompileLoadCallback(name, receiver, holder, callback);
328  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
329  GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
330  JSObject::UpdateMapCodeCache(receiver, name, code);
331  return code;
332 }
333 
334 
335 Handle<Code> StubCache::ComputeKeyedLoadArrayLength(Handle<String> name,
336  Handle<JSArray> receiver) {
338  Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
339  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
340  if (probe->IsCode()) return Handle<Code>::cast(probe);
341 
342  KeyedLoadStubCompiler compiler(isolate_);
343  Handle<Code> code = compiler.CompileLoadArrayLength(name);
344  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
345  GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
346  JSObject::UpdateMapCodeCache(receiver, name, code);
347  return code;
348 }
349 
350 
351 Handle<Code> StubCache::ComputeKeyedLoadStringLength(Handle<String> name,
352  Handle<String> receiver) {
354  Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
355  Handle<Map> map(receiver->map());
356  Handle<Object> probe(map->FindInCodeCache(*name, flags));
357  if (probe->IsCode()) return Handle<Code>::cast(probe);
358 
359  KeyedLoadStubCompiler compiler(isolate_);
360  Handle<Code> code = compiler.CompileLoadStringLength(name);
361  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
362  GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
363  Map::UpdateCodeCache(map, name, code);
364  return code;
365 }
366 
367 
368 Handle<Code> StubCache::ComputeKeyedLoadFunctionPrototype(
370  Handle<JSFunction> receiver) {
372  Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
373  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
374  if (probe->IsCode()) return Handle<Code>::cast(probe);
375 
376  KeyedLoadStubCompiler compiler(isolate_);
377  Handle<Code> code = compiler.CompileLoadFunctionPrototype(name);
378  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
379  GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
380  JSObject::UpdateMapCodeCache(receiver, name, code);
381  return code;
382 }
383 
384 
385 Handle<Code> StubCache::ComputeStoreField(Handle<String> name,
386  Handle<JSObject> receiver,
387  int field_index,
388  Handle<Map> transition,
389  StrictModeFlag strict_mode) {
390  PropertyType type = (transition.is_null()) ? FIELD : MAP_TRANSITION;
391  Code::Flags flags = Code::ComputeMonomorphicFlags(
392  Code::STORE_IC, type, strict_mode);
393  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
394  if (probe->IsCode()) return Handle<Code>::cast(probe);
395 
396  StoreStubCompiler compiler(isolate_, strict_mode);
397  Handle<Code> code =
398  compiler.CompileStoreField(receiver, field_index, transition, name);
399  PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
400  GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
401  JSObject::UpdateMapCodeCache(receiver, name, code);
402  return code;
403 }
404 
405 
406 Handle<Code> StubCache::ComputeKeyedLoadOrStoreElement(
407  Handle<Map> receiver_map,
408  KeyedIC::StubKind stub_kind,
409  StrictModeFlag strict_mode) {
410  KeyedAccessGrowMode grow_mode =
411  KeyedIC::GetGrowModeFromStubKind(stub_kind);
412  Code::ExtraICState extra_state =
413  Code::ComputeExtraICState(grow_mode, strict_mode);
415  Code::ComputeMonomorphicFlags(
416  stub_kind == KeyedIC::LOAD ? Code::KEYED_LOAD_IC
417  : Code::KEYED_STORE_IC,
418  NORMAL,
419  extra_state);
421  switch (stub_kind) {
422  case KeyedIC::LOAD:
423  name = isolate()->factory()->KeyedLoadElementMonomorphic_symbol();
424  break;
425  case KeyedIC::STORE_NO_TRANSITION:
426  name = isolate()->factory()->KeyedStoreElementMonomorphic_symbol();
427  break;
428  case KeyedIC::STORE_AND_GROW_NO_TRANSITION:
429  name = isolate()->factory()->KeyedStoreAndGrowElementMonomorphic_symbol();
430  break;
431  default:
432  UNREACHABLE();
433  break;
434  }
435  Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags));
436  if (probe->IsCode()) return Handle<Code>::cast(probe);
437 
438  Handle<Code> code;
439  switch (stub_kind) {
440  case KeyedIC::LOAD: {
441  KeyedLoadStubCompiler compiler(isolate_);
442  code = compiler.CompileLoadElement(receiver_map);
443  break;
444  }
445  case KeyedIC::STORE_AND_GROW_NO_TRANSITION: {
446  KeyedStoreStubCompiler compiler(isolate_, strict_mode,
448  code = compiler.CompileStoreElement(receiver_map);
449  break;
450  }
451  case KeyedIC::STORE_NO_TRANSITION: {
452  KeyedStoreStubCompiler compiler(isolate_, strict_mode,
454  code = compiler.CompileStoreElement(receiver_map);
455  break;
456  }
457  default:
458  UNREACHABLE();
459  break;
460  }
461 
462  ASSERT(!code.is_null());
463 
464  if (stub_kind == KeyedIC::LOAD) {
465  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, 0));
466  } else {
467  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, 0));
468  }
469  Map::UpdateCodeCache(receiver_map, name, code);
470  return code;
471 }
472 
473 
474 Handle<Code> StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) {
475  return (strict_mode == kStrictMode)
476  ? isolate_->builtins()->Builtins::StoreIC_Normal_Strict()
477  : isolate_->builtins()->Builtins::StoreIC_Normal();
478 }
479 
480 
481 Handle<Code> StubCache::ComputeStoreGlobal(Handle<String> name,
482  Handle<GlobalObject> receiver,
484  StrictModeFlag strict_mode) {
485  Code::Flags flags = Code::ComputeMonomorphicFlags(
486  Code::STORE_IC, NORMAL, strict_mode);
487  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
488  if (probe->IsCode()) return Handle<Code>::cast(probe);
489 
490  StoreStubCompiler compiler(isolate_, strict_mode);
491  Handle<Code> code = compiler.CompileStoreGlobal(receiver, cell, name);
492  PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
493  GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
494  JSObject::UpdateMapCodeCache(receiver, name, code);
495  return code;
496 }
497 
498 
499 Handle<Code> StubCache::ComputeStoreCallback(Handle<String> name,
500  Handle<JSObject> receiver,
501  Handle<AccessorInfo> callback,
502  StrictModeFlag strict_mode) {
503  ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
504  Code::Flags flags = Code::ComputeMonomorphicFlags(
505  Code::STORE_IC, CALLBACKS, strict_mode);
506  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
507  if (probe->IsCode()) return Handle<Code>::cast(probe);
508 
509  StoreStubCompiler compiler(isolate_, strict_mode);
510  Handle<Code> code = compiler.CompileStoreCallback(receiver, callback, name);
511  PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
512  GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
513  JSObject::UpdateMapCodeCache(receiver, name, code);
514  return code;
515 }
516 
517 
518 Handle<Code> StubCache::ComputeStoreViaSetter(Handle<String> name,
519  Handle<JSObject> receiver,
520  Handle<JSFunction> setter,
521  StrictModeFlag strict_mode) {
522  Code::Flags flags = Code::ComputeMonomorphicFlags(
523  Code::STORE_IC, CALLBACKS, strict_mode);
524  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
525  if (probe->IsCode()) return Handle<Code>::cast(probe);
526 
527  StoreStubCompiler compiler(isolate_, strict_mode);
528  Handle<Code> code = compiler.CompileStoreViaSetter(receiver, setter, name);
529  PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
530  GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
531  JSObject::UpdateMapCodeCache(receiver, name, code);
532  return code;
533 }
534 
535 
536 Handle<Code> StubCache::ComputeStoreInterceptor(Handle<String> name,
537  Handle<JSObject> receiver,
538  StrictModeFlag strict_mode) {
539  Code::Flags flags = Code::ComputeMonomorphicFlags(
540  Code::STORE_IC, INTERCEPTOR, strict_mode);
541  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
542  if (probe->IsCode()) return Handle<Code>::cast(probe);
543 
544  StoreStubCompiler compiler(isolate_, strict_mode);
545  Handle<Code> code = compiler.CompileStoreInterceptor(receiver, name);
546  PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
547  GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
548  JSObject::UpdateMapCodeCache(receiver, name, code);
549  return code;
550 }
551 
552 Handle<Code> StubCache::ComputeKeyedStoreField(Handle<String> name,
553  Handle<JSObject> receiver,
554  int field_index,
555  Handle<Map> transition,
556  StrictModeFlag strict_mode) {
557  PropertyType type = (transition.is_null()) ? FIELD : MAP_TRANSITION;
558  Code::Flags flags = Code::ComputeMonomorphicFlags(
559  Code::KEYED_STORE_IC, type, strict_mode);
560  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
561  if (probe->IsCode()) return Handle<Code>::cast(probe);
562 
563  KeyedStoreStubCompiler compiler(isolate(), strict_mode,
565  Handle<Code> code =
566  compiler.CompileStoreField(receiver, field_index, transition, name);
567  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name));
568  GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
569  JSObject::UpdateMapCodeCache(receiver, name, code);
570  return code;
571 }
572 
573 
574 #define CALL_LOGGER_TAG(kind, type) \
575  (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
576 
577 Handle<Code> StubCache::ComputeCallConstant(int argc,
578  Code::Kind kind,
579  Code::ExtraICState extra_state,
581  Handle<Object> object,
582  Handle<JSObject> holder,
583  Handle<JSFunction> function) {
584  // Compute the check type and the map.
585  InlineCacheHolderFlag cache_holder =
586  IC::GetCodeCacheForObject(*object, *holder);
587  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder));
588 
589  // Compute check type based on receiver/holder.
591  if (object->IsString()) {
592  check = STRING_CHECK;
593  } else if (object->IsNumber()) {
594  check = NUMBER_CHECK;
595  } else if (object->IsBoolean()) {
596  check = BOOLEAN_CHECK;
597  }
598 
600  Code::ComputeMonomorphicFlags(kind, CONSTANT_FUNCTION, extra_state,
601  cache_holder, argc);
602  Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
603  if (probe->IsCode()) return Handle<Code>::cast(probe);
604 
605  CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
606  Handle<Code> code =
607  compiler.CompileCallConstant(object, holder, function, name, check);
608  code->set_check_type(check);
609  ASSERT_EQ(flags, code->flags());
610  PROFILE(isolate_,
611  CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
612  GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
613  JSObject::UpdateMapCodeCache(map_holder, name, code);
614  return code;
615 }
616 
617 
618 Handle<Code> StubCache::ComputeCallField(int argc,
619  Code::Kind kind,
620  Code::ExtraICState extra_state,
622  Handle<Object> object,
623  Handle<JSObject> holder,
624  int index) {
625  // Compute the check type and the map.
626  InlineCacheHolderFlag cache_holder =
627  IC::GetCodeCacheForObject(*object, *holder);
628  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder));
629 
630  // TODO(1233596): We cannot do receiver map check for non-JS objects
631  // because they may be represented as immediates without a
632  // map. Instead, we check against the map in the holder.
633  if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
634  object = holder;
635  }
636 
638  Code::ComputeMonomorphicFlags(kind, FIELD, extra_state,
639  cache_holder, argc);
640  Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
641  if (probe->IsCode()) return Handle<Code>::cast(probe);
642 
643  CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
644  Handle<Code> code =
645  compiler.CompileCallField(Handle<JSObject>::cast(object),
646  holder, index, name);
647  ASSERT_EQ(flags, code->flags());
648  PROFILE(isolate_,
649  CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
650  GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
651  JSObject::UpdateMapCodeCache(map_holder, name, code);
652  return code;
653 }
654 
655 
656 Handle<Code> StubCache::ComputeCallInterceptor(int argc,
657  Code::Kind kind,
658  Code::ExtraICState extra_state,
660  Handle<Object> object,
661  Handle<JSObject> holder) {
662  // Compute the check type and the map.
663  InlineCacheHolderFlag cache_holder =
664  IC::GetCodeCacheForObject(*object, *holder);
665  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder));
666 
667  // TODO(1233596): We cannot do receiver map check for non-JS objects
668  // because they may be represented as immediates without a
669  // map. Instead, we check against the map in the holder.
670  if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
671  object = holder;
672  }
673 
675  Code::ComputeMonomorphicFlags(kind, INTERCEPTOR, extra_state,
676  cache_holder, argc);
677  Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
678  if (probe->IsCode()) return Handle<Code>::cast(probe);
679 
680  CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
681  Handle<Code> code =
683  holder, name);
684  ASSERT_EQ(flags, code->flags());
685  PROFILE(isolate(),
686  CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
687  GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
688  JSObject::UpdateMapCodeCache(map_holder, name, code);
689  return code;
690 }
691 
692 
693 Handle<Code> StubCache::ComputeCallGlobal(int argc,
694  Code::Kind kind,
695  Code::ExtraICState extra_state,
697  Handle<JSObject> receiver,
698  Handle<GlobalObject> holder,
700  Handle<JSFunction> function) {
701  InlineCacheHolderFlag cache_holder =
702  IC::GetCodeCacheForObject(*receiver, *holder);
703  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
705  Code::ComputeMonomorphicFlags(kind, NORMAL, extra_state,
706  cache_holder, argc);
707  Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
708  if (probe->IsCode()) return Handle<Code>::cast(probe);
709 
710  CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
711  Handle<Code> code =
712  compiler.CompileCallGlobal(receiver, holder, cell, function, name);
713  ASSERT_EQ(flags, code->flags());
714  PROFILE(isolate(),
715  CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
716  GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
717  JSObject::UpdateMapCodeCache(map_holder, name, code);
718  return code;
719 }
720 
721 
722 static void FillCache(Isolate* isolate, Handle<Code> code) {
724  UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(),
725  code->flags(),
726  code);
727  isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
728 }
729 
730 
731 Code* StubCache::FindCallInitialize(int argc,
732  RelocInfo::Mode mode,
733  Code::Kind kind) {
734  Code::ExtraICState extra_state =
735  CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
736  CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
738  Code::ComputeFlags(kind, UNINITIALIZED, extra_state, NORMAL, argc);
739 
740  // Use raw_unchecked... so we don't get assert failures during GC.
741  UnseededNumberDictionary* dictionary =
742  isolate()->heap()->raw_unchecked_non_monomorphic_cache();
743  int entry = dictionary->FindEntry(isolate(), flags);
744  ASSERT(entry != -1);
745  Object* code = dictionary->ValueAt(entry);
746  // This might be called during the marking phase of the collector
747  // hence the unchecked cast.
748  return reinterpret_cast<Code*>(code);
749 }
750 
751 
752 Handle<Code> StubCache::ComputeCallInitialize(int argc,
753  RelocInfo::Mode mode,
754  Code::Kind kind) {
755  Code::ExtraICState extra_state =
756  CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
757  CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
759  Code::ComputeFlags(kind, UNINITIALIZED, extra_state, NORMAL, argc);
761  isolate_->factory()->non_monomorphic_cache();
762  int entry = cache->FindEntry(isolate_, flags);
763  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
764 
765  StubCompiler compiler(isolate_);
766  Handle<Code> code = compiler.CompileCallInitialize(flags);
767  FillCache(isolate_, code);
768  return code;
769 }
770 
771 
772 Handle<Code> StubCache::ComputeCallInitialize(int argc, RelocInfo::Mode mode) {
773  return ComputeCallInitialize(argc, mode, Code::CALL_IC);
774 }
775 
776 
777 Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc) {
778  return ComputeCallInitialize(argc, RelocInfo::CODE_TARGET,
779  Code::KEYED_CALL_IC);
780 }
781 
782 
783 Handle<Code> StubCache::ComputeCallPreMonomorphic(
784  int argc,
785  Code::Kind kind,
786  Code::ExtraICState extra_state) {
787  Code::Flags flags =
788  Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, NORMAL, argc);
790  isolate_->factory()->non_monomorphic_cache();
791  int entry = cache->FindEntry(isolate_, flags);
792  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
793 
794  StubCompiler compiler(isolate_);
795  Handle<Code> code = compiler.CompileCallPreMonomorphic(flags);
796  FillCache(isolate_, code);
797  return code;
798 }
799 
800 
801 Handle<Code> StubCache::ComputeCallNormal(int argc,
802  Code::Kind kind,
803  Code::ExtraICState extra_state) {
804  Code::Flags flags =
805  Code::ComputeFlags(kind, MONOMORPHIC, extra_state, NORMAL, argc);
807  isolate_->factory()->non_monomorphic_cache();
808  int entry = cache->FindEntry(isolate_, flags);
809  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
810 
811  StubCompiler compiler(isolate_);
812  Handle<Code> code = compiler.CompileCallNormal(flags);
813  FillCache(isolate_, code);
814  return code;
815 }
816 
817 
818 Handle<Code> StubCache::ComputeCallArguments(int argc, Code::Kind kind) {
819  ASSERT(kind == Code::KEYED_CALL_IC);
820  Code::Flags flags =
821  Code::ComputeFlags(kind, MEGAMORPHIC, Code::kNoExtraICState,
822  NORMAL, argc);
824  isolate_->factory()->non_monomorphic_cache();
825  int entry = cache->FindEntry(isolate_, flags);
826  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
827 
828  StubCompiler compiler(isolate_);
829  Handle<Code> code = compiler.CompileCallArguments(flags);
830  FillCache(isolate_, code);
831  return code;
832 }
833 
834 
835 Handle<Code> StubCache::ComputeCallMegamorphic(
836  int argc,
837  Code::Kind kind,
838  Code::ExtraICState extra_state) {
839  Code::Flags flags =
840  Code::ComputeFlags(kind, MEGAMORPHIC, extra_state,
841  NORMAL, argc);
843  isolate_->factory()->non_monomorphic_cache();
844  int entry = cache->FindEntry(isolate_, flags);
845  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
846 
847  StubCompiler compiler(isolate_);
848  Handle<Code> code = compiler.CompileCallMegamorphic(flags);
849  FillCache(isolate_, code);
850  return code;
851 }
852 
853 
854 Handle<Code> StubCache::ComputeCallMiss(int argc,
855  Code::Kind kind,
856  Code::ExtraICState extra_state) {
857  // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs
858  // and monomorphic stubs are not mixed up together in the stub cache.
859  Code::Flags flags =
860  Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state,
861  NORMAL, argc, OWN_MAP);
863  isolate_->factory()->non_monomorphic_cache();
864  int entry = cache->FindEntry(isolate_, flags);
865  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
866 
867  StubCompiler compiler(isolate_);
868  Handle<Code> code = compiler.CompileCallMiss(flags);
869  FillCache(isolate_, code);
870  return code;
871 }
872 
873 
874 #ifdef ENABLE_DEBUGGER_SUPPORT
875 Handle<Code> StubCache::ComputeCallDebugBreak(int argc,
876  Code::Kind kind) {
877  // Extra IC state is irrelevant for debug break ICs. They jump to
878  // the actual call ic to carry out the work.
879  Code::Flags flags =
880  Code::ComputeFlags(kind, DEBUG_BREAK, Code::kNoExtraICState,
881  NORMAL, argc);
883  isolate_->factory()->non_monomorphic_cache();
884  int entry = cache->FindEntry(isolate_, flags);
885  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
886 
887  StubCompiler compiler(isolate_);
888  Handle<Code> code = compiler.CompileCallDebugBreak(flags);
889  FillCache(isolate_, code);
890  return code;
891 }
892 
893 
894 Handle<Code> StubCache::ComputeCallDebugPrepareStepIn(int argc,
895  Code::Kind kind) {
896  // Extra IC state is irrelevant for debug break ICs. They jump to
897  // the actual call ic to carry out the work.
898  Code::Flags flags =
899  Code::ComputeFlags(kind, DEBUG_PREPARE_STEP_IN, Code::kNoExtraICState,
900  NORMAL, argc);
902  isolate_->factory()->non_monomorphic_cache();
903  int entry = cache->FindEntry(isolate_, flags);
904  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
905 
906  StubCompiler compiler(isolate_);
907  Handle<Code> code = compiler.CompileCallDebugPrepareStepIn(flags);
908  FillCache(isolate_, code);
909  return code;
910 }
911 #endif
912 
913 
914 void StubCache::Clear() {
915  Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal);
916  for (int i = 0; i < kPrimaryTableSize; i++) {
917  primary_[i].key = heap()->empty_string();
918  primary_[i].value = empty;
919  }
920  for (int j = 0; j < kSecondaryTableSize; j++) {
921  secondary_[j].key = heap()->empty_string();
922  secondary_[j].value = empty;
923  }
924 }
925 
926 
927 void StubCache::CollectMatchingMaps(SmallMapList* types,
928  String* name,
929  Code::Flags flags,
930  Handle<Context> global_context) {
931  for (int i = 0; i < kPrimaryTableSize; i++) {
932  if (primary_[i].key == name) {
933  Map* map = primary_[i].value->FindFirstMap();
934  // Map can be NULL, if the stub is constant function call
935  // with a primitive receiver.
936  if (map == NULL) continue;
937 
938  int offset = PrimaryOffset(name, flags, map);
939  if (entry(primary_, offset) == &primary_[i] &&
940  !TypeFeedbackOracle::CanRetainOtherContext(map, *global_context)) {
941  types->Add(Handle<Map>(map), zone());
942  }
943  }
944  }
945 
946  for (int i = 0; i < kSecondaryTableSize; i++) {
947  if (secondary_[i].key == name) {
948  Map* map = secondary_[i].value->FindFirstMap();
949  // Map can be NULL, if the stub is constant function call
950  // with a primitive receiver.
951  if (map == NULL) continue;
952 
953  // Lookup in primary table and skip duplicates.
954  int primary_offset = PrimaryOffset(name, flags, map);
955  Entry* primary_entry = entry(primary_, primary_offset);
956  if (primary_entry->key == name) {
957  Map* primary_map = primary_entry->value->FindFirstMap();
958  if (map == primary_map) continue;
959  }
960 
961  // Lookup in secondary table and add matches.
962  int offset = SecondaryOffset(name, flags, primary_offset);
963  if (entry(secondary_, offset) == &secondary_[i] &&
964  !TypeFeedbackOracle::CanRetainOtherContext(map, *global_context)) {
965  types->Add(Handle<Map>(map), zone());
966  }
967  }
968  }
969 }
970 
971 
972 // ------------------------------------------------------------------------
973 // StubCompiler implementation.
974 
975 
976 RUNTIME_FUNCTION(MaybeObject*, LoadCallbackProperty) {
977  ASSERT(args[0]->IsJSObject());
978  ASSERT(args[1]->IsJSObject());
979  ASSERT(args[3]->IsSmi());
980  AccessorInfo* callback = AccessorInfo::cast(args[4]);
981  Address getter_address = v8::ToCData<Address>(callback->getter());
982  v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address);
983  ASSERT(fun != NULL);
984  ASSERT(callback->IsCompatibleReceiver(args[0]));
985  v8::AccessorInfo info(&args[0]);
986  HandleScope scope(isolate);
987  v8::Handle<v8::Value> result;
988  {
989  // Leaving JavaScript.
990  VMState state(isolate, EXTERNAL);
991  ExternalCallbackScope call_scope(isolate, getter_address);
992  result = fun(v8::Utils::ToLocal(args.at<String>(5)), info);
993  }
995  if (result.IsEmpty()) return HEAP->undefined_value();
996  return *v8::Utils::OpenHandle(*result);
997 }
998 
999 
1000 RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty) {
1001  JSObject* recv = JSObject::cast(args[0]);
1002  AccessorInfo* callback = AccessorInfo::cast(args[1]);
1003  Address setter_address = v8::ToCData<Address>(callback->setter());
1004  v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address);
1005  ASSERT(fun != NULL);
1006  ASSERT(callback->IsCompatibleReceiver(recv));
1007  Handle<String> name = args.at<String>(2);
1008  Handle<Object> value = args.at<Object>(3);
1009  HandleScope scope(isolate);
1010  LOG(isolate, ApiNamedPropertyAccess("store", recv, *name));
1011  CustomArguments custom_args(isolate, callback->data(), recv, recv);
1012  v8::AccessorInfo info(custom_args.end());
1013  {
1014  // Leaving JavaScript.
1015  VMState state(isolate, EXTERNAL);
1016  ExternalCallbackScope call_scope(isolate, setter_address);
1017  fun(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), info);
1018  }
1020  return *value;
1021 }
1022 
1023 
1024 static const int kAccessorInfoOffsetInInterceptorArgs = 2;
1025 
1026 
1034 RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly) {
1035  Handle<String> name_handle = args.at<String>(0);
1036  Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(1);
1037  ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2);
1038  ASSERT(args[2]->IsJSObject()); // Receiver.
1039  ASSERT(args[3]->IsJSObject()); // Holder.
1040  ASSERT(args[5]->IsSmi()); // Isolate.
1041  ASSERT(args.length() == 6);
1042 
1043  Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
1044  v8::NamedPropertyGetter getter =
1045  FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address);
1046  ASSERT(getter != NULL);
1047 
1048  {
1049  // Use the interceptor getter.
1050  v8::AccessorInfo info(args.arguments() -
1051  kAccessorInfoOffsetInInterceptorArgs);
1052  HandleScope scope(isolate);
1054  {
1055  // Leaving JavaScript.
1056  VMState state(isolate, EXTERNAL);
1057  r = getter(v8::Utils::ToLocal(name_handle), info);
1058  }
1060  if (!r.IsEmpty()) {
1061  return *v8::Utils::OpenHandle(*r);
1062  }
1063  }
1064 
1065  return isolate->heap()->no_interceptor_result_sentinel();
1066 }
1067 
1068 
1069 static MaybeObject* ThrowReferenceError(String* name) {
1070  // If the load is non-contextual, just return the undefined result.
1071  // Note that both keyed and non-keyed loads may end up here, so we
1072  // can't use either LoadIC or KeyedLoadIC constructors.
1073  IC ic(IC::NO_EXTRA_FRAME, Isolate::Current());
1074  ASSERT(ic.target()->is_load_stub() || ic.target()->is_keyed_load_stub());
1075  if (!ic.SlowIsContextual()) return HEAP->undefined_value();
1076 
1077  // Throw a reference error.
1078  HandleScope scope;
1079  Handle<String> name_handle(name);
1080  Handle<Object> error =
1081  FACTORY->NewReferenceError("not_defined",
1082  HandleVector(&name_handle, 1));
1083  return Isolate::Current()->Throw(*error);
1084 }
1085 
1086 
1087 static MaybeObject* LoadWithInterceptor(Arguments* args,
1088  PropertyAttributes* attrs) {
1089  Handle<String> name_handle = args->at<String>(0);
1090  Handle<InterceptorInfo> interceptor_info = args->at<InterceptorInfo>(1);
1091  ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2);
1092  Handle<JSObject> receiver_handle = args->at<JSObject>(2);
1093  Handle<JSObject> holder_handle = args->at<JSObject>(3);
1094  ASSERT(args->length() == 6);
1095 
1096  Isolate* isolate = receiver_handle->GetIsolate();
1097 
1098  Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
1099  v8::NamedPropertyGetter getter =
1100  FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address);
1101  ASSERT(getter != NULL);
1102 
1103  {
1104  // Use the interceptor getter.
1105  v8::AccessorInfo info(args->arguments() -
1106  kAccessorInfoOffsetInInterceptorArgs);
1107  HandleScope scope(isolate);
1109  {
1110  // Leaving JavaScript.
1111  VMState state(isolate, EXTERNAL);
1112  r = getter(v8::Utils::ToLocal(name_handle), info);
1113  }
1115  if (!r.IsEmpty()) {
1116  *attrs = NONE;
1117  return *v8::Utils::OpenHandle(*r);
1118  }
1119  }
1120 
1121  MaybeObject* result = holder_handle->GetPropertyPostInterceptor(
1122  *receiver_handle,
1123  *name_handle,
1124  attrs);
1126  return result;
1127 }
1128 
1129 
1134 RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad) {
1135  PropertyAttributes attr = NONE;
1136  Object* result;
1137  { MaybeObject* maybe_result = LoadWithInterceptor(&args, &attr);
1138  if (!maybe_result->ToObject(&result)) return maybe_result;
1139  }
1140 
1141  // If the property is present, return it.
1142  if (attr != ABSENT) return result;
1143  return ThrowReferenceError(String::cast(args[0]));
1144 }
1145 
1146 
1147 RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) {
1148  PropertyAttributes attr;
1149  MaybeObject* result = LoadWithInterceptor(&args, &attr);
1151  // This is call IC. In this case, we simply return the undefined result which
1152  // will lead to an exception when trying to invoke the result as a
1153  // function.
1154  return result;
1155 }
1156 
1157 
1158 RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) {
1159  ASSERT(args.length() == 4);
1160  JSObject* recv = JSObject::cast(args[0]);
1161  String* name = String::cast(args[1]);
1162  Object* value = args[2];
1163  ASSERT(args.smi_at(3) == kStrictMode || args.smi_at(3) == kNonStrictMode);
1164  StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3));
1165  ASSERT(recv->HasNamedInterceptor());
1166  PropertyAttributes attr = NONE;
1167  MaybeObject* result = recv->SetPropertyWithInterceptor(
1168  name, value, attr, strict_mode);
1169  return result;
1170 }
1171 
1172 
1173 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) {
1174  JSObject* receiver = JSObject::cast(args[0]);
1175  ASSERT(args.smi_at(1) >= 0);
1176  uint32_t index = args.smi_at(1);
1177  return receiver->GetElementWithInterceptor(receiver, index);
1178 }
1179 
1180 
1181 Handle<Code> StubCompiler::CompileCallInitialize(Code::Flags flags) {
1182  int argc = Code::ExtractArgumentsCountFromFlags(flags);
1183  Code::Kind kind = Code::ExtractKindFromFlags(flags);
1184  Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1185  if (kind == Code::CALL_IC) {
1186  CallIC::GenerateInitialize(masm(), argc, extra_state);
1187  } else {
1188  KeyedCallIC::GenerateInitialize(masm(), argc);
1189  }
1190  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallInitialize");
1191  isolate()->counters()->call_initialize_stubs()->Increment();
1192  PROFILE(isolate(),
1193  CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG),
1194  *code, code->arguments_count()));
1195  GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, *code));
1196  return code;
1197 }
1198 
1199 
1200 Handle<Code> StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) {
1201  int argc = Code::ExtractArgumentsCountFromFlags(flags);
1202  // The code of the PreMonomorphic stub is the same as the code
1203  // of the Initialized stub. They just differ on the code object flags.
1204  Code::Kind kind = Code::ExtractKindFromFlags(flags);
1205  Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1206  if (kind == Code::CALL_IC) {
1207  CallIC::GenerateInitialize(masm(), argc, extra_state);
1208  } else {
1209  KeyedCallIC::GenerateInitialize(masm(), argc);
1210  }
1211  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallPreMonomorphic");
1212  isolate()->counters()->call_premonomorphic_stubs()->Increment();
1213  PROFILE(isolate(),
1214  CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG),
1215  *code, code->arguments_count()));
1216  GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, *code));
1217  return code;
1218 }
1219 
1220 
1221 Handle<Code> StubCompiler::CompileCallNormal(Code::Flags flags) {
1222  int argc = Code::ExtractArgumentsCountFromFlags(flags);
1223  Code::Kind kind = Code::ExtractKindFromFlags(flags);
1224  if (kind == Code::CALL_IC) {
1225  // Call normal is always with a explict receiver.
1226  ASSERT(!CallIC::Contextual::decode(
1227  Code::ExtractExtraICStateFromFlags(flags)));
1228  CallIC::GenerateNormal(masm(), argc);
1229  } else {
1230  KeyedCallIC::GenerateNormal(masm(), argc);
1231  }
1232  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallNormal");
1233  isolate()->counters()->call_normal_stubs()->Increment();
1234  PROFILE(isolate(),
1235  CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG),
1236  *code, code->arguments_count()));
1237  GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, *code));
1238  return code;
1239 }
1240 
1241 
1242 Handle<Code> StubCompiler::CompileCallMegamorphic(Code::Flags flags) {
1243  int argc = Code::ExtractArgumentsCountFromFlags(flags);
1244  Code::Kind kind = Code::ExtractKindFromFlags(flags);
1245  Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1246  if (kind == Code::CALL_IC) {
1247  CallIC::GenerateMegamorphic(masm(), argc, extra_state);
1248  } else {
1249  KeyedCallIC::GenerateMegamorphic(masm(), argc);
1250  }
1251  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMegamorphic");
1252  isolate()->counters()->call_megamorphic_stubs()->Increment();
1253  PROFILE(isolate(),
1254  CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG),
1255  *code, code->arguments_count()));
1256  GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code));
1257  return code;
1258 }
1259 
1260 
1261 Handle<Code> StubCompiler::CompileCallArguments(Code::Flags flags) {
1262  int argc = Code::ExtractArgumentsCountFromFlags(flags);
1263  KeyedCallIC::GenerateNonStrictArguments(masm(), argc);
1264  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallArguments");
1265  PROFILE(isolate(),
1266  CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags),
1267  CALL_MEGAMORPHIC_TAG),
1268  *code, code->arguments_count()));
1269  GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code));
1270  return code;
1271 }
1272 
1273 
1274 Handle<Code> StubCompiler::CompileCallMiss(Code::Flags flags) {
1275  int argc = Code::ExtractArgumentsCountFromFlags(flags);
1276  Code::Kind kind = Code::ExtractKindFromFlags(flags);
1277  Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1278  if (kind == Code::CALL_IC) {
1279  CallIC::GenerateMiss(masm(), argc, extra_state);
1280  } else {
1281  KeyedCallIC::GenerateMiss(masm(), argc);
1282  }
1283  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMiss");
1284  isolate()->counters()->call_megamorphic_stubs()->Increment();
1285  PROFILE(isolate(),
1286  CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG),
1287  *code, code->arguments_count()));
1288  GDBJIT(AddCode(GDBJITInterface::CALL_MISS, *code));
1289  return code;
1290 }
1291 
1292 
1293 #ifdef ENABLE_DEBUGGER_SUPPORT
1294 Handle<Code> StubCompiler::CompileCallDebugBreak(Code::Flags flags) {
1295  Debug::GenerateCallICDebugBreak(masm());
1296  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugBreak");
1297  PROFILE(isolate(),
1298  CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags),
1299  CALL_DEBUG_BREAK_TAG),
1300  *code, code->arguments_count()));
1301  return code;
1302 }
1303 
1304 
1305 Handle<Code> StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) {
1306  // Use the same code for the the step in preparations as we do for the
1307  // miss case.
1308  int argc = Code::ExtractArgumentsCountFromFlags(flags);
1309  Code::Kind kind = Code::ExtractKindFromFlags(flags);
1310  if (kind == Code::CALL_IC) {
1311  // For the debugger extra ic state is irrelevant.
1312  CallIC::GenerateMiss(masm(), argc, Code::kNoExtraICState);
1313  } else {
1314  KeyedCallIC::GenerateMiss(masm(), argc);
1315  }
1316  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn");
1317  PROFILE(isolate(),
1318  CodeCreateEvent(
1319  CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG),
1320  *code,
1321  code->arguments_count()));
1322  return code;
1323 }
1324 #endif // ENABLE_DEBUGGER_SUPPORT
1325 
1326 #undef CALL_LOGGER_TAG
1327 
1328 
1329 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
1330  const char* name) {
1331  // Create code object in the heap.
1332  CodeDesc desc;
1333  masm_.GetCode(&desc);
1334  Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject());
1335 #ifdef ENABLE_DISASSEMBLER
1336  if (FLAG_print_code_stubs) code->Disassemble(name);
1337 #endif
1338  return code;
1339 }
1340 
1341 
1342 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
1343  Handle<String> name) {
1344  return (FLAG_print_code_stubs && !name.is_null())
1345  ? GetCodeWithFlags(flags, *name->ToCString())
1346  : GetCodeWithFlags(flags, reinterpret_cast<char*>(NULL));
1347 }
1348 
1349 
1350 void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder,
1351  Handle<String> name,
1352  LookupResult* lookup) {
1353  holder->LocalLookupRealNamedProperty(*name, lookup);
1354  if (lookup->IsProperty()) return;
1355 
1356  lookup->NotFound();
1357  if (holder->GetPrototype()->IsNull()) return;
1358 
1359  holder->GetPrototype()->Lookup(*name, lookup);
1360 }
1361 
1362 
1363 Handle<Code> LoadStubCompiler::GetCode(PropertyType type, Handle<String> name) {
1364  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type);
1365  Handle<Code> code = GetCodeWithFlags(flags, name);
1366  PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
1367  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
1368  return code;
1369 }
1370 
1371 
1372 Handle<Code> KeyedLoadStubCompiler::GetCode(PropertyType type,
1373  Handle<String> name,
1374  InlineCacheState state) {
1375  Code::Flags flags = Code::ComputeFlags(
1376  Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type);
1377  Handle<Code> code = GetCodeWithFlags(flags, name);
1378  PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
1379  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
1380  return code;
1381 }
1382 
1383 
1384 Handle<Code> StoreStubCompiler::GetCode(PropertyType type,
1385  Handle<String> name) {
1386  Code::Flags flags =
1387  Code::ComputeMonomorphicFlags(Code::STORE_IC, type, strict_mode_);
1388  Handle<Code> code = GetCodeWithFlags(flags, name);
1389  PROFILE(isolate(), CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
1390  GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
1391  return code;
1392 }
1393 
1394 
1395 Handle<Code> KeyedStoreStubCompiler::GetCode(PropertyType type,
1396  Handle<String> name,
1397  InlineCacheState state) {
1398  Code::ExtraICState extra_state =
1399  Code::ComputeExtraICState(grow_mode_, strict_mode_);
1400  Code::Flags flags =
1401  Code::ComputeFlags(Code::KEYED_STORE_IC, state, extra_state, type);
1402  Handle<Code> code = GetCodeWithFlags(flags, name);
1403  PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name));
1404  GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
1405  return code;
1406 }
1407 
1408 
1409 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement(
1410  MacroAssembler* masm) {
1411  KeyedStoreIC::GenerateSlow(masm);
1412 }
1413 
1414 
1415 CallStubCompiler::CallStubCompiler(Isolate* isolate,
1416  int argc,
1417  Code::Kind kind,
1418  Code::ExtraICState extra_state,
1419  InlineCacheHolderFlag cache_holder)
1420  : StubCompiler(isolate),
1421  arguments_(argc),
1422  kind_(kind),
1423  extra_state_(extra_state),
1424  cache_holder_(cache_holder) {
1425 }
1426 
1427 
1429  if (function->shared()->HasBuiltinFunctionId()) {
1430  BuiltinFunctionId id = function->shared()->builtin_function_id();
1431 #define CALL_GENERATOR_CASE(name) if (id == k##name) return true;
1433 #undef CALL_GENERATOR_CASE
1434  }
1435 
1436  CallOptimization optimization(function);
1437  return optimization.is_simple_api_call();
1438 }
1439 
1440 
1441 Handle<Code> CallStubCompiler::CompileCustomCall(
1442  Handle<Object> object,
1443  Handle<JSObject> holder,
1445  Handle<JSFunction> function,
1446  Handle<String> fname) {
1447  ASSERT(HasCustomCallGenerator(function));
1448 
1449  if (function->shared()->HasBuiltinFunctionId()) {
1450  BuiltinFunctionId id = function->shared()->builtin_function_id();
1451 #define CALL_GENERATOR_CASE(name) \
1452  if (id == k##name) { \
1453  return CallStubCompiler::Compile##name##Call(object, \
1454  holder, \
1455  cell, \
1456  function, \
1457  fname); \
1458  }
1460 #undef CALL_GENERATOR_CASE
1461  }
1462  CallOptimization optimization(function);
1463  ASSERT(optimization.is_simple_api_call());
1464  return CompileFastApiCall(optimization,
1465  object,
1466  holder,
1467  cell,
1468  function,
1469  fname);
1470 }
1471 
1472 
1473 Handle<Code> CallStubCompiler::GetCode(PropertyType type, Handle<String> name) {
1474  int argc = arguments_.immediate();
1476  type,
1477  extra_state_,
1478  cache_holder_,
1479  argc);
1480  return GetCodeWithFlags(flags, name);
1481 }
1482 
1483 
1484 Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) {
1485  Handle<String> function_name;
1486  if (function->shared()->name()->IsString()) {
1487  function_name = Handle<String>(String::cast(function->shared()->name()));
1488  }
1489  return GetCode(CONSTANT_FUNCTION, function_name);
1490 }
1491 
1492 
1493 Handle<Code> ConstructStubCompiler::GetCode() {
1495  Handle<Code> code = GetCodeWithFlags(flags, "ConstructStub");
1496  PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, "ConstructStub"));
1497  GDBJIT(AddCode(GDBJITInterface::STUB, "ConstructStub", *code));
1498  return code;
1499 }
1500 
1501 
1502 CallOptimization::CallOptimization(LookupResult* lookup) {
1503  if (lookup->IsFound() &&
1504  lookup->IsCacheable() &&
1505  lookup->type() == CONSTANT_FUNCTION) {
1506  // We only optimize constant function calls.
1507  Initialize(Handle<JSFunction>(lookup->GetConstantFunction()));
1508  } else {
1509  Initialize(Handle<JSFunction>::null());
1510  }
1511 }
1512 
1513 CallOptimization::CallOptimization(Handle<JSFunction> function) {
1514  Initialize(function);
1515 }
1516 
1517 
1518 int CallOptimization::GetPrototypeDepthOfExpectedType(
1519  Handle<JSObject> object,
1520  Handle<JSObject> holder) const {
1521  ASSERT(is_simple_api_call());
1522  if (expected_receiver_type_.is_null()) return 0;
1523  int depth = 0;
1524  while (!object.is_identical_to(holder)) {
1525  if (object->IsInstanceOf(*expected_receiver_type_)) return depth;
1526  object = Handle<JSObject>(JSObject::cast(object->GetPrototype()));
1527  ++depth;
1528  }
1529  if (holder->IsInstanceOf(*expected_receiver_type_)) return depth;
1530  return kInvalidProtoDepth;
1531 }
1532 
1533 
1534 void CallOptimization::Initialize(Handle<JSFunction> function) {
1535  constant_function_ = Handle<JSFunction>::null();
1536  is_simple_api_call_ = false;
1537  expected_receiver_type_ = Handle<FunctionTemplateInfo>::null();
1538  api_call_info_ = Handle<CallHandlerInfo>::null();
1539 
1540  if (function.is_null() || !function->is_compiled()) return;
1541 
1542  constant_function_ = function;
1543  AnalyzePossibleApiFunction(function);
1544 }
1545 
1546 
1547 void CallOptimization::AnalyzePossibleApiFunction(Handle<JSFunction> function) {
1548  if (!function->shared()->IsApiFunction()) return;
1549  Handle<FunctionTemplateInfo> info(function->shared()->get_api_func_data());
1550 
1551  // Require a C++ callback.
1552  if (info->call_code()->IsUndefined()) return;
1553  api_call_info_ =
1554  Handle<CallHandlerInfo>(CallHandlerInfo::cast(info->call_code()));
1555 
1556  // Accept signatures that either have no restrictions at all or
1557  // only have restrictions on the receiver.
1558  if (!info->signature()->IsUndefined()) {
1559  Handle<SignatureInfo> signature =
1560  Handle<SignatureInfo>(SignatureInfo::cast(info->signature()));
1561  if (!signature->args()->IsUndefined()) return;
1562  if (!signature->receiver()->IsUndefined()) {
1563  expected_receiver_type_ =
1564  Handle<FunctionTemplateInfo>(
1565  FunctionTemplateInfo::cast(signature->receiver()));
1566  }
1567  }
1568 
1569  is_simple_api_call_ = true;
1570 }
1571 
1572 
1573 } } // namespace v8::internal
byte * Address
Definition: globals.h:172
MUST_USE_RESULT MaybeObject * GetElementWithInterceptor(Object *receiver, uint32_t index)
Definition: objects.cc:9955
Handle< Code > CompileLoadFunctionPrototype(Handle< String > name)
Handle< Code > CompileLoadCallback(Handle< String > name, Handle< JSObject > object, Handle< JSObject > holder, Handle< AccessorInfo > callback)
static CallHandlerInfo * cast(Object *obj)
Handle< Code > CompileStoreField(Handle< JSObject > object, int index, Handle< Map > transition, Handle< String > name)
#define RETURN_IF_SCHEDULED_EXCEPTION(isolate)
Definition: isolate.h:111
Handle< Code > CompileLoadNonexistent(Handle< String > name, Handle< JSObject > object, Handle< JSObject > last)
static String * cast(Object *obj)
Handle< Code > CompileStoreElement(Handle< Map > receiver_map)
#define LOG(isolate, Call)
Definition: log.h:81
value format" "after each garbage collection") DEFINE_bool(print_cumulative_gc_stat, false, "print cumulative GC statistics in name=value format on exit") DEFINE_bool(trace_gc_verbose, false, "print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false, "report fragmentation for old pointer and data pages") DEFINE_bool(collect_maps, true, "garbage collect maps from which no objects can be reached") DEFINE_bool(flush_code, true, "flush code that we expect not to use again before full gc") DEFINE_bool(incremental_marking, true, "use incremental marking") DEFINE_bool(incremental_marking_steps, true, "do incremental marking steps") DEFINE_bool(trace_incremental_marking, false, "trace progress of the incremental marking") DEFINE_bool(use_idle_notification, true, "Use idle notification to reduce memory footprint.") DEFINE_bool(send_idle_notification, false, "Send idle notifcation between stress runs.") DEFINE_bool(use_ic, true, "use inline caching") DEFINE_bool(native_code_counters, false, "generate extra code for manipulating stats counters") DEFINE_bool(always_compact, false, "Perform compaction on every full GC") DEFINE_bool(lazy_sweeping, true, "Use lazy sweeping for old pointer and data spaces") DEFINE_bool(never_compact, false, "Never perform compaction on full GC-testing only") DEFINE_bool(compact_code_space, true, "Compact code space on full non-incremental collections") DEFINE_bool(cleanup_code_caches_at_gc, true, "Flush inline caches prior to mark compact collection and" "flush code caches in maps during mark compact cycle.") DEFINE_int(random_seed, 0, "Default seed for initializing random generator" "(0, the default, means to use system random).") DEFINE_bool(use_verbose_printer, true, "allows verbose printing") DEFINE_bool(allow_natives_syntax, false, "allow natives syntax") DEFINE_bool(trace_sim, false, "Trace simulator execution") DEFINE_bool(check_icache, false, "Check icache flushes in ARM and MIPS simulator") DEFINE_int(stop_sim_at, 0, "Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8, "Stack alingment in bytes in simulator(4 or 8, 8 is default)") DEFINE_bool(trace_exception, false, "print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false, "preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true, "randomize hashes to avoid predictable hash collisions" "(with snapshots this option cannot override the baked-in seed)") DEFINE_int(hash_seed, 0, "Fixed seed to use to hash property keys(0 means random)" "(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(preemption, false, "activate a 100ms timer that switches between V8 threads") DEFINE_bool(regexp_optimization, true, "generate optimized regexp code") DEFINE_bool(testing_bool_flag, true, "testing_bool_flag") DEFINE_int(testing_int_flag, 13, "testing_int_flag") DEFINE_float(testing_float_flag, 2.5, "float-flag") DEFINE_string(testing_string_flag, "Hello, world!", "string-flag") DEFINE_int(testing_prng_seed, 42, "Seed used for threading test randomness") DEFINE_string(testing_serialization_file, "/tmp/serdes", "file in which to serialize heap") DEFINE_bool(help, false, "Print usage message, including flags, on console") DEFINE_bool(dump_counters, false, "Dump counters on exit") DEFINE_string(map_counters, "", "Map counters to a file") DEFINE_args(js_arguments, JSARGUMENTS_INIT, "Pass all remaining arguments to the script.Alias for\"--\".") DEFINE_bool(debug_compile_events, true,"Enable debugger compile events") DEFINE_bool(debug_script_collected_events, true,"Enable debugger script collected events") DEFINE_bool(gdbjit, false,"enable GDBJIT interface (disables compacting GC)") DEFINE_bool(gdbjit_full, false,"enable GDBJIT interface for all code objects") DEFINE_bool(gdbjit_dump, false,"dump elf objects with debug info to disk") DEFINE_string(gdbjit_dump_filter,"","dump only objects containing this substring") DEFINE_bool(force_marking_deque_overflows, false,"force overflows of marking deque by reducing it's size ""to 64 words") DEFINE_bool(stress_compaction, false,"stress the GC compactor to flush out bugs (implies ""--force_marking_deque_overflows)")#define FLAG DEFINE_bool(enable_slow_asserts, false,"enable asserts that are slow to execute") DEFINE_bool(trace_codegen, false,"print name of functions for which code is generated") DEFINE_bool(print_source, false,"pretty print source code") DEFINE_bool(print_builtin_source, false,"pretty print source code for builtins") DEFINE_bool(print_ast, false,"print source AST") DEFINE_bool(print_builtin_ast, false,"print source AST for builtins") DEFINE_string(stop_at,"","function name where to insert a breakpoint") DEFINE_bool(print_builtin_scopes, false,"print scopes for builtins") DEFINE_bool(print_scopes, false,"print scopes") DEFINE_bool(trace_contexts, false,"trace contexts operations") DEFINE_bool(gc_greedy, false,"perform GC prior to some allocations") DEFINE_bool(gc_verbose, false,"print stuff during garbage collection") DEFINE_bool(heap_stats, false,"report heap statistics before and after GC") DEFINE_bool(code_stats, false,"report code statistics after GC") DEFINE_bool(verify_heap, false,"verify heap pointers before and after GC") DEFINE_bool(print_handles, false,"report handles after GC") DEFINE_bool(print_global_handles, false,"report global handles after GC") DEFINE_bool(trace_ic, false,"trace inline cache state transitions") DEFINE_bool(print_interfaces, false,"print interfaces") DEFINE_bool(print_interface_details, false,"print interface inference details") DEFINE_int(print_interface_depth, 5,"depth for printing interfaces") DEFINE_bool(trace_normalization, false,"prints when objects are turned into dictionaries.") DEFINE_bool(trace_lazy, false,"trace lazy compilation") DEFINE_bool(collect_heap_spill_statistics, false,"report heap spill statistics along with heap_stats ""(requires heap_stats)") DEFINE_bool(trace_isolates, false,"trace isolate state changes") DEFINE_bool(log_state_changes, false,"Log state changes.") DEFINE_bool(regexp_possessive_quantifier, false,"enable possessive quantifier syntax for testing") DEFINE_bool(trace_regexp_bytecodes, false,"trace regexp bytecode execution") DEFINE_bool(trace_regexp_assembler, false,"trace regexp macro assembler calls.")#define FLAG DEFINE_bool(log, false,"Minimal logging (no API, code, GC, suspect, or handles samples).") DEFINE_bool(log_all, false,"Log all events to the log file.") DEFINE_bool(log_runtime, false,"Activate runtime system %Log call.") DEFINE_bool(log_api, false,"Log API events to the log file.") DEFINE_bool(log_code, false,"Log code events to the log file without profiling.") DEFINE_bool(log_gc, false,"Log heap samples on garbage collection for the hp2ps tool.") DEFINE_bool(log_handles, false,"Log global handle events.") DEFINE_bool(log_snapshot_positions, false,"log positions of (de)serialized objects in the snapshot.") DEFINE_bool(log_suspect, false,"Log suspect operations.") DEFINE_bool(prof, false,"Log statistical profiling information (implies --log-code).") DEFINE_bool(prof_auto, true,"Used with --prof, starts profiling automatically") DEFINE_bool(prof_lazy, false,"Used with --prof, only does sampling and logging"" when profiler is active (implies --noprof_auto).") DEFINE_bool(prof_browser_mode, true,"Used with --prof, turns on browser-compatible mode for profiling.") DEFINE_bool(log_regexp, false,"Log regular expression execution.") DEFINE_bool(sliding_state_window, false,"Update sliding state window counters.") DEFINE_string(logfile,"v8.log","Specify the name of the log file.") DEFINE_bool(ll_prof, false,"Enable low-level linux profiler.")#define FLAG DEFINE_bool(trace_elements_transitions, false,"trace elements transitions") DEFINE_bool(print_code_stubs, false,"print code stubs") DEFINE_bool(test_secondary_stub_cache, false,"test secondary stub cache by disabling the primary one") DEFINE_bool(test_primary_stub_cache, false,"test primary stub cache by disabling the secondary one") DEFINE_bool(print_code, false,"print generated code") DEFINE_bool(print_opt_code, false,"print optimized code") DEFINE_bool(print_unopt_code, false,"print unoptimized code before ""printing optimized code based on it") DEFINE_bool(print_code_verbose, false,"print more information for code") DEFINE_bool(print_builtin_code, false,"print generated code for builtins")#43"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flags.cc"2#define FLAG_MODE_DEFINE_DEFAULTS#1"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flag-definitions.h"1#define FLAG_FULL(ftype, ctype, nam, def, cmt)#define FLAG_READONLY(ftype, ctype, nam, def, cmt)#define DEFINE_implication(whenflag, thenflag)#define DEFINE_bool(nam, def, cmt)#define DEFINE_int(nam, def, cmt)#define DEFINE_float(nam, def, cmt)#define DEFINE_string(nam, def, cmt)#define DEFINE_args(nam, def, cmt)#define FLAG DEFINE_bool(use_strict, false,"enforce strict mode") DEFINE_bool(es5_readonly, false,"activate correct semantics for inheriting readonliness") DEFINE_bool(es52_globals, false,"activate new semantics for global var declarations") DEFINE_bool(harmony_typeof, false,"enable harmony semantics for typeof") DEFINE_bool(harmony_scoping, false,"enable harmony block scoping") DEFINE_bool(harmony_modules, false,"enable harmony modules (implies block scoping)") DEFINE_bool(harmony_proxies, false,"enable harmony proxies") DEFINE_bool(harmony_collections, false,"enable harmony collections (sets, maps, and weak maps)") DEFINE_bool(harmony, false,"enable all harmony features (except typeof)") DEFINE_implication(harmony, harmony_scoping) DEFINE_implication(harmony, harmony_modules) DEFINE_implication(harmony, harmony_proxies) DEFINE_implication(harmony, harmony_collections) DEFINE_implication(harmony_modules, harmony_scoping) DEFINE_bool(packed_arrays, false,"optimizes arrays that have no holes") DEFINE_bool(smi_only_arrays, true,"tracks arrays with only smi values") DEFINE_bool(clever_optimizations, true,"Optimize object size, Array shift, DOM strings and string +") DEFINE_bool(unbox_double_arrays, true,"automatically unbox arrays of doubles") DEFINE_bool(string_slices, true,"use string slices") DEFINE_bool(crankshaft, true,"use crankshaft") DEFINE_string(hydrogen_filter,"","optimization filter") DEFINE_bool(use_range, true,"use hydrogen range analysis") DEFINE_bool(eliminate_dead_phis, true,"eliminate dead phis") DEFINE_bool(use_gvn, true,"use hydrogen global value numbering") DEFINE_bool(use_canonicalizing, true,"use hydrogen instruction canonicalizing") DEFINE_bool(use_inlining, true,"use function inlining") DEFINE_int(max_inlined_source_size, 600,"maximum source size in bytes considered for a single inlining") DEFINE_int(max_inlined_nodes, 196,"maximum number of AST nodes considered for a single inlining") DEFINE_int(max_inlined_nodes_cumulative, 196,"maximum cumulative number of AST nodes considered for inlining") DEFINE_bool(loop_invariant_code_motion, true,"loop invariant code motion") DEFINE_bool(collect_megamorphic_maps_from_stub_cache, true,"crankshaft harvests type feedback from stub cache") DEFINE_bool(hydrogen_stats, false,"print statistics for hydrogen") DEFINE_bool(trace_hydrogen, false,"trace generated hydrogen to file") DEFINE_string(trace_phase,"Z","trace generated IR for specified phases") DEFINE_bool(trace_inlining, false,"trace inlining decisions") DEFINE_bool(trace_alloc, false,"trace register allocator") DEFINE_bool(trace_all_uses, false,"trace all use positions") DEFINE_bool(trace_range, false,"trace range analysis") DEFINE_bool(trace_gvn, false,"trace global value numbering") DEFINE_bool(trace_representation, false,"trace representation types") DEFINE_bool(stress_pointer_maps, false,"pointer map for every instruction") DEFINE_bool(stress_environments, false,"environment for every instruction") DEFINE_int(deopt_every_n_times, 0,"deoptimize every n times a deopt point is passed") DEFINE_bool(trap_on_deopt, false,"put a break point before deoptimizing") DEFINE_bool(deoptimize_uncommon_cases, true,"deoptimize uncommon cases") DEFINE_bool(polymorphic_inlining, true,"polymorphic inlining") DEFINE_bool(use_osr, true,"use on-stack replacement") DEFINE_bool(array_bounds_checks_elimination, false,"perform array bounds checks elimination") DEFINE_bool(array_index_dehoisting, false,"perform array index dehoisting") DEFINE_bool(trace_osr, false,"trace on-stack replacement") DEFINE_int(stress_runs, 0,"number of stress runs") DEFINE_bool(optimize_closures, true,"optimize closures") DEFINE_bool(inline_construct, true,"inline constructor calls") DEFINE_bool(inline_arguments, true,"inline functions with arguments object") DEFINE_int(loop_weight, 1,"loop weight for representation inference") DEFINE_bool(optimize_for_in, true,"optimize functions containing for-in loops") DEFINE_bool(experimental_profiler, true,"enable all profiler experiments") DEFINE_bool(watch_ic_patching, false,"profiler considers IC stability") DEFINE_int(frame_count, 1,"number of stack frames inspected by the profiler") DEFINE_bool(self_optimization, false,"primitive functions trigger their own optimization") DEFINE_bool(direct_self_opt, false,"call recompile stub directly when self-optimizing") DEFINE_bool(retry_self_opt, false,"re-try self-optimization if it failed") DEFINE_bool(count_based_interrupts, false,"trigger profiler ticks based on counting instead of timing") DEFINE_bool(interrupt_at_exit, false,"insert an interrupt check at function exit") DEFINE_bool(weighted_back_edges, false,"weight back edges by jump distance for interrupt triggering") DEFINE_int(interrupt_budget, 5900,"execution budget before interrupt is triggered") DEFINE_int(type_info_threshold, 15,"percentage of ICs that must have type info to allow optimization") DEFINE_int(self_opt_count, 130,"call count before self-optimization") DEFINE_implication(experimental_profiler, watch_ic_patching) DEFINE_implication(experimental_profiler, self_optimization) DEFINE_implication(experimental_profiler, retry_self_opt) DEFINE_implication(experimental_profiler, count_based_interrupts) DEFINE_implication(experimental_profiler, interrupt_at_exit) DEFINE_implication(experimental_profiler, weighted_back_edges) DEFINE_bool(trace_opt_verbose, false,"extra verbose compilation tracing") DEFINE_implication(trace_opt_verbose, trace_opt) DEFINE_bool(debug_code, false,"generate extra code (assertions) for debugging") DEFINE_bool(code_comments, false,"emit comments in code disassembly") DEFINE_bool(enable_sse2, true,"enable use of SSE2 instructions if available") DEFINE_bool(enable_sse3, true,"enable use of SSE3 instructions if available") DEFINE_bool(enable_sse4_1, true,"enable use of SSE4.1 instructions if available") DEFINE_bool(enable_cmov, true,"enable use of CMOV instruction if available") DEFINE_bool(enable_rdtsc, true,"enable use of RDTSC instruction if available") DEFINE_bool(enable_sahf, true,"enable use of SAHF instruction if available (X64 only)") DEFINE_bool(enable_vfp3, true,"enable use of VFP3 instructions if available - this implies ""enabling ARMv7 instructions (ARM only)") DEFINE_bool(enable_armv7, true,"enable use of ARMv7 instructions if available (ARM only)") DEFINE_bool(enable_fpu, true,"enable use of MIPS FPU instructions if available (MIPS only)") DEFINE_string(expose_natives_as, NULL,"expose natives in global object") DEFINE_string(expose_debug_as, NULL,"expose debug in global object") DEFINE_bool(expose_gc, false,"expose gc extension") DEFINE_bool(expose_externalize_string, false,"expose externalize string extension") DEFINE_int(stack_trace_limit, 10,"number of stack frames to capture") DEFINE_bool(builtins_in_stack_traces, false,"show built-in functions in stack traces") DEFINE_bool(disable_native_files, false,"disable builtin natives files") DEFINE_bool(inline_new, true,"use fast inline allocation") DEFINE_bool(stack_trace_on_abort, true,"print a stack trace if an assertion failure occurs") DEFINE_bool(trace, false,"trace function calls") DEFINE_bool(mask_constants_with_cookie, true,"use random jit cookie to mask large constants") DEFINE_bool(lazy, true,"use lazy compilation") DEFINE_bool(trace_opt, false,"trace lazy optimization") DEFINE_bool(trace_opt_stats, false,"trace lazy optimization statistics") DEFINE_bool(opt, true,"use adaptive optimizations") DEFINE_bool(always_opt, false,"always try to optimize functions") DEFINE_bool(prepare_always_opt, false,"prepare for turning on always opt") DEFINE_bool(trace_deopt, false,"trace deoptimization") DEFINE_int(min_preparse_length, 1024,"minimum length for automatic enable preparsing") DEFINE_bool(always_full_compiler, false,"try to use the dedicated run-once backend for all code") DEFINE_bool(trace_bailout, false,"print reasons for falling back to using the classic V8 backend") DEFINE_bool(compilation_cache, true,"enable compilation cache") DEFINE_bool(cache_prototype_transitions, true,"cache prototype transitions") DEFINE_bool(trace_debug_json, false,"trace debugging JSON request/response") DEFINE_bool(debugger_auto_break, true,"automatically set the debug break flag when debugger commands are ""in the queue") DEFINE_bool(enable_liveedit, true,"enable liveedit experimental feature") DEFINE_bool(break_on_abort, true,"always cause a debug break before aborting") DEFINE_int(stack_size, kPointerSize *123,"default size of stack region v8 is allowed to use (in kBytes)") DEFINE_int(max_stack_trace_source_length, 300,"maximum length of function source code printed in a stack trace.") DEFINE_bool(always_inline_smi_code, false,"always inline smi code in non-opt code") DEFINE_int(max_new_space_size, 0,"max size of the new generation (in kBytes)") DEFINE_int(max_old_space_size, 0,"max size of the old generation (in Mbytes)") DEFINE_int(max_executable_size, 0,"max size of executable memory (in Mbytes)") DEFINE_bool(gc_global, false,"always perform global GCs") DEFINE_int(gc_interval,-1,"garbage collect after <n> allocations") DEFINE_bool(trace_gc, false,"print one trace line following each garbage collection") DEFINE_bool(trace_gc_nvp, false,"print one detailed trace line in name=value format ""after each garbage collection") DEFINE_bool(print_cumulative_gc_stat, false,"print cumulative GC statistics in name=value format on exit") DEFINE_bool(trace_gc_verbose, false,"print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false,"report fragmentation for old pointer and data pages") DEFINE_bool(collect_maps, true,"garbage collect maps from which no objects can be reached") DEFINE_bool(flush_code, true,"flush code that we expect not to use again before full gc") DEFINE_bool(incremental_marking, true,"use incremental marking") DEFINE_bool(incremental_marking_steps, true,"do incremental marking steps") DEFINE_bool(trace_incremental_marking, false,"trace progress of the incremental marking") DEFINE_bool(use_idle_notification, true,"Use idle notification to reduce memory footprint.") DEFINE_bool(send_idle_notification, false,"Send idle notifcation between stress runs.") DEFINE_bool(use_ic, true,"use inline caching") DEFINE_bool(native_code_counters, false,"generate extra code for manipulating stats counters") DEFINE_bool(always_compact, false,"Perform compaction on every full GC") DEFINE_bool(lazy_sweeping, true,"Use lazy sweeping for old pointer and data spaces") DEFINE_bool(never_compact, false,"Never perform compaction on full GC - testing only") DEFINE_bool(compact_code_space, true,"Compact code space on full non-incremental collections") DEFINE_bool(cleanup_code_caches_at_gc, true,"Flush inline caches prior to mark compact collection and ""flush code caches in maps during mark compact cycle.") DEFINE_int(random_seed, 0,"Default seed for initializing random generator ""(0, the default, means to use system random).") DEFINE_bool(use_verbose_printer, true,"allows verbose printing") DEFINE_bool(allow_natives_syntax, false,"allow natives syntax") DEFINE_bool(trace_sim, false,"Trace simulator execution") DEFINE_bool(check_icache, false,"Check icache flushes in ARM and MIPS simulator") DEFINE_int(stop_sim_at, 0,"Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8,"Stack alingment in bytes in simulator (4 or 8, 8 is default)") DEFINE_bool(trace_exception, false,"print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false,"preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true,"randomize hashes to avoid predictable hash collisions ""(with snapshots this option cannot override the baked-in seed)") DEFINE_int(hash_seed, 0,"Fixed seed to use to hash property keys (0 means random)""(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(preemption, false,"activate a 100ms timer that switches between V8 threads") DEFINE_bool(regexp_optimization, true,"generate optimized regexp code") DEFINE_bool(testing_bool_flag, true,"testing_bool_flag") DEFINE_int(testing_int_flag, 13,"testing_int_flag") DEFINE_float(testing_float_flag, 2.5,"float-flag") DEFINE_string(testing_string_flag,"Hello, world!","string-flag") DEFINE_int(testing_prng_seed, 42,"Seed used for threading test randomness") DEFINE_string(testing_serialization_file,"/tmp/serdes","file in which to serialize heap") DEFINE_bool(help, false,"Print usage message, including flags, on console") DEFINE_bool(dump_counters, false,"Dump counters on exit") DEFINE_string(map_counters,"","Map counters to a file") DEFINE_args(js_arguments, JSARGUMENTS_INIT,"Pass all remaining arguments to the script. Alias for \"--\".") DEFINE_bool(debug_compile_events, true,"Enable debugger compile events") DEFINE_bool(debug_script_collected_events, true,"Enable debugger script collected events") DEFINE_bool(gdbjit, false,"enable GDBJIT interface (disables compacting GC)") DEFINE_bool(gdbjit_full, false,"enable GDBJIT interface for all code objects") DEFINE_bool(gdbjit_dump, false,"dump elf objects with debug info to disk") DEFINE_string(gdbjit_dump_filter,"","dump only objects containing this substring") DEFINE_bool(force_marking_deque_overflows, false,"force overflows of marking deque by reducing it's size ""to 64 words") DEFINE_bool(stress_compaction, false,"stress the GC compactor to flush out bugs (implies ""--force_marking_deque_overflows)")#define FLAG DEFINE_bool(enable_slow_asserts, false,"enable asserts that are slow to execute") DEFINE_bool(trace_codegen, false,"print name of functions for which code is generated") DEFINE_bool(print_source, false,"pretty print source code") DEFINE_bool(print_builtin_source, false,"pretty print source code for builtins") DEFINE_bool(print_ast, false,"print source AST") DEFINE_bool(print_builtin_ast, false,"print source AST for builtins") DEFINE_string(stop_at,"","function name where to insert a breakpoint") DEFINE_bool(print_builtin_scopes, false,"print scopes for builtins") DEFINE_bool(print_scopes, false,"print scopes") DEFINE_bool(trace_contexts, false,"trace contexts operations") DEFINE_bool(gc_greedy, false,"perform GC prior to some allocations") DEFINE_bool(gc_verbose, false,"print stuff during garbage collection") DEFINE_bool(heap_stats, false,"report heap statistics before and after GC") DEFINE_bool(code_stats, false,"report code statistics after GC") DEFINE_bool(verify_heap, false,"verify heap pointers before and after GC") DEFINE_bool(print_handles, false,"report handles after GC") DEFINE_bool(print_global_handles, false,"report global handles after GC") DEFINE_bool(trace_ic, false,"trace inline cache state transitions") DEFINE_bool(print_interfaces, false,"print interfaces") DEFINE_bool(print_interface_details, false,"print interface inference details") DEFINE_int(print_interface_depth, 5,"depth for printing interfaces") DEFINE_bool(trace_normalization, false,"prints when objects are turned into dictionaries.") DEFINE_bool(trace_lazy, false,"trace lazy compilation") DEFINE_bool(collect_heap_spill_statistics, false,"report heap spill statistics along with heap_stats ""(requires heap_stats)") DEFINE_bool(trace_isolates, false,"trace isolate state changes") DEFINE_bool(log_state_changes, false,"Log state changes.") DEFINE_bool(regexp_possessive_quantifier, false,"enable possessive quantifier syntax for testing") DEFINE_bool(trace_regexp_bytecodes, false,"trace regexp bytecode execution") DEFINE_bool(trace_regexp_assembler, false,"trace regexp macro assembler calls.")#define FLAG DEFINE_bool(log, false,"Minimal logging (no API, code, GC, suspect, or handles samples).") DEFINE_bool(log_all, false,"Log all events to the log file.") DEFINE_bool(log_runtime, false,"Activate runtime system %Log call.") DEFINE_bool(log_api, false,"Log API events to the log file.") DEFINE_bool(log_code, false,"Log code events to the log file without profiling.") DEFINE_bool(log_gc, false,"Log heap samples on garbage collection for the hp2ps tool.") DEFINE_bool(log_handles, false,"Log global handle events.") DEFINE_bool(log_snapshot_positions, false,"log positions of (de)serialized objects in the snapshot.") DEFINE_bool(log_suspect, false,"Log suspect operations.") DEFINE_bool(prof, false,"Log statistical profiling information (implies --log-code).") DEFINE_bool(prof_auto, true,"Used with --prof, starts profiling automatically") DEFINE_bool(prof_lazy, false,"Used with --prof, only does sampling and logging"" when profiler is active (implies --noprof_auto).") DEFINE_bool(prof_browser_mode, true,"Used with --prof, turns on browser-compatible mode for profiling.") DEFINE_bool(log_regexp, false,"Log regular expression execution.") DEFINE_bool(sliding_state_window, false,"Update sliding state window counters.") DEFINE_string(logfile,"v8.log","Specify the name of the log file.") DEFINE_bool(ll_prof, false,"Enable low-level linux profiler.")#define FLAG DEFINE_bool(trace_elements_transitions, false,"trace elements transitions") DEFINE_bool(print_code_stubs, false,"print code stubs") DEFINE_bool(test_secondary_stub_cache, false,"test secondary stub cache by disabling the primary one") DEFINE_bool(test_primary_stub_cache, false,"test primary stub cache by disabling the secondary one") DEFINE_bool(print_code, false,"print generated code") DEFINE_bool(print_opt_code, false,"print optimized code") DEFINE_bool(print_unopt_code, false,"print unoptimized code before ""printing optimized code based on it") DEFINE_bool(print_code_verbose, false,"print more information for code") DEFINE_bool(print_builtin_code, false,"print generated code for builtins")#47"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flags.cc"2 namespace{struct Flag{enum FlagType{TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_ARGS} name
Definition: flags.cc:1349
Handle< Code > CompileStoreViaSetter(Handle< JSObject > receiver, Handle< JSFunction > setter, Handle< String > name)
Flag flags[]
Definition: flags.cc:1467
#define RUNTIME_FUNCTION(Type, Name)
Definition: arguments.h:121
String * key
Definition: stub-cache.h:70
#define CALL_GENERATOR_CASE(name)
#define ASSERT(condition)
Definition: checks.h:270
#define CUSTOM_CALL_IC_GENERATORS(V)
Definition: stub-cache.h:765
#define PROFILE(isolate, Call)
Definition: cpu-profiler.h:190
Handle< Code > CompileStoreCallback(Handle< JSObject > object, Handle< AccessorInfo > callback, Handle< String > name)
static Flags ComputeMonomorphicFlags(Kind kind, PropertyType type, ExtraICState extra_ic_state=kNoExtraICState, InlineCacheHolderFlag holder=OWN_MAP, int argc=-1)
Definition: objects-inl.h:3335
Factory * factory()
Definition: isolate.h:977
PropertyAttributes
Handle< Code > CompileLoadField(Handle< JSObject > object, Handle< JSObject > holder, int index, Handle< String > name)
Handle< Code > CompileStoreInterceptor(Handle< JSObject > object, Handle< String > name)
unsigned int seed
Definition: test-strings.cc:17
Handle< Code > CompileStoreField(Handle< JSObject > object, int index, Handle< Map > transition, Handle< String > name)
Object * ValueAt(int entry)
Definition: objects.h:3039
Handle< Code > CompileLoadInterceptor(Handle< JSObject > object, Handle< JSObject > holder, Handle< String > name)
Code * value
Definition: stub-cache.h:71
#define UNREACHABLE()
Definition: checks.h:50
Handle< Value >(* NamedPropertyGetter)(Local< String > property, const AccessorInfo &info)
Definition: v8.h:2023
Handle< Code > CompileCallGlobal(Handle< JSObject > object, Handle< GlobalObject > holder, Handle< JSGlobalPropertyCell > cell, Handle< JSFunction > function, Handle< String > name)
Handle< Code > CompileLoadField(Handle< String > name, Handle< JSObject > object, Handle< JSObject > holder, int index)
Handle< Code > CompileStoreGlobal(Handle< GlobalObject > object, Handle< JSGlobalPropertyCell > holder, Handle< String > name)
Handle< Code > CompileLoadViaGetter(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder, Handle< JSFunction > getter)
Handle< Code > CompileLoadConstant(Handle< JSObject > object, Handle< JSObject > holder, Handle< JSFunction > value, Handle< String > name)
Definition: stub-cache.h:69
Handle< Code > CompileLoadConstant(Handle< String > name, Handle< JSObject > object, Handle< JSObject > holder, Handle< JSFunction > value)
Handle< Code > CompileCallField(Handle< JSObject > object, Handle< JSObject > holder, int index, Handle< String > name)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
Map * map
Definition: stub-cache.h:72
Handle< Code > CompileLoadStringLength(Handle< String > name)
void(* AccessorSetter)(Local< String > property, Local< Value > value, const AccessorInfo &info)
Definition: v8.h:1428
static FunctionTemplateInfo * cast(Object *obj)
Handle< Code > CompileLoadGlobal(Handle< JSObject > object, Handle< GlobalObject > holder, Handle< JSGlobalPropertyCell > cell, Handle< String > name, bool is_dont_delete)
Definition: v8.h:104
bool IsPowerOf2(T x)
Definition: utils.h:50
static Local< Context > ToLocal(v8::internal::Handle< v8::internal::Context > obj)
#define CALL_LOGGER_TAG(kind, type)
Definition: stub-cache.cc:574
#define GDBJIT(action)
Definition: gdb-jit.h:141
bool is_null() const
Definition: handles.h:87
Handle< Code > CompileCallInterceptor(Handle< JSObject > object, Handle< JSObject > holder, Handle< String > name)
static Flags ComputeFlags(Kind kind, InlineCacheState ic_state=UNINITIALIZED, ExtraICState extra_ic_state=kNoExtraICState, PropertyType type=NORMAL, int argc=-1, InlineCacheHolderFlag holder=OWN_MAP)
Definition: objects-inl.h:3312
static Handle< T > null()
Definition: handles.h:86
Map * FindFirstMap()
Definition: objects.cc:8230
#define HEAP
Definition: isolate.h:1408
#define ASSERT_EQ(v1, v2)
Definition: checks.h:271
Handle< Code > CompileLoadArrayLength(Handle< String > name)
void public_set_non_monomorphic_cache(UnseededNumberDictionary *value)
Definition: heap.h:1206
Handle< Code > CompileCallConstant(Handle< Object > object, Handle< JSObject > holder, Handle< JSFunction > function, Handle< String > name, CheckType check)
bool IsCompatibleReceiver(Object *receiver)
Definition: objects-inl.h:4850
bool IsEmpty() const
Definition: v8.h:208
#define FACTORY
Definition: isolate.h:1409
static bool HasCustomCallGenerator(Handle< JSFunction > function)
Definition: stub-cache.cc:1428
const int kInvalidProtoDepth
Vector< Handle< Object > > HandleVector(v8::internal::Handle< T > *elms, int length)
Definition: v8utils.h:114
Handle< Code > CompileLoadCallback(Handle< String > name, Handle< JSObject > object, Handle< JSObject > holder, Handle< AccessorInfo > callback)
#define STATIC_ASSERT(test)
Definition: checks.h:283
void Add(Handle< Map > handle, Zone *zone)
Definition: ast.h:278
static SignatureInfo * cast(Object *obj)
Handle< Code > CompileLoadInterceptor(Handle< JSObject > object, Handle< JSObject > holder, Handle< String > name)
KeyedAccessGrowMode
Definition: objects.h:141
void check(i::Vector< const char > string)
Handle< Value >(* AccessorGetter)(Local< String > property, const AccessorInfo &info)
Definition: v8.h:1424
Handle< Code > CompileLoadElement(Handle< Map > receiver_map)
static JSObject * cast(Object *obj)
FlagType type() const
Definition: flags.cc:1358
static v8::internal::Handle< v8::internal::TemplateInfo > OpenHandle(const Template *that)