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

Side by Side Diff: src/scopes.cc

Issue 7824038: Remove variable rewrites and the unneccesary Slot class. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 13 matching lines...) Expand all
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "scopes.h" 30 #include "scopes.h"
31 31
32 #include "bootstrapper.h" 32 #include "bootstrapper.h"
33 #include "compiler.h" 33 #include "compiler.h"
34 #include "prettyprinter.h"
35 #include "scopeinfo.h" 34 #include "scopeinfo.h"
36 35
37 #include "allocation-inl.h" 36 #include "allocation-inl.h"
38 37
39 namespace v8 { 38 namespace v8 {
40 namespace internal { 39 namespace internal {
41 40
42 // ---------------------------------------------------------------------------- 41 // ----------------------------------------------------------------------------
43 // A Zone allocator for use with LocalsMap. 42 // A Zone allocator for use with LocalsMap.
44 43
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 } else { 306 } else {
308 ASSERT(is_function_scope() || 307 ASSERT(is_function_scope() ||
309 is_global_scope() || 308 is_global_scope() ||
310 is_eval_scope()); 309 is_eval_scope());
311 Variable* var = 310 Variable* var =
312 variables_.Declare(this, 311 variables_.Declare(this,
313 isolate_->factory()->this_symbol(), 312 isolate_->factory()->this_symbol(),
314 Variable::VAR, 313 Variable::VAR,
315 false, 314 false,
316 Variable::THIS); 315 Variable::THIS);
317 var->set_rewrite(NewSlot(var, Slot::PARAMETER, -1)); 316 var->AllocateTo(Variable::PARAMETER, -1);
318 receiver_ = var; 317 receiver_ = var;
319 } 318 }
320 319
321 if (is_function_scope()) { 320 if (is_function_scope()) {
322 // Declare 'arguments' variable which exists in all functions. 321 // Declare 'arguments' variable which exists in all functions.
323 // Note that it might never be accessed, in which case it won't be 322 // Note that it might never be accessed, in which case it won't be
324 // allocated during variable allocation. 323 // allocated during variable allocation.
325 variables_.Declare(this, 324 variables_.Declare(this,
326 isolate_->factory()->arguments_symbol(), 325 isolate_->factory()->arguments_symbol(),
327 Variable::VAR, 326 Variable::VAR,
(...skipping 25 matching lines...) Expand all
353 index = scope_info_->ParameterIndex(*name); 352 index = scope_info_->ParameterIndex(*name);
354 if (index < 0) { 353 if (index < 0) {
355 // Check the function name. 354 // Check the function name.
356 index = scope_info_->FunctionContextSlotIndex(*name); 355 index = scope_info_->FunctionContextSlotIndex(*name);
357 if (index < 0) return NULL; 356 if (index < 0) return NULL;
358 } 357 }
359 } 358 }
360 359
361 Variable* var = 360 Variable* var =
362 variables_.Declare(this, name, mode, true, Variable::NORMAL); 361 variables_.Declare(this, name, mode, true, Variable::NORMAL);
363 var->set_rewrite(NewSlot(var, Slot::CONTEXT, index)); 362 var->AllocateTo(Variable::CONTEXT, index);
364 return var; 363 return var;
365 } 364 }
366 365
367 366
368 Variable* Scope::Lookup(Handle<String> name) { 367 Variable* Scope::Lookup(Handle<String> name) {
369 for (Scope* scope = this; 368 for (Scope* scope = this;
370 scope != NULL; 369 scope != NULL;
371 scope = scope->outer_scope()) { 370 scope = scope->outer_scope()) {
372 Variable* var = scope->LocalLookup(name); 371 Variable* var = scope->LocalLookup(name);
373 if (var != NULL) return var; 372 if (var != NULL) return var;
374 } 373 }
375 return NULL; 374 return NULL;
376 } 375 }
377 376
378 377
379 Variable* Scope::DeclareFunctionVar(Handle<String> name) { 378 Variable* Scope::DeclareFunctionVar(Handle<String> name) {
380 ASSERT(is_function_scope() && function_ == NULL); 379 ASSERT(is_function_scope() && function_ == NULL);
381 Variable* function_var = 380 Variable* function_var =
382 new Variable(this, name, Variable::CONST, true, Variable::NORMAL); 381 new Variable(this, name, Variable::CONST, true, Variable::NORMAL);
383 function_ = new(isolate_->zone()) VariableProxy(isolate_, function_var); 382 function_ = new(isolate_->zone()) VariableProxy(isolate_, function_var);
384 return function_->var(); 383 return function_var;
385 } 384 }
386 385
387 386
388 void Scope::DeclareParameter(Handle<String> name, Variable::Mode mode) { 387 void Scope::DeclareParameter(Handle<String> name, Variable::Mode mode) {
389 ASSERT(!already_resolved()); 388 ASSERT(!already_resolved());
390 ASSERT(is_function_scope()); 389 ASSERT(is_function_scope());
391 Variable* var = 390 Variable* var =
392 variables_.Declare(this, name, mode, true, Variable::NORMAL); 391 variables_.Declare(this, name, mode, true, Variable::NORMAL);
393 params_.Add(var); 392 params_.Add(var);
394 } 393 }
395 394
396 395
397 Variable* Scope::DeclareLocal(Handle<String> name, Variable::Mode mode) { 396 Variable* Scope::DeclareLocal(Handle<String> name, Variable::Mode mode) {
398 ASSERT(!already_resolved()); 397 ASSERT(!already_resolved());
399 // This function handles VAR and CONST modes. DYNAMIC variables are 398 // This function handles VAR and CONST modes. DYNAMIC variables are
400 // introduces during variable allocation, INTERNAL variables are allocated 399 // introduces during variable allocation, INTERNAL variables are allocated
401 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). 400 // explicitly, and TEMPORARY variables are allocated via NewTemporary().
402 ASSERT(mode == Variable::VAR || 401 ASSERT(mode == Variable::VAR ||
403 mode == Variable::CONST || 402 mode == Variable::CONST ||
404 mode == Variable::LET); 403 mode == Variable::LET);
405 ++num_var_or_const_; 404 ++num_var_or_const_;
406 return variables_.Declare(this, name, mode, true, Variable::NORMAL); 405 return variables_.Declare(this, name, mode, true, Variable::NORMAL);
407 } 406 }
408 407
409 408
410 Variable* Scope::DeclareGlobal(Handle<String> name) { 409 Variable* Scope::DeclareGlobal(Handle<String> name) {
411 ASSERT(is_global_scope()); 410 ASSERT(is_global_scope());
412 return variables_.Declare(this, name, Variable::DYNAMIC_GLOBAL, true, 411 return variables_.Declare(this, name, Variable::DYNAMIC_GLOBAL,
412 true,
413 Variable::NORMAL); 413 Variable::NORMAL);
414 } 414 }
415 415
416 416
417 VariableProxy* Scope::NewUnresolved(Handle<String> name, 417 VariableProxy* Scope::NewUnresolved(Handle<String> name,
418 bool inside_with, 418 bool inside_with,
419 int position) { 419 int position) {
420 // Note that we must not share the unresolved variables with 420 // Note that we must not share the unresolved variables with
421 // the same name because they may be removed selectively via 421 // the same name because they may be removed selectively via
422 // RemoveUnresolved(). 422 // RemoveUnresolved().
(...skipping 12 matching lines...) Expand all
435 if (unresolved_[i] == var) { 435 if (unresolved_[i] == var) {
436 unresolved_.Remove(i); 436 unresolved_.Remove(i);
437 return; 437 return;
438 } 438 }
439 } 439 }
440 } 440 }
441 441
442 442
443 Variable* Scope::NewTemporary(Handle<String> name) { 443 Variable* Scope::NewTemporary(Handle<String> name) {
444 ASSERT(!already_resolved()); 444 ASSERT(!already_resolved());
445 Variable* var = 445 Variable* var = new Variable(this,
446 new Variable(this, name, Variable::TEMPORARY, true, Variable::NORMAL); 446 name,
447 Variable::TEMPORARY,
448 true,
449 Variable::NORMAL);
447 temps_.Add(var); 450 temps_.Add(var);
448 return var; 451 return var;
449 } 452 }
450 453
451 454
452 void Scope::AddDeclaration(Declaration* declaration) { 455 void Scope::AddDeclaration(Declaration* declaration) {
453 decls_.Add(declaration); 456 decls_.Add(declaration);
454 } 457 }
455 458
456 459
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 PrintF("%*s%s", n, "", str); 632 PrintF("%*s%s", n, "", str);
630 } 633 }
631 634
632 635
633 static void PrintName(Handle<String> name) { 636 static void PrintName(Handle<String> name) {
634 SmartPointer<char> s = name->ToCString(DISALLOW_NULLS); 637 SmartPointer<char> s = name->ToCString(DISALLOW_NULLS);
635 PrintF("%s", *s); 638 PrintF("%s", *s);
636 } 639 }
637 640
638 641
639 static void PrintVar(PrettyPrinter* printer, int indent, Variable* var) { 642 static void PrintLocation(Variable* var) {
640 if (var->is_used() || var->rewrite() != NULL) { 643 switch (var->location()) {
644 case Variable::UNALLOCATED:
645 break;
646 case Variable::PARAMETER:
647 PrintF("parameter[%d]", var->index());
648 break;
649 case Variable::LOCAL:
650 PrintF("local[%d]", var->index());
651 break;
652 case Variable::CONTEXT:
653 PrintF("context[%d]", var->index());
654 break;
655 case Variable::LOOKUP:
656 PrintF("lookup");
657 break;
658 }
659 }
660
661
662 static void PrintVar(int indent, Variable* var) {
663 if (var->is_used() || !var->IsUnallocated()) {
641 Indent(indent, Variable::Mode2String(var->mode())); 664 Indent(indent, Variable::Mode2String(var->mode()));
642 PrintF(" "); 665 PrintF(" ");
643 PrintName(var->name()); 666 PrintName(var->name());
644 PrintF("; // "); 667 PrintF("; // ");
645 if (var->rewrite() != NULL) { 668 PrintLocation(var);
646 PrintF("%s, ", printer->Print(var->rewrite()));
647 if (var->is_accessed_from_inner_function_scope()) PrintF(", ");
648 }
649 if (var->is_accessed_from_inner_function_scope()) { 669 if (var->is_accessed_from_inner_function_scope()) {
670 if (!var->IsUnallocated()) PrintF(", ");
650 PrintF("inner scope access"); 671 PrintF("inner scope access");
651 } 672 }
652 PrintF("\n"); 673 PrintF("\n");
653 } 674 }
654 } 675 }
655 676
656 677
657 static void PrintMap(PrettyPrinter* printer, int indent, VariableMap* map) { 678 static void PrintMap(int indent, VariableMap* map) {
658 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { 679 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
659 Variable* var = reinterpret_cast<Variable*>(p->value); 680 Variable* var = reinterpret_cast<Variable*>(p->value);
660 PrintVar(printer, indent, var); 681 PrintVar(indent, var);
661 } 682 }
662 } 683 }
663 684
664 685
665 void Scope::Print(int n) { 686 void Scope::Print(int n) {
666 int n0 = (n > 0 ? n : 0); 687 int n0 = (n > 0 ? n : 0);
667 int n1 = n0 + 2; // indentation 688 int n1 = n0 + 2; // indentation
668 689
669 // Print header. 690 // Print header.
670 Indent(n0, Header(type_)); 691 Indent(n0, Header(type_));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); 728 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
708 if (outer_scope_is_eval_scope_) { 729 if (outer_scope_is_eval_scope_) {
709 Indent(n1, "// outer scope is 'eval' scope\n"); 730 Indent(n1, "// outer scope is 'eval' scope\n");
710 } 731 }
711 if (num_stack_slots_ > 0) { Indent(n1, "// "); 732 if (num_stack_slots_ > 0) { Indent(n1, "// ");
712 PrintF("%d stack slots\n", num_stack_slots_); } 733 PrintF("%d stack slots\n", num_stack_slots_); }
713 if (num_heap_slots_ > 0) { Indent(n1, "// "); 734 if (num_heap_slots_ > 0) { Indent(n1, "// ");
714 PrintF("%d heap slots\n", num_heap_slots_); } 735 PrintF("%d heap slots\n", num_heap_slots_); }
715 736
716 // Print locals. 737 // Print locals.
717 PrettyPrinter printer;
718 Indent(n1, "// function var\n"); 738 Indent(n1, "// function var\n");
719 if (function_ != NULL) { 739 if (function_ != NULL) {
720 PrintVar(&printer, n1, function_->var()); 740 PrintVar(n1, function_->var());
721 } 741 }
722 742
723 Indent(n1, "// temporary vars\n"); 743 Indent(n1, "// temporary vars\n");
724 for (int i = 0; i < temps_.length(); i++) { 744 for (int i = 0; i < temps_.length(); i++) {
725 PrintVar(&printer, n1, temps_[i]); 745 PrintVar(n1, temps_[i]);
726 } 746 }
727 747
728 Indent(n1, "// local vars\n"); 748 Indent(n1, "// local vars\n");
729 PrintMap(&printer, n1, &variables_); 749 PrintMap(n1, &variables_);
730 750
731 Indent(n1, "// dynamic vars\n"); 751 Indent(n1, "// dynamic vars\n");
732 if (dynamics_ != NULL) { 752 if (dynamics_ != NULL) {
733 PrintMap(&printer, n1, dynamics_->GetMap(Variable::DYNAMIC)); 753 PrintMap(n1, dynamics_->GetMap(Variable::DYNAMIC));
734 PrintMap(&printer, n1, dynamics_->GetMap(Variable::DYNAMIC_LOCAL)); 754 PrintMap(n1, dynamics_->GetMap(Variable::DYNAMIC_LOCAL));
735 PrintMap(&printer, n1, dynamics_->GetMap(Variable::DYNAMIC_GLOBAL)); 755 PrintMap(n1, dynamics_->GetMap(Variable::DYNAMIC_GLOBAL));
736 } 756 }
737 757
738 // Print inner scopes (disable by providing negative n). 758 // Print inner scopes (disable by providing negative n).
739 if (n >= 0) { 759 if (n >= 0) {
740 for (int i = 0; i < inner_scopes_.length(); i++) { 760 for (int i = 0; i < inner_scopes_.length(); i++) {
741 PrintF("\n"); 761 PrintF("\n");
742 inner_scopes_[i]->Print(n1); 762 inner_scopes_[i]->Print(n1);
743 } 763 }
744 } 764 }
745 765
746 Indent(n0, "}\n"); 766 Indent(n0, "}\n");
747 } 767 }
748 #endif // DEBUG 768 #endif // DEBUG
749 769
750 770
751 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { 771 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) {
752 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart(); 772 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart();
753 VariableMap* map = dynamics_->GetMap(mode); 773 VariableMap* map = dynamics_->GetMap(mode);
754 Variable* var = map->Lookup(name); 774 Variable* var = map->Lookup(name);
755 if (var == NULL) { 775 if (var == NULL) {
756 // Declare a new non-local. 776 // Declare a new non-local.
757 var = map->Declare(NULL, name, mode, true, Variable::NORMAL); 777 var = map->Declare(NULL, name, mode, true, Variable::NORMAL);
758 // Allocate it by giving it a dynamic lookup. 778 // Allocate it by giving it a dynamic lookup.
759 var->set_rewrite(NewSlot(var, Slot::LOOKUP, -1)); 779 var->AllocateTo(Variable::LOOKUP, -1);
760 } 780 }
761 return var; 781 return var;
762 } 782 }
763 783
764 784
765 // Lookup a variable starting with this scope. The result is either 785 // Lookup a variable starting with this scope. The result is either
766 // the statically resolved variable belonging to an outer scope, or 786 // the statically resolved variable belonging to an outer scope, or
767 // NULL. It may be NULL because a) we couldn't find a variable, or b) 787 // NULL. It may be NULL because a) we couldn't find a variable, or b)
768 // because the variable is just a guess (and may be shadowed by 788 // because the variable is just a guess (and may be shadowed by
769 // another variable that is introduced dynamically via an 'eval' call 789 // another variable that is introduced dynamically via an 'eval' call
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 if (params_[i]->name().is_identical_to( 1029 if (params_[i]->name().is_identical_to(
1010 isolate_->factory()->arguments_symbol())) { 1030 isolate_->factory()->arguments_symbol())) {
1011 return true; 1031 return true;
1012 } 1032 }
1013 } 1033 }
1014 return false; 1034 return false;
1015 } 1035 }
1016 1036
1017 1037
1018 void Scope::AllocateStackSlot(Variable* var) { 1038 void Scope::AllocateStackSlot(Variable* var) {
1019 var->set_rewrite(NewSlot(var, Slot::LOCAL, num_stack_slots_++)); 1039 var->AllocateTo(Variable::LOCAL, num_stack_slots_++);
1020 } 1040 }
1021 1041
1022 1042
1023 void Scope::AllocateHeapSlot(Variable* var) { 1043 void Scope::AllocateHeapSlot(Variable* var) {
1024 var->set_rewrite(NewSlot(var, Slot::CONTEXT, num_heap_slots_++)); 1044 var->AllocateTo(Variable::CONTEXT, num_heap_slots_++);
1025 } 1045 }
1026 1046
1027 1047
1028 void Scope::AllocateParameterLocals() { 1048 void Scope::AllocateParameterLocals() {
1029 ASSERT(is_function_scope()); 1049 ASSERT(is_function_scope());
1030 Variable* arguments = LocalLookup(isolate_->factory()->arguments_symbol()); 1050 Variable* arguments = LocalLookup(isolate_->factory()->arguments_symbol());
1031 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly 1051 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly
1032 1052
1033 bool uses_nonstrict_arguments = false; 1053 bool uses_nonstrict_arguments = false;
1034 1054
(...skipping 25 matching lines...) Expand all
1060 Variable* var = params_[i]; 1080 Variable* var = params_[i];
1061 ASSERT(var->scope() == this); 1081 ASSERT(var->scope() == this);
1062 if (uses_nonstrict_arguments) { 1082 if (uses_nonstrict_arguments) {
1063 // Give the parameter a use from an inner scope, to force allocation 1083 // Give the parameter a use from an inner scope, to force allocation
1064 // to the context. 1084 // to the context.
1065 var->MarkAsAccessedFromInnerFunctionScope(); 1085 var->MarkAsAccessedFromInnerFunctionScope();
1066 } 1086 }
1067 1087
1068 if (MustAllocate(var)) { 1088 if (MustAllocate(var)) {
1069 if (MustAllocateInContext(var)) { 1089 if (MustAllocateInContext(var)) {
1070 ASSERT(var->rewrite() == NULL || var->IsContextSlot()); 1090 ASSERT(var->IsUnallocated() || var->IsContextSlot());
1071 if (var->rewrite() == NULL) { 1091 if (var->IsUnallocated()) {
1072 AllocateHeapSlot(var); 1092 AllocateHeapSlot(var);
1073 } 1093 }
1074 } else { 1094 } else {
1075 ASSERT(var->rewrite() == NULL || var->IsParameter()); 1095 ASSERT(var->IsUnallocated() || var->IsParameter());
1076 if (var->rewrite() == NULL) { 1096 if (var->IsUnallocated()) {
1077 var->set_rewrite(NewSlot(var, Slot::PARAMETER, i)); 1097 var->AllocateTo(Variable::PARAMETER, i);
1078 } 1098 }
1079 } 1099 }
1080 } 1100 }
1081 } 1101 }
1082 } 1102 }
1083 1103
1084 1104
1085 void Scope::AllocateNonParameterLocal(Variable* var) { 1105 void Scope::AllocateNonParameterLocal(Variable* var) {
1086 ASSERT(var->scope() == this); 1106 ASSERT(var->scope() == this);
1087 ASSERT(var->rewrite() == NULL || 1107 ASSERT(!var->IsVariable(isolate_->factory()->result_symbol()) ||
1088 !var->IsVariable(isolate_->factory()->result_symbol()) || 1108 !var->IsStackLocal());
1089 var->AsSlot() == NULL || 1109 if (var->IsUnallocated() && MustAllocate(var)) {
1090 var->AsSlot()->type() != Slot::LOCAL);
1091 if (var->rewrite() == NULL && MustAllocate(var)) {
1092 if (MustAllocateInContext(var)) { 1110 if (MustAllocateInContext(var)) {
1093 AllocateHeapSlot(var); 1111 AllocateHeapSlot(var);
1094 } else { 1112 } else {
1095 AllocateStackSlot(var); 1113 AllocateStackSlot(var);
1096 } 1114 }
1097 } 1115 }
1098 } 1116 }
1099 1117
1100 1118
1101 void Scope::AllocateNonParameterLocals() { 1119 void Scope::AllocateNonParameterLocals() {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && 1173 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
1156 !must_have_local_context) { 1174 !must_have_local_context) {
1157 num_heap_slots_ = 0; 1175 num_heap_slots_ = 0;
1158 } 1176 }
1159 1177
1160 // Allocation done. 1178 // Allocation done.
1161 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); 1179 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
1162 } 1180 }
1163 1181
1164 } } // namespace v8::internal 1182 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698