v8  3.14.5(node0.10.28)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ast.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 "ast.h"
29 
30 #include <math.h> // For isfinite.
31 #include "builtins.h"
32 #include "conversions.h"
33 #include "hashmap.h"
34 #include "parser.h"
35 #include "property-details.h"
36 #include "property.h"
37 #include "scopes.h"
38 #include "string-stream.h"
39 #include "type-info.h"
40 
41 namespace v8 {
42 namespace internal {
43 
44 // ----------------------------------------------------------------------------
45 // All the Accept member functions for each syntax tree node type.
46 
47 #define DECL_ACCEPT(type) \
48  void type::Accept(AstVisitor* v) { v->Visit##type(this); }
50 #undef DECL_ACCEPT
51 
52 
53 // ----------------------------------------------------------------------------
54 // Implementation of other node functionality.
55 
56 
58  return AsLiteral() != NULL && AsLiteral()->handle()->IsSmi();
59 }
60 
61 
63  return AsLiteral() != NULL && AsLiteral()->handle()->IsString();
64 }
65 
66 
68  return AsLiteral() != NULL && AsLiteral()->handle()->IsNull();
69 }
70 
71 
73  : Expression(isolate),
74  name_(var->name()),
75  var_(NULL), // Will be set by the call to BindTo.
76  is_this_(var->is_this()),
77  is_trivial_(false),
78  is_lvalue_(false),
79  position_(RelocInfo::kNoPosition),
80  interface_(var->interface()) {
81  BindTo(var);
82 }
83 
84 
86  Handle<String> name,
87  bool is_this,
89  int position)
90  : Expression(isolate),
91  name_(name),
92  var_(NULL),
93  is_this_(is_this),
94  is_trivial_(false),
95  is_lvalue_(false),
96  position_(position),
97  interface_(interface) {
98  // Names must be canonicalized for fast equality checks.
99  ASSERT(name->IsSymbol());
100 }
101 
102 
104  ASSERT(var_ == NULL); // must be bound only once
105  ASSERT(var != NULL); // must bind
106  ASSERT((is_this() && var->is_this()) || name_.is_identical_to(var->name()));
107  // Ideally CONST-ness should match. However, this is very hard to achieve
108  // because we don't know the exact semantics of conflicting (const and
109  // non-const) multiple variable declarations, const vars introduced via
110  // eval() etc. Const-ness and variable declarations are a complete mess
111  // in JS. Sigh...
112  var_ = var;
113  var->set_is_used(true);
114 }
115 
116 
118  Token::Value op,
119  Expression* target,
120  Expression* value,
121  int pos)
122  : Expression(isolate),
123  op_(op),
124  target_(target),
125  value_(value),
126  pos_(pos),
127  binary_operation_(NULL),
128  assignment_id_(GetNextId(isolate)),
129  is_monomorphic_(false) { }
130 
131 
133  switch (op_) {
134  case Token::ASSIGN_BIT_OR: return Token::BIT_OR;
135  case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR;
136  case Token::ASSIGN_BIT_AND: return Token::BIT_AND;
137  case Token::ASSIGN_SHL: return Token::SHL;
138  case Token::ASSIGN_SAR: return Token::SAR;
139  case Token::ASSIGN_SHR: return Token::SHR;
140  case Token::ASSIGN_ADD: return Token::ADD;
141  case Token::ASSIGN_SUB: return Token::SUB;
142  case Token::ASSIGN_MUL: return Token::MUL;
143  case Token::ASSIGN_DIV: return Token::DIV;
144  case Token::ASSIGN_MOD: return Token::MOD;
145  default: UNREACHABLE();
146  }
147  return Token::ILLEGAL;
148 }
149 
150 
152  return scope()->AllowsLazyCompilation();
153 }
154 
155 
158 }
159 
160 
162  return scope()->start_position();
163 }
164 
165 
167  return scope()->end_position();
168 }
169 
170 
172  return scope()->language_mode();
173 }
174 
175 
177  Expression* value,
178  Isolate* isolate) {
179  emit_store_ = true;
180  key_ = key;
181  value_ = value;
182  Object* k = *key->handle();
183  if (k->IsSymbol() &&
184  isolate->heap()->Proto_symbol()->Equals(String::cast(k))) {
185  kind_ = PROTOTYPE;
186  } else if (value_->AsMaterializedLiteral() != NULL) {
187  kind_ = MATERIALIZED_LITERAL;
188  } else if (value_->AsLiteral() != NULL) {
189  kind_ = CONSTANT;
190  } else {
191  kind_ = COMPUTED;
192  }
193 }
194 
195 
197  emit_store_ = true;
198  value_ = value;
199  kind_ = is_getter ? GETTER : SETTER;
200 }
201 
202 
204  return kind_ == CONSTANT ||
205  (kind_ == MATERIALIZED_LITERAL &&
207 }
208 
209 
211  emit_store_ = emit_store;
212 }
213 
214 
216  return emit_store_;
217 }
218 
219 
220 bool IsEqualString(void* first, void* second) {
221  ASSERT((*reinterpret_cast<String**>(first))->IsString());
222  ASSERT((*reinterpret_cast<String**>(second))->IsString());
223  Handle<String> h1(reinterpret_cast<String**>(first));
224  Handle<String> h2(reinterpret_cast<String**>(second));
225  return (*h1)->Equals(*h2);
226 }
227 
228 
229 bool IsEqualNumber(void* first, void* second) {
230  ASSERT((*reinterpret_cast<Object**>(first))->IsNumber());
231  ASSERT((*reinterpret_cast<Object**>(second))->IsNumber());
232 
233  Handle<Object> h1(reinterpret_cast<Object**>(first));
234  Handle<Object> h2(reinterpret_cast<Object**>(second));
235  if (h1->IsSmi()) {
236  return h2->IsSmi() && *h1 == *h2;
237  }
238  if (h2->IsSmi()) return false;
241  ASSERT(isfinite(n1->value()));
242  ASSERT(isfinite(n2->value()));
243  return n1->value() == n2->value();
244 }
245 
246 
248  ZoneAllocationPolicy allocator(zone);
249 
251  allocator);
252  for (int i = properties()->length() - 1; i >= 0; i--) {
253  ObjectLiteral::Property* property = properties()->at(i);
254  Literal* literal = property->key();
255  if (literal->handle()->IsNull()) continue;
256  uint32_t hash = literal->Hash();
257  // If the key of a computed property is in the table, do not emit
258  // a store for the property later.
259  if (property->kind() == ObjectLiteral::Property::COMPUTED &&
260  table.Lookup(literal, hash, false, allocator) != NULL) {
261  property->set_emit_store(false);
262  } else {
263  // Add key to the table.
264  table.Lookup(literal, hash, true, allocator);
265  }
266  }
267 }
268 
269 
270 void TargetCollector::AddTarget(Label* target, Zone* zone) {
271  // Add the label to the collector, but discard duplicates.
272  int length = targets_.length();
273  for (int i = 0; i < length; i++) {
274  if (targets_[i] == target) return;
275  }
276  targets_.Add(target, zone);
277 }
278 
279 
281  switch (op_) {
282  case Token::BIT_NOT:
283  case Token::SUB:
284  return true;
285  default:
286  return false;
287  }
288 }
289 
290 
292  switch (op_) {
293  case Token::COMMA:
294  case Token::OR:
295  case Token::AND:
296  return false;
297  case Token::BIT_OR:
298  case Token::BIT_XOR:
299  case Token::BIT_AND:
300  case Token::SHL:
301  case Token::SAR:
302  case Token::SHR:
303  case Token::ADD:
304  case Token::SUB:
305  case Token::MUL:
306  case Token::DIV:
307  case Token::MOD:
308  return true;
309  default:
310  UNREACHABLE();
311  }
312  return false;
313 }
314 
315 
316 static bool IsTypeof(Expression* expr) {
317  UnaryOperation* maybe_unary = expr->AsUnaryOperation();
318  return maybe_unary != NULL && maybe_unary->op() == Token::TYPEOF;
319 }
320 
321 
322 // Check for the pattern: typeof <expression> equals <string literal>.
323 static bool MatchLiteralCompareTypeof(Expression* left,
324  Token::Value op,
325  Expression* right,
326  Expression** expr,
328  if (IsTypeof(left) && right->IsStringLiteral() && Token::IsEqualityOp(op)) {
329  *expr = left->AsUnaryOperation()->expression();
330  *check = Handle<String>::cast(right->AsLiteral()->handle());
331  return true;
332  }
333  return false;
334 }
335 
336 
338  Handle<String>* check) {
339  return MatchLiteralCompareTypeof(left_, op_, right_, expr, check) ||
340  MatchLiteralCompareTypeof(right_, op_, left_, expr, check);
341 }
342 
343 
344 static bool IsVoidOfLiteral(Expression* expr) {
345  UnaryOperation* maybe_unary = expr->AsUnaryOperation();
346  return maybe_unary != NULL &&
347  maybe_unary->op() == Token::VOID &&
348  maybe_unary->expression()->AsLiteral() != NULL;
349 }
350 
351 
352 // Check for the pattern: void <literal> equals <expression>
353 static bool MatchLiteralCompareUndefined(Expression* left,
354  Token::Value op,
355  Expression* right,
356  Expression** expr) {
357  if (IsVoidOfLiteral(left) && Token::IsEqualityOp(op)) {
358  *expr = right;
359  return true;
360  }
361  return false;
362 }
363 
364 
366  return MatchLiteralCompareUndefined(left_, op_, right_, expr) ||
367  MatchLiteralCompareUndefined(right_, op_, left_, expr);
368 }
369 
370 
371 // Check for the pattern: null equals <expression>
372 static bool MatchLiteralCompareNull(Expression* left,
373  Token::Value op,
374  Expression* right,
375  Expression** expr) {
376  if (left->IsNullLiteral() && Token::IsEqualityOp(op)) {
377  *expr = right;
378  return true;
379  }
380  return false;
381 }
382 
383 
385  return MatchLiteralCompareNull(left_, op_, right_, expr) ||
386  MatchLiteralCompareNull(right_, op_, left_, expr);
387 }
388 
389 
390 // ----------------------------------------------------------------------------
391 // Inlining support
392 
394  return proxy()->var()->IsStackAllocated();
395 }
396 
398  return false;
399 }
400 
401 
402 // ----------------------------------------------------------------------------
403 // Recording of type feedback
404 
406  Zone* zone) {
407  // Record type feedback from the oracle in the AST.
408  is_uninitialized_ = oracle->LoadIsUninitialized(this);
409  if (is_uninitialized_) return;
410 
411  is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this);
412  receiver_types_.Clear();
413  if (key()->IsPropertyName()) {
414  if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_ArrayLength)) {
415  is_array_length_ = true;
416  } else if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_StringLength)) {
417  is_string_length_ = true;
418  } else if (oracle->LoadIsBuiltin(this,
419  Builtins::kLoadIC_FunctionPrototype)) {
420  is_function_prototype_ = true;
421  } else {
422  Literal* lit_key = key()->AsLiteral();
423  ASSERT(lit_key != NULL && lit_key->handle()->IsString());
424  Handle<String> name = Handle<String>::cast(lit_key->handle());
425  oracle->LoadReceiverTypes(this, name, &receiver_types_);
426  }
427  } else if (oracle->LoadIsBuiltin(this, Builtins::kKeyedLoadIC_String)) {
428  is_string_access_ = true;
429  } else if (is_monomorphic_) {
430  receiver_types_.Add(oracle->LoadMonomorphicReceiverType(this),
431  zone);
432  } else if (oracle->LoadIsMegamorphicWithTypeInfo(this)) {
433  receiver_types_.Reserve(kMaxKeyedPolymorphism, zone);
434  oracle->CollectKeyedReceiverTypes(PropertyFeedbackId(), &receiver_types_);
435  }
436 }
437 
438 
440  Zone* zone) {
441  Property* prop = target()->AsProperty();
442  ASSERT(prop != NULL);
443  TypeFeedbackId id = AssignmentFeedbackId();
444  is_monomorphic_ = oracle->StoreIsMonomorphicNormal(id);
445  receiver_types_.Clear();
446  if (prop->key()->IsPropertyName()) {
447  Literal* lit_key = prop->key()->AsLiteral();
448  ASSERT(lit_key != NULL && lit_key->handle()->IsString());
449  Handle<String> name = Handle<String>::cast(lit_key->handle());
450  oracle->StoreReceiverTypes(this, name, &receiver_types_);
451  } else if (is_monomorphic_) {
452  // Record receiver type for monomorphic keyed stores.
453  receiver_types_.Add(oracle->StoreMonomorphicReceiverType(id), zone);
454  } else if (oracle->StoreIsMegamorphicWithTypeInfo(id)) {
455  receiver_types_.Reserve(kMaxKeyedPolymorphism, zone);
456  oracle->CollectKeyedReceiverTypes(id, &receiver_types_);
457  }
458 }
459 
460 
462  Zone* zone) {
463  TypeFeedbackId id = CountStoreFeedbackId();
464  is_monomorphic_ = oracle->StoreIsMonomorphicNormal(id);
465  receiver_types_.Clear();
466  if (is_monomorphic_) {
467  // Record receiver type for monomorphic keyed stores.
468  receiver_types_.Add(
469  oracle->StoreMonomorphicReceiverType(id), zone);
470  } else if (oracle->StoreIsMegamorphicWithTypeInfo(id)) {
471  receiver_types_.Reserve(kMaxKeyedPolymorphism, zone);
472  oracle->CollectKeyedReceiverTypes(id, &receiver_types_);
473  }
474 }
475 
476 
478  TypeInfo info = oracle->SwitchType(this);
479  if (info.IsSmi()) {
480  compare_type_ = SMI_ONLY;
481  } else if (info.IsSymbol()) {
482  compare_type_ = SYMBOL_ONLY;
483  } else if (info.IsNonSymbol()) {
484  compare_type_ = STRING_ONLY;
485  } else if (info.IsNonPrimitive()) {
486  compare_type_ = OBJECT_ONLY;
487  } else {
488  ASSERT(compare_type_ == NONE);
489  }
490 }
491 
492 
494  // If there is an interceptor, we can't compute the target for a direct call.
495  if (type->has_named_interceptor()) return false;
496 
497  if (check_type_ == RECEIVER_MAP_CHECK) {
498  // For primitive checks the holder is set up to point to the corresponding
499  // prototype object, i.e. one step of the algorithm below has been already
500  // performed. For non-primitive checks we clear it to allow computing
501  // targets for polymorphic calls.
502  holder_ = Handle<JSObject>::null();
503  }
504  LookupResult lookup(type->GetIsolate());
505  while (true) {
506  type->LookupDescriptor(NULL, *name, &lookup);
507  if (lookup.IsFound()) {
508  switch (lookup.type()) {
509  case CONSTANT_FUNCTION:
510  // We surely know the target for a constant function.
511  target_ =
512  Handle<JSFunction>(lookup.GetConstantFunctionFromMap(*type));
513  return true;
514  case NORMAL:
515  case FIELD:
516  case CALLBACKS:
517  case HANDLER:
518  case INTERCEPTOR:
519  // We don't know the target.
520  return false;
521  case TRANSITION:
522  case NONEXISTENT:
523  UNREACHABLE();
524  break;
525  }
526  }
527  // If we reach the end of the prototype chain, we don't know the target.
528  if (!type->prototype()->IsJSObject()) return false;
529  // Go up the prototype chain, recording where we are currently.
530  holder_ = Handle<JSObject>(JSObject::cast(type->prototype()));
531  if (!holder_->HasFastProperties()) return false;
532  type = Handle<Map>(holder()->map());
533  }
534 }
535 
536 
538  LookupResult* lookup) {
539  target_ = Handle<JSFunction>::null();
541  ASSERT(lookup->IsFound() &&
542  lookup->type() == NORMAL &&
543  lookup->holder() == *global);
544  cell_ = Handle<JSGlobalPropertyCell>(global->GetPropertyCell(lookup));
545  if (cell_->value()->IsJSFunction()) {
546  Handle<JSFunction> candidate(JSFunction::cast(cell_->value()));
547  // If the function is in new space we assume it's more likely to
548  // change and thus prefer the general IC code.
549  if (!HEAP->InNewSpace(*candidate)) {
550  target_ = candidate;
551  return true;
552  }
553  }
554  return false;
555 }
556 
557 
559  CallKind call_kind) {
560  is_monomorphic_ = oracle->CallIsMonomorphic(this);
561  Property* property = expression()->AsProperty();
562  if (property == NULL) {
563  // Function call. Specialize for monomorphic calls.
564  if (is_monomorphic_) target_ = oracle->GetCallTarget(this);
565  } else {
566  // Method call. Specialize for the receiver types seen at runtime.
567  Literal* key = property->key()->AsLiteral();
568  ASSERT(key != NULL && key->handle()->IsString());
570  receiver_types_.Clear();
571  oracle->CallReceiverTypes(this, name, call_kind, &receiver_types_);
572 #ifdef DEBUG
574  int length = receiver_types_.length();
575  for (int i = 0; i < length; i++) {
576  Handle<Map> map = receiver_types_.at(i);
577  ASSERT(!map.is_null() && *map != NULL);
578  }
579  }
580 #endif
581  check_type_ = oracle->GetCallCheckType(this);
582  if (is_monomorphic_) {
583  Handle<Map> map;
584  if (receiver_types_.length() > 0) {
585  ASSERT(check_type_ == RECEIVER_MAP_CHECK);
586  map = receiver_types_.at(0);
587  } else {
588  ASSERT(check_type_ != RECEIVER_MAP_CHECK);
589  holder_ = Handle<JSObject>(
590  oracle->GetPrototypeForPrimitiveCheck(check_type_));
591  map = Handle<Map>(holder_->map());
592  }
593  is_monomorphic_ = ComputeTarget(map, name);
594  }
595  }
596 }
597 
598 
600  is_monomorphic_ = oracle->CallNewIsMonomorphic(this);
601  if (is_monomorphic_) {
602  target_ = oracle->GetCallNewTarget(this);
603  }
604 }
605 
606 
608  TypeInfo info = oracle->CompareType(this);
609  if (info.IsSmi()) {
610  compare_type_ = SMI_ONLY;
611  } else if (info.IsNonPrimitive()) {
612  compare_type_ = OBJECT_ONLY;
613  } else {
614  ASSERT(compare_type_ == NONE);
615  }
616 }
617 
618 
620  receiver_type_ = oracle->ObjectLiteralStoreIsMonomorphic(this)
621  ? oracle->GetObjectLiteralStoreMap(this)
622  : Handle<Map>::null();
623 }
624 
625 
626 // ----------------------------------------------------------------------------
627 // Implementation of AstVisitor
628 
629 bool AstVisitor::CheckStackOverflow() {
630  if (stack_overflow_) return true;
631  StackLimitCheck check(isolate_);
632  if (!check.HasOverflowed()) return false;
633  return (stack_overflow_ = true);
634 }
635 
636 
637 void AstVisitor::VisitDeclarations(ZoneList<Declaration*>* declarations) {
638  for (int i = 0; i < declarations->length(); i++) {
639  Visit(declarations->at(i));
640  }
641 }
642 
643 
644 void AstVisitor::VisitStatements(ZoneList<Statement*>* statements) {
645  for (int i = 0; i < statements->length(); i++) {
646  Visit(statements->at(i));
647  }
648 }
649 
650 
651 void AstVisitor::VisitExpressions(ZoneList<Expression*>* expressions) {
652  for (int i = 0; i < expressions->length(); i++) {
653  // The variable statement visiting code may pass NULL expressions
654  // to this code. Maybe this should be handled by introducing an
655  // undefined expression or literal? Revisit this code if this
656  // changes
657  Expression* expression = expressions->at(i);
658  if (expression != NULL) Visit(expression);
659  }
660 }
661 
662 
663 // ----------------------------------------------------------------------------
664 // Regular expressions
665 
666 #define MAKE_ACCEPT(Name) \
667  void* RegExp##Name::Accept(RegExpVisitor* visitor, void* data) { \
668  return visitor->Visit##Name(this, data); \
669  }
671 #undef MAKE_ACCEPT
672 
673 #define MAKE_TYPE_CASE(Name) \
674  RegExp##Name* RegExpTree::As##Name() { \
675  return NULL; \
676  } \
677  bool RegExpTree::Is##Name() { return false; }
679 #undef MAKE_TYPE_CASE
680 
681 #define MAKE_TYPE_CASE(Name) \
682  RegExp##Name* RegExp##Name::As##Name() { \
683  return this; \
684  } \
685  bool RegExp##Name::Is##Name() { return true; }
687 #undef MAKE_TYPE_CASE
688 
689 
690 static Interval ListCaptureRegisters(ZoneList<RegExpTree*>* children) {
691  Interval result = Interval::Empty();
692  for (int i = 0; i < children->length(); i++)
693  result = result.Union(children->at(i)->CaptureRegisters());
694  return result;
695 }
696 
697 
699  return ListCaptureRegisters(nodes());
700 }
701 
702 
704  return ListCaptureRegisters(alternatives());
705 }
706 
707 
709  return body()->CaptureRegisters();
710 }
711 
712 
714  Interval self(StartRegister(index()), EndRegister(index()));
715  return self.Union(body()->CaptureRegisters());
716 }
717 
718 
720  return body()->CaptureRegisters();
721 }
722 
723 
725  return type() == RegExpAssertion::START_OF_INPUT;
726 }
727 
728 
730  return type() == RegExpAssertion::END_OF_INPUT;
731 }
732 
733 
735  ZoneList<RegExpTree*>* nodes = this->nodes();
736  for (int i = 0; i < nodes->length(); i++) {
737  RegExpTree* node = nodes->at(i);
738  if (node->IsAnchoredAtStart()) { return true; }
739  if (node->max_match() > 0) { return false; }
740  }
741  return false;
742 }
743 
744 
746  ZoneList<RegExpTree*>* nodes = this->nodes();
747  for (int i = nodes->length() - 1; i >= 0; i--) {
748  RegExpTree* node = nodes->at(i);
749  if (node->IsAnchoredAtEnd()) { return true; }
750  if (node->max_match() > 0) { return false; }
751  }
752  return false;
753 }
754 
755 
757  ZoneList<RegExpTree*>* alternatives = this->alternatives();
758  for (int i = 0; i < alternatives->length(); i++) {
759  if (!alternatives->at(i)->IsAnchoredAtStart())
760  return false;
761  }
762  return true;
763 }
764 
765 
767  ZoneList<RegExpTree*>* alternatives = this->alternatives();
768  for (int i = 0; i < alternatives->length(); i++) {
769  if (!alternatives->at(i)->IsAnchoredAtEnd())
770  return false;
771  }
772  return true;
773 }
774 
775 
777  return is_positive() && body()->IsAnchoredAtStart();
778 }
779 
780 
782  return body()->IsAnchoredAtStart();
783 }
784 
785 
787  return body()->IsAnchoredAtEnd();
788 }
789 
790 
791 // Convert regular expression trees to a simple sexp representation.
792 // This representation should be different from the input grammar
793 // in as many cases as possible, to make it more difficult for incorrect
794 // parses to look as correct ones which is likely if the input and
795 // output formats are alike.
796 class RegExpUnparser: public RegExpVisitor {
797  public:
798  explicit RegExpUnparser(Zone* zone);
799  void VisitCharacterRange(CharacterRange that);
800  SmartArrayPointer<const char> ToString() { return stream_.ToCString(); }
801 #define MAKE_CASE(Name) virtual void* Visit##Name(RegExp##Name*, void* data);
803 #undef MAKE_CASE
804  private:
805  StringStream* stream() { return &stream_; }
806  HeapStringAllocator alloc_;
807  StringStream stream_;
808  Zone* zone_;
809 };
810 
811 
812 RegExpUnparser::RegExpUnparser(Zone* zone) : stream_(&alloc_), zone_(zone) {
813 }
814 
815 
816 void* RegExpUnparser::VisitDisjunction(RegExpDisjunction* that, void* data) {
817  stream()->Add("(|");
818  for (int i = 0; i < that->alternatives()->length(); i++) {
819  stream()->Add(" ");
820  that->alternatives()->at(i)->Accept(this, data);
821  }
822  stream()->Add(")");
823  return NULL;
824 }
825 
826 
827 void* RegExpUnparser::VisitAlternative(RegExpAlternative* that, void* data) {
828  stream()->Add("(:");
829  for (int i = 0; i < that->nodes()->length(); i++) {
830  stream()->Add(" ");
831  that->nodes()->at(i)->Accept(this, data);
832  }
833  stream()->Add(")");
834  return NULL;
835 }
836 
837 
839  stream()->Add("%k", that.from());
840  if (!that.IsSingleton()) {
841  stream()->Add("-%k", that.to());
842  }
843 }
844 
845 
846 
847 void* RegExpUnparser::VisitCharacterClass(RegExpCharacterClass* that,
848  void* data) {
849  if (that->is_negated())
850  stream()->Add("^");
851  stream()->Add("[");
852  for (int i = 0; i < that->ranges(zone_)->length(); i++) {
853  if (i > 0) stream()->Add(" ");
854  VisitCharacterRange(that->ranges(zone_)->at(i));
855  }
856  stream()->Add("]");
857  return NULL;
858 }
859 
860 
861 void* RegExpUnparser::VisitAssertion(RegExpAssertion* that, void* data) {
862  switch (that->type()) {
864  stream()->Add("@^i");
865  break;
867  stream()->Add("@$i");
868  break;
870  stream()->Add("@^l");
871  break;
873  stream()->Add("@$l");
874  break;
876  stream()->Add("@b");
877  break;
879  stream()->Add("@B");
880  break;
881  }
882  return NULL;
883 }
884 
885 
886 void* RegExpUnparser::VisitAtom(RegExpAtom* that, void* data) {
887  stream()->Add("'");
888  Vector<const uc16> chardata = that->data();
889  for (int i = 0; i < chardata.length(); i++) {
890  stream()->Add("%k", chardata[i]);
891  }
892  stream()->Add("'");
893  return NULL;
894 }
895 
896 
897 void* RegExpUnparser::VisitText(RegExpText* that, void* data) {
898  if (that->elements()->length() == 1) {
899  that->elements()->at(0).data.u_atom->Accept(this, data);
900  } else {
901  stream()->Add("(!");
902  for (int i = 0; i < that->elements()->length(); i++) {
903  stream()->Add(" ");
904  that->elements()->at(i).data.u_atom->Accept(this, data);
905  }
906  stream()->Add(")");
907  }
908  return NULL;
909 }
910 
911 
912 void* RegExpUnparser::VisitQuantifier(RegExpQuantifier* that, void* data) {
913  stream()->Add("(# %i ", that->min());
914  if (that->max() == RegExpTree::kInfinity) {
915  stream()->Add("- ");
916  } else {
917  stream()->Add("%i ", that->max());
918  }
919  stream()->Add(that->is_greedy() ? "g " : that->is_possessive() ? "p " : "n ");
920  that->body()->Accept(this, data);
921  stream()->Add(")");
922  return NULL;
923 }
924 
925 
926 void* RegExpUnparser::VisitCapture(RegExpCapture* that, void* data) {
927  stream()->Add("(^ ");
928  that->body()->Accept(this, data);
929  stream()->Add(")");
930  return NULL;
931 }
932 
933 
934 void* RegExpUnparser::VisitLookahead(RegExpLookahead* that, void* data) {
935  stream()->Add("(-> ");
936  stream()->Add(that->is_positive() ? "+ " : "- ");
937  that->body()->Accept(this, data);
938  stream()->Add(")");
939  return NULL;
940 }
941 
942 
943 void* RegExpUnparser::VisitBackReference(RegExpBackReference* that,
944  void* data) {
945  stream()->Add("(<- %i)", that->index());
946  return NULL;
947 }
948 
949 
950 void* RegExpUnparser::VisitEmpty(RegExpEmpty* that, void* data) {
951  stream()->Put('%');
952  return NULL;
953 }
954 
955 
957  RegExpUnparser unparser(zone);
958  Accept(&unparser, NULL);
959  return unparser.ToString();
960 }
961 
962 
964  : alternatives_(alternatives) {
965  ASSERT(alternatives->length() > 1);
966  RegExpTree* first_alternative = alternatives->at(0);
967  min_match_ = first_alternative->min_match();
968  max_match_ = first_alternative->max_match();
969  for (int i = 1; i < alternatives->length(); i++) {
970  RegExpTree* alternative = alternatives->at(i);
971  min_match_ = Min(min_match_, alternative->min_match());
972  max_match_ = Max(max_match_, alternative->max_match());
973  }
974 }
975 
976 
977 static int IncreaseBy(int previous, int increase) {
978  if (RegExpTree::kInfinity - previous < increase) {
979  return RegExpTree::kInfinity;
980  } else {
981  return previous + increase;
982  }
983 }
984 
986  : nodes_(nodes) {
987  ASSERT(nodes->length() > 1);
988  min_match_ = 0;
989  max_match_ = 0;
990  for (int i = 0; i < nodes->length(); i++) {
991  RegExpTree* node = nodes->at(i);
992  int node_min_match = node->min_match();
993  min_match_ = IncreaseBy(min_match_, node_min_match);
994  int node_max_match = node->max_match();
995  max_match_ = IncreaseBy(max_match_, node_max_match);
996  }
997 }
998 
999 
1001  Expression* label,
1002  ZoneList<Statement*>* statements,
1003  int pos)
1004  : label_(label),
1005  statements_(statements),
1006  position_(pos),
1007  compare_type_(NONE),
1008  compare_id_(AstNode::GetNextId(isolate)),
1009  entry_id_(AstNode::GetNextId(isolate)) {
1010 }
1011 
1012 
1013 #define REGULAR_NODE(NodeType) \
1014  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
1015  increase_node_count(); \
1016  }
1017 #define DONT_OPTIMIZE_NODE(NodeType) \
1018  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
1019  increase_node_count(); \
1020  add_flag(kDontOptimize); \
1021  add_flag(kDontInline); \
1022  add_flag(kDontSelfOptimize); \
1023  }
1024 #define DONT_INLINE_NODE(NodeType) \
1025  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
1026  increase_node_count(); \
1027  add_flag(kDontInline); \
1028  }
1029 #define DONT_SELFOPTIMIZE_NODE(NodeType) \
1030  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
1031  increase_node_count(); \
1032  add_flag(kDontSelfOptimize); \
1033  }
1034 #define DONT_CACHE_NODE(NodeType) \
1035  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
1036  increase_node_count(); \
1037  add_flag(kDontOptimize); \
1038  add_flag(kDontInline); \
1039  add_flag(kDontSelfOptimize); \
1040  add_flag(kDontCache); \
1041  }
1042 
1043 REGULAR_NODE(VariableDeclaration)
1044 REGULAR_NODE(FunctionDeclaration)
1046 REGULAR_NODE(ExpressionStatement)
1047 REGULAR_NODE(EmptyStatement)
1048 REGULAR_NODE(IfStatement)
1049 REGULAR_NODE(ContinueStatement)
1050 REGULAR_NODE(BreakStatement)
1051 REGULAR_NODE(ReturnStatement)
1052 REGULAR_NODE(SwitchStatement)
1053 REGULAR_NODE(Conditional)
1054 REGULAR_NODE(Literal)
1055 REGULAR_NODE(ObjectLiteral)
1056 REGULAR_NODE(RegExpLiteral)
1057 REGULAR_NODE(Assignment)
1058 REGULAR_NODE(Throw)
1059 REGULAR_NODE(Property)
1060 REGULAR_NODE(UnaryOperation)
1061 REGULAR_NODE(CountOperation)
1062 REGULAR_NODE(BinaryOperation)
1063 REGULAR_NODE(CompareOperation)
1064 REGULAR_NODE(ThisFunction)
1065 REGULAR_NODE(Call)
1066 REGULAR_NODE(CallNew)
1067 // In theory, for VariableProxy we'd have to add:
1068 // if (node->var()->IsLookupSlot()) add_flag(kDontInline);
1069 // But node->var() is usually not bound yet at VariableProxy creation time, and
1070 // LOOKUP variables only result from constructs that cannot be inlined anyway.
1071 REGULAR_NODE(VariableProxy)
1072 
1073 // We currently do not optimize any modules. Note in particular, that module
1074 // instance objects associated with ModuleLiterals are allocated during
1075 // scope resolution, and references to them are embedded into the code.
1076 // That code may hence neither be cached nor re-compiled.
1077 DONT_OPTIMIZE_NODE(ModuleDeclaration)
1078 DONT_OPTIMIZE_NODE(ImportDeclaration)
1079 DONT_OPTIMIZE_NODE(ExportDeclaration)
1080 DONT_OPTIMIZE_NODE(ModuleVariable)
1081 DONT_OPTIMIZE_NODE(ModulePath)
1082 DONT_OPTIMIZE_NODE(ModuleUrl)
1083 DONT_OPTIMIZE_NODE(WithStatement)
1084 DONT_OPTIMIZE_NODE(TryCatchStatement)
1085 DONT_OPTIMIZE_NODE(TryFinallyStatement)
1086 DONT_OPTIMIZE_NODE(DebuggerStatement)
1087 DONT_OPTIMIZE_NODE(SharedFunctionInfoLiteral)
1088 
1089 DONT_INLINE_NODE(ArrayLiteral) // TODO(1322): Allow materialized literals.
1091 
1096 
1098 
1099 void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) {
1100  increase_node_count();
1101  if (node->is_jsruntime()) {
1102  // Don't try to inline JS runtime calls because we don't (currently) even
1103  // optimize them.
1104  add_flag(kDontInline);
1105  } else if (node->function()->intrinsic_type == Runtime::INLINE &&
1106  (node->name()->IsEqualTo(CStrVector("_ArgumentsLength")) ||
1107  node->name()->IsEqualTo(CStrVector("_Arguments")))) {
1108  // Don't inline the %_ArgumentsLength or %_Arguments because their
1109  // implementation will not work. There is no stack frame to get them
1110  // from.
1111  add_flag(kDontInline);
1112  }
1113 }
1114 
1115 #undef REGULAR_NODE
1116 #undef DONT_OPTIMIZE_NODE
1117 #undef DONT_INLINE_NODE
1118 #undef DONT_SELFOPTIMIZE_NODE
1119 #undef DONT_CACHE_NODE
1120 
1121 
1122 Handle<String> Literal::ToString() {
1123  if (handle_->IsString()) return Handle<String>::cast(handle_);
1124  ASSERT(handle_->IsNumber());
1125  char arr[100];
1126  Vector<char> buffer(arr, ARRAY_SIZE(arr));
1127  const char* str;
1128  if (handle_->IsSmi()) {
1129  // Optimization only, the heap number case would subsume this.
1130  OS::SNPrintF(buffer, "%d", Smi::cast(*handle_)->value());
1131  str = arr;
1132  } else {
1133  str = DoubleToCString(handle_->Number(), buffer);
1134  }
1135  return FACTORY->NewStringFromAscii(CStrVector(str));
1136 }
1137 
1138 
1139 } } // namespace v8::internal
bool ComputeGlobalTarget(Handle< GlobalObject > global, LookupResult *lookup)
Definition: ast.cc:537
bool FLAG_enable_slow_asserts
bool IsStringLiteral()
Definition: ast.cc:62
virtual bool IsAnchoredAtStart()
Definition: ast.cc:776
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 use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra 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 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage including on console Map counters to a file Enable debugger compile events enable GDBJIT interface(disables compacting GC)") DEFINE_bool(gdbjit_full
Handle< JSFunction > GetCallNewTarget(CallNew *expr)
Definition: type-info.cc:297
virtual bool IsAnchoredAtEnd()
Definition: ast.cc:729
bool AllowsLazyCompilationWithoutContext()
Definition: ast.cc:156
#define MAKE_TYPE_CASE(Name)
Definition: ast.cc:681
#define FOR_EACH_REG_EXP_TREE_TYPE(VISIT)
Definition: jsregexp.h:411
void CollectKeyedReceiverTypes(TypeFeedbackId ast_id, SmallMapList *types)
Definition: type-info.cc:574
void RecordTypeFeedback(TypeFeedbackOracle *oracle, CallKind call_kind)
Definition: ast.cc:558
virtual bool ResultOverwriteAllowed()
Definition: ast.cc:291
#define DONT_SELFOPTIMIZE_NODE(NodeType)
Definition: ast.cc:1029
static String * cast(Object *obj)
SmartArrayPointer< const char > ToString()
Definition: ast.cc:800
RegExpUnparser(Zone *zone)
Definition: ast.cc:812
ZoneList< CharacterRange > * ranges(Zone *zone)
Definition: ast.h:2272
VariableProxy(Isolate *isolate, Variable *var)
Definition: ast.cc:72
static Handle< T > cast(Handle< S > that)
Definition: handles.h:81
DONT_INLINE_NODE(ArrayLiteral) void AstConstructionVisitor
Definition: ast.cc:1089
T Max(T a, T b)
Definition: utils.h:222
virtual bool IsAnchoredAtStart()
Definition: ast.cc:756
bool is_identical_to(const Handle< T > other) const
Definition: handles.h:67
uint32_t Hash()
Definition: ast.h:1187
virtual bool IsAnchoredAtEnd()
Definition: ast.cc:766
SmartArrayPointer< const char > ToString(Zone *zone)
Definition: ast.cc:956
#define DECL_ACCEPT(type)
Definition: ast.cc:47
virtual bool ResultOverwriteAllowed()
Definition: ast.cc:280
Handle< Map > LoadMonomorphicReceiverType(Property *expr)
Definition: type-info.cc:192
virtual bool IsAnchoredAtEnd()
Definition: ast.h:2132
virtual bool IsAnchoredAtStart()
Definition: ast.cc:781
void RecordTypeFeedback(TypeFeedbackOracle *oracle)
Definition: ast.cc:619
#define ASSERT(condition)
Definition: checks.h:270
void RecordTypeFeedback(TypeFeedbackOracle *oracle)
Definition: ast.cc:599
bool StoreIsMonomorphicNormal(TypeFeedbackId ast_id)
Definition: type-info.cc:127
static bool IsCompileTimeValue(Expression *expression)
Definition: parser.cc:3830
Expression(Isolate *isolate)
Definition: ast.h:356
virtual MaterializedLiteral * AsMaterializedLiteral()
Definition: ast.h:220
virtual bool IsInlineable() const
Definition: ast.cc:397
bool is_this() const
Definition: variables.h:129
virtual Interval CaptureRegisters()
Definition: ast.cc:719
virtual Interval CaptureRegisters()
Definition: ast.cc:713
void RecordTypeFeedback(TypeFeedbackOracle *oracle, Zone *znoe)
Definition: ast.cc:461
static Interval Empty()
Definition: jsregexp.h:712
Token::Value binary_op() const
Definition: ast.cc:132
bool is_this() const
Definition: ast.h:1412
Handle< String > name() const
Definition: variables.h:96
static Smi * cast(Object *object)
void CallReceiverTypes(Call *expr, Handle< String > name, CallKind call_kind, SmallMapList *types)
Definition: type-info.cc:241
void LoadReceiverTypes(Property *expr, Handle< String > name, SmallMapList *types)
Definition: type-info.cc:223
void Add(Vector< const char > format, Vector< FmtElm > elms)
bool AllowsLazyCompilation() const
Definition: scopes.cc:725
virtual bool IsInlineable() const
Definition: ast.cc:393
void set_emit_store(bool emit_store)
Definition: ast.cc:210
TypeInfo SwitchType(CaseClause *clause)
Definition: type-info.cc:443
virtual bool IsAnchoredAtStart()
Definition: ast.cc:734
virtual Interval CaptureRegisters()
Definition: ast.cc:703
int start_position() const
Definition: scopes.h:262
Variable * var() const
Definition: ast.h:1411
#define UNREACHABLE()
Definition: checks.h:50
void RecordTypeFeedback(TypeFeedbackOracle *oracle)
Definition: ast.cc:607
bool IsLiteralCompareNull(Expression **expr)
Definition: ast.cc:384
void RecordTypeFeedback(TypeFeedbackOracle *oracle, Zone *zone)
Definition: ast.cc:439
bool IsEqualString(void *first, void *second)
Definition: ast.cc:220
#define REGULAR_NODE(NodeType)
Definition: ast.cc:1013
Interval Union(Interval that)
Definition: jsregexp.h:698
LanguageMode language_mode() const
Definition: ast.cc:171
static const int kInfinity
Definition: ast.h:2125
CheckType GetCallCheckType(Call *expr)
Definition: type-info.cc:261
int end_position() const
Definition: ast.cc:166
#define DONT_CACHE_NODE(NodeType)
Definition: ast.cc:1034
const char * DoubleToCString(double v, Vector< char > buffer)
Definition: conversions.cc:68
ZoneList< RegExpTree * > * alternatives()
Definition: ast.h:2161
virtual int min_match()=0
RegExpAlternative(ZoneList< RegExpTree * > *nodes)
Definition: ast.cc:985
void CalculateEmitStore(Zone *zone)
Definition: ast.cc:247
Entry * Lookup(void *key, uint32_t hash, bool insert, AllocationPolicy allocator=AllocationPolicy())
Definition: hashmap.h:131
bool StoreIsMegamorphicWithTypeInfo(TypeFeedbackId ast_id)
Definition: type-info.cc:148
Handle< String > name_
Definition: ast.h:1432
ZoneList< Property * > * properties() const
Definition: ast.h:1291
Handle< JSObject > GetPrototypeForPrimitiveCheck(CheckType check)
Definition: type-info.cc:270
Handle< Map > StoreMonomorphicReceiverType(TypeFeedbackId ast_id)
Definition: type-info.cc:207
bool LoadIsUninitialized(Property *expr)
Definition: type-info.cc:87
#define MAKE_CASE(Name)
Definition: ast.cc:801
Token::Value op() const
Definition: ast.h:1641
int end_position() const
Definition: scopes.h:266
Expression * key() const
Definition: ast.h:1451
virtual bool IsAnchoredAtEnd()
Definition: ast.cc:745
TypeInfo CompareType(CompareOperation *expr)
Definition: type-info.cc:315
static bool IsEqualityOp(Value op)
Definition: token.h:222
bool IsEqualNumber(void *first, void *second)
Definition: ast.cc:229
virtual bool IsPropertyName()
Definition: ast.h:321
Handle< Object > handle() const
Definition: ast.h:1183
activate correct semantics for inheriting readonliness false
Definition: flags.cc:141
Vector< const char > CStrVector(const char *data)
Definition: utils.h:526
#define AST_NODE_LIST(V)
Definition: ast.h:115
void AddTarget(Label *target, Zone *zone)
Definition: ast.cc:270
virtual Interval CaptureRegisters()
Definition: ast.cc:698
Scope * scope() const
Definition: ast.h:1953
static int SNPrintF(Vector< char > str, const char *format,...)
virtual Interval CaptureRegisters()
Definition: ast.cc:708
Assignment(Isolate *isolate, Token::Value op, Expression *target, Expression *value, int pos)
Definition: ast.cc:117
bool IsLiteralCompareTypeof(Expression **expr, Handle< String > *check)
Definition: ast.cc:337
virtual void * Accept(RegExpVisitor *visitor, void *data)=0
bool is_null() const
Definition: handles.h:87
CaseClause(Isolate *isolate, Expression *label, ZoneList< Statement * > *statements, int pos)
Definition: ast.cc:1000
void VisitCharacterRange(CharacterRange that)
Definition: ast.cc:838
Handle< Map > GetObjectLiteralStoreMap(ObjectLiteral::Property *prop)
Definition: type-info.cc:302
virtual bool IsAnchoredAtStart()
Definition: ast.h:2131
bool AllowsLazyCompilationWithoutContext() const
Definition: scopes.cc:730
bool LoadIsBuiltin(Property *expr, Builtins::Name id)
Definition: type-info.cc:309
int start_position() const
Definition: ast.cc:161
bool IsLiteralCompareUndefined(Expression **expr)
Definition: ast.cc:365
static Handle< T > null()
Definition: handles.h:86
bool ComputeTarget(Handle< Map > type, Handle< String > name)
Definition: ast.cc:493
RegExpDisjunction(ZoneList< RegExpTree * > *alternatives)
Definition: ast.cc:963
#define HEAP
Definition: isolate.h:1433
void BindTo(Variable *var)
Definition: ast.cc:103
void set_is_used(bool flag)
Definition: variables.h:106
#define FACTORY
Definition: isolate.h:1434
void RecordTypeFeedback(TypeFeedbackOracle *oracle)
Definition: ast.cc:477
void StoreReceiverTypes(Assignment *expr, Handle< String > name, SmallMapList *types)
Definition: type-info.cc:232
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 use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra 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 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Definition: flags.cc:301
bool CallIsMonomorphic(Call *expr)
Definition: type-info.cc:166
Expression * expression() const
Definition: ast.h:1642
Handle< JSFunction > GetCallTarget(Call *expr)
Definition: type-info.cc:292
bool ObjectLiteralStoreIsMonomorphic(ObjectLiteral::Property *prop)
Definition: type-info.cc:178
#define MAKE_ACCEPT(Name)
Definition: ast.cc:666
LanguageMode language_mode() const
Definition: scopes.h:317
static bool Match(void *literal1, void *literal2)
Definition: ast.h:1189
const int kMaxKeyedPolymorphism
Definition: type-info.h:39
T Min(T a, T b)
Definition: utils.h:229
virtual bool IsAnchoredAtEnd()
Definition: ast.cc:786
virtual int max_match()=0
bool LoadIsMonomorphicNormal(Property *expr)
Definition: type-info.cc:98
#define VOID
bool LoadIsMegamorphicWithTypeInfo(Property *expr)
Definition: type-info.cc:114
void check(i::Vector< const char > string)
bool IsNullLiteral()
Definition: ast.cc:67
#define DONT_OPTIMIZE_NODE(NodeType)
Definition: ast.cc:1017
#define ARRAY_SIZE(a)
Definition: globals.h:281
Property(Literal *key, Expression *value, Isolate *isolate)
Definition: ast.cc:176
static JSObject * cast(Object *obj)
int isfinite(double x)
bool CallNewIsMonomorphic(CallNew *expr)
Definition: type-info.cc:172
virtual bool IsAnchoredAtStart()
Definition: ast.cc:724
static JSFunction * cast(Object *obj)