[stubs] Use a single slot for context globals.
authorbmeurer <bmeurer@chromium.org>
Tue, 28 Jul 2015 08:18:17 +0000 (01:18 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 28 Jul 2015 08:18:33 +0000 (08:18 +0000)
Don't use different read/write slots for context globals, but
let them share the same slot, which reduces the number of
initial misses, and also saves some memory for large scripts.

R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/1258213002

Cr-Commit-Position: refs/heads/master@{#29889}

13 files changed:
src/compiler/ast-graph-builder.cc
src/contexts.cc
src/full-codegen/arm/full-codegen-arm.cc
src/full-codegen/arm64/full-codegen-arm64.cc
src/full-codegen/ia32/full-codegen-ia32.cc
src/full-codegen/mips/full-codegen-mips.cc
src/full-codegen/mips64/full-codegen-mips64.cc
src/full-codegen/ppc/full-codegen-ppc.cc
src/full-codegen/x64/full-codegen-x64.cc
src/full-codegen/x87/full-codegen-x87.cc
src/hydrogen.cc
src/scopeinfo.cc
src/scopes.cc

index 7ccb8aa320d18044f9bdf1ab77f9d37f371f9eed..a9a767817515558621ffdf381352033aaf5a367d 100644 (file)
@@ -3334,7 +3334,6 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
       int slot_index = -1;
       if (variable->index() > 0) {
         DCHECK(variable->IsStaticGlobalObjectProperty());
       int slot_index = -1;
       if (variable->index() > 0) {
         DCHECK(variable->IsStaticGlobalObjectProperty());
-        // Each var occupies two slots in the context: for reads and writes.
         slot_index = variable->index();
         int depth = current_scope()->ContextChainLength(variable->scope());
         if (depth > 0) {
         slot_index = variable->index();
         int depth = current_scope()->ContextChainLength(variable->scope());
         if (depth > 0) {
@@ -3485,7 +3484,6 @@ Node* AstGraphBuilder::BuildVariableAssignment(
       int slot_index = -1;
       if (variable->index() > 0) {
         DCHECK(variable->IsStaticGlobalObjectProperty());
       int slot_index = -1;
       if (variable->index() > 0) {
         DCHECK(variable->IsStaticGlobalObjectProperty());
-        // Each var occupies two slots in the context: for reads and writes.
         slot_index = variable->index();
         int depth = current_scope()->ContextChainLength(variable->scope());
         if (depth > 0) {
         slot_index = variable->index();
         int depth = current_scope()->ContextChainLength(variable->scope());
         if (depth > 0) {
index 88f593fab8525a197cc2d13d47dbdf8ece4a3292..31ce98c8986b402bba38a1d13a1f87be9b2f6d9e 100644 (file)
@@ -365,8 +365,6 @@ void Context::InitializeGlobalSlots() {
     int context_locals = scope_info->ContextLocalCount();
     int index = Context::MIN_CONTEXT_SLOTS + context_locals;
     for (int i = 0; i < context_globals; i++) {
     int context_locals = scope_info->ContextLocalCount();
     int index = Context::MIN_CONTEXT_SLOTS + context_locals;
     for (int i = 0; i < context_globals; i++) {
-      // Clear both read and write slots.
-      set(index++, empty_cell);
       set(index++, empty_cell);
     }
   }
       set(index++, empty_cell);
     }
   }
index 705e2b79a76456dcf466d4754d4fa267bc4403dd..16bd8bc27d2109dcbfb63e546978829f4c31ba00 100644 (file)
@@ -1414,7 +1414,6 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
   if (var->IsGlobalSlot()) {
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
   if (var->IsGlobalSlot()) {
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
-    // Each var occupies two slots in the context: for reads and writes.
     const int slot = var->index();
     const int depth = scope()->ContextChainLength(var->scope());
     if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
     const int slot = var->index();
     const int depth = scope()->ContextChainLength(var->scope());
     if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
@@ -2713,8 +2712,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
     // Global var, const, or let.
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
     // Global var, const, or let.
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
-    // Each var occupies two slots in the context: for reads and writes.
-    const int slot = var->index() + 1;
+    const int slot = var->index();
     const int depth = scope()->ContextChainLength(var->scope());
     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
       __ mov(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
     const int depth = scope()->ContextChainLength(var->scope());
     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
       __ mov(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
index 78681b4683499368feddee72f33b80214838583d..40af62cf1953f2b95a2b129b24c3a722eef8b3ea 100644 (file)
@@ -1397,7 +1397,6 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
   if (var->IsGlobalSlot()) {
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
   if (var->IsGlobalSlot()) {
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
-    // Each var occupies two slots in the context: for reads and writes.
     int const slot = var->index();
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
     int const slot = var->index();
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
@@ -2399,8 +2398,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
     // Global var, const, or let.
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
     // Global var, const, or let.
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
-    // Each var occupies two slots in the context: for reads and writes.
-    int const slot = var->index() + 1;
+    int const slot = var->index();
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
       __ Mov(StoreGlobalViaContextDescriptor::SlotRegister(), slot);
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
       __ Mov(StoreGlobalViaContextDescriptor::SlotRegister(), slot);
index bebd0fbbe995082b337e4f5095f588668e1b80e3..6652c92e9fd2f0a9dbdf1d48bab44a3ae11031bb 100644 (file)
@@ -1340,7 +1340,6 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
   if (var->IsGlobalSlot()) {
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
   if (var->IsGlobalSlot()) {
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
-    // Each var occupies two slots in the context: for reads and writes.
     int const slot = var->index();
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
     int const slot = var->index();
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
@@ -2620,8 +2619,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
     // Global var, const, or let.
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
     // Global var, const, or let.
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
-    // Each var occupies two slots in the context: for reads and writes.
-    int const slot = var->index() + 1;
+    int const slot = var->index();
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
       __ Move(StoreGlobalViaContextDescriptor::SlotRegister(), Immediate(slot));
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
       __ Move(StoreGlobalViaContextDescriptor::SlotRegister(), Immediate(slot));
index 35e6da2bb5b19bc14e1d6a1ab54b30903ea6bf83..47fe9118075bba5bfe444da00e925cf686fccd6e 100644 (file)
@@ -1406,7 +1406,6 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
   if (var->IsGlobalSlot()) {
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
   if (var->IsGlobalSlot()) {
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
-    // Each var occupies two slots in the context: for reads and writes.
     int const slot = var->index();
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
     int const slot = var->index();
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
@@ -2703,8 +2702,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
     DCHECK(var->IsStaticGlobalObjectProperty());
     DCHECK(StoreGlobalViaContextDescriptor::ValueRegister().is(a0));
     __ mov(StoreGlobalViaContextDescriptor::ValueRegister(), result_register());
     DCHECK(var->IsStaticGlobalObjectProperty());
     DCHECK(StoreGlobalViaContextDescriptor::ValueRegister().is(a0));
     __ mov(StoreGlobalViaContextDescriptor::ValueRegister(), result_register());
-    // Each var occupies two slots in the context: for reads and writes.
-    int const slot = var->index() + 1;
+    int const slot = var->index();
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
       __ li(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
       __ li(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
index 7b2cda3f3dfb83c90f0060a4552f3145b916baad..89c5593790dd88498819fbe442f0552a09e1cebc 100644 (file)
@@ -1402,7 +1402,6 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
   if (var->IsGlobalSlot()) {
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
   if (var->IsGlobalSlot()) {
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
-    // Each var occupies two slots in the context: for reads and writes.
     int const slot = var->index();
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
     int const slot = var->index();
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
@@ -2700,8 +2699,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
     DCHECK(var->IsStaticGlobalObjectProperty());
     DCHECK(StoreGlobalViaContextDescriptor::ValueRegister().is(a0));
     __ mov(StoreGlobalViaContextDescriptor::ValueRegister(), result_register());
     DCHECK(var->IsStaticGlobalObjectProperty());
     DCHECK(StoreGlobalViaContextDescriptor::ValueRegister().is(a0));
     __ mov(StoreGlobalViaContextDescriptor::ValueRegister(), result_register());
-    // Each var occupies two slots in the context: for reads and writes.
-    int const slot = var->index() + 1;
+    int const slot = var->index();
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
       __ li(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
       __ li(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
index 0654a9a64abd4d92ea47bee487ab154613be656d..68a0dc0bdee861b76a0e9e910a0d7c6dfdceae5f 100644 (file)
@@ -1377,7 +1377,6 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
   if (var->IsGlobalSlot()) {
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
   if (var->IsGlobalSlot()) {
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
-    // Each var occupies two slots in the context: for reads and writes.
     const int slot = var->index();
     const int depth = scope()->ContextChainLength(var->scope());
     if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
     const int slot = var->index();
     const int depth = scope()->ContextChainLength(var->scope());
     if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
@@ -2715,8 +2714,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
     // Global var, const, or let.
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
     // Global var, const, or let.
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
-    // Each var occupies two slots in the context: for reads and writes.
-    const int slot = var->index() + 1;
+    const int slot = var->index();
     const int depth = scope()->ContextChainLength(var->scope());
     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
       __ mov(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
     const int depth = scope()->ContextChainLength(var->scope());
     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
       __ mov(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
index 1839d2c22219417d0f26e865c2866ebe1c514e87..894a64a2ee657f5c23b9b79ddaad84cf1febc17d 100644 (file)
@@ -2614,8 +2614,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
     // Global var, const, or let.
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
     // Global var, const, or let.
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
-    // Each var occupies two slots in the context: for reads and writes.
-    int const slot = var->index() + 1;
+    int const slot = var->index();
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
       __ Set(StoreGlobalViaContextDescriptor::SlotRegister(), slot);
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
       __ Set(StoreGlobalViaContextDescriptor::SlotRegister(), slot);
index 1e93fe1fa86a029e662a5f6e5fe76d20c7fde88b..8f40e0513f55d046c4b388496a445bcc67769260 100644 (file)
@@ -1333,7 +1333,6 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
   if (var->IsGlobalSlot()) {
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
   if (var->IsGlobalSlot()) {
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
-    // Each var occupies two slots in the context: for reads and writes.
     int const slot = var->index();
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
     int const slot = var->index();
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
@@ -2613,8 +2612,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
     // Global var, const, or let.
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
     // Global var, const, or let.
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
-    // Each var occupies two slots in the context: for reads and writes.
-    int const slot = var->index() + 1;
+    int const slot = var->index();
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
       __ Move(StoreGlobalViaContextDescriptor::SlotRegister(), Immediate(slot));
     int const depth = scope()->ContextChainLength(var->scope());
     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
       __ Move(StoreGlobalViaContextDescriptor::SlotRegister(), Immediate(slot));
index f652b313ca9765f93e3db44157c7f323be9483e2..2689e42d5c1d89e38bb3f698b6503be70e5bc965 100644 (file)
@@ -5564,7 +5564,6 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
       } else if (variable->IsGlobalSlot()) {
         DCHECK(variable->index() > 0);
         DCHECK(variable->IsStaticGlobalObjectProperty());
       } else if (variable->IsGlobalSlot()) {
         DCHECK(variable->index() > 0);
         DCHECK(variable->IsStaticGlobalObjectProperty());
-        // Each var occupies two slots in the context: for reads and writes.
         int slot_index = variable->index();
         int depth = scope()->ContextChainLength(variable->scope());
 
         int slot_index = variable->index();
         int depth = scope()->ContextChainLength(variable->scope());
 
@@ -6796,8 +6795,7 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
   } else if (var->IsGlobalSlot()) {
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
   } else if (var->IsGlobalSlot()) {
     DCHECK(var->index() > 0);
     DCHECK(var->IsStaticGlobalObjectProperty());
-    // Each var occupies two slots in the context: for reads and writes.
-    int slot_index = var->index() + 1;
+    int slot_index = var->index();
     int depth = scope()->ContextChainLength(var->scope());
 
     HStoreGlobalViaContext* instr = Add<HStoreGlobalViaContext>(
     int depth = scope()->ContextChainLength(var->scope());
 
     HStoreGlobalViaContext* instr = Add<HStoreGlobalViaContext>(
index c79a98060cccb039999c811e0e5ac626bb10a2e4..fda3b1bd38978c68a3618981ed4728393958e2a1 100644 (file)
@@ -340,7 +340,7 @@ int ScopeInfo::ContextLength() {
                        scope_type() == MODULE_SCOPE;
 
     if (has_context) {
                        scope_type() == MODULE_SCOPE;
 
     if (has_context) {
-      return Context::MIN_CONTEXT_SLOTS + context_locals + 2 * context_globals +
+      return Context::MIN_CONTEXT_SLOTS + context_locals + context_globals +
              (function_name_context_slot ? 1 : 0);
     }
   }
              (function_name_context_slot ? 1 : 0);
     }
   }
@@ -553,7 +553,7 @@ int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
           var -= scope_info->ContextLocalCount();
           *location = VariableLocation::GLOBAL;
           result = Context::MIN_CONTEXT_SLOTS +
           var -= scope_info->ContextLocalCount();
           *location = VariableLocation::GLOBAL;
           result = Context::MIN_CONTEXT_SLOTS +
-                   scope_info->ContextLocalCount() + 2 * var;
+                   scope_info->ContextLocalCount() + var;
         }
 
         context_slot_cache->Update(scope_info, name, *mode, *location,
         }
 
         context_slot_cache->Update(scope_info, name, *mode, *location,
@@ -573,15 +573,10 @@ int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
 
 
 String* ScopeInfo::ContextSlotName(int slot_index) {
 
 
 String* ScopeInfo::ContextSlotName(int slot_index) {
-  // TODO(bmeurer): Simplify this once we have only a single slot for both reads
-  // and writes to context globals;  currently we have 2 slots per context
-  // global, and these are located after the common context slots (of which we
-  // always have Context::MIN_CONTEXT_SLOTS) and the context locals.
-  int const var =
-      slot_index - (Context::MIN_CONTEXT_SLOTS + ContextLocalCount());
+  int const var = slot_index - Context::MIN_CONTEXT_SLOTS;
   DCHECK_LE(0, var);
   DCHECK_LE(0, var);
-  DCHECK_LT(var, 2 * ContextGlobalCount());
-  return ContextLocalName(ContextLocalCount() + var / 2);
+  DCHECK_LT(var, ContextLocalCount() + ContextGlobalCount());
+  return ContextLocalName(var);
 }
 
 
 }
 
 
index bf580cfa74cc21b86c6ab597063645c8a74a6da4..1473b2471f59ebbd87acf6cebdbd5f3c114cfc42 100644 (file)
@@ -1470,11 +1470,8 @@ void Scope::AllocateDeclaredGlobal(Isolate* isolate, Variable* var) {
     if (var->IsStaticGlobalObjectProperty()) {
       DCHECK_EQ(-1, var->index());
       DCHECK(var->name()->IsString());
     if (var->IsStaticGlobalObjectProperty()) {
       DCHECK_EQ(-1, var->index());
       DCHECK(var->name()->IsString());
-      var->AllocateTo(VariableLocation::GLOBAL, num_heap_slots_);
+      var->AllocateTo(VariableLocation::GLOBAL, num_heap_slots_++);
       num_global_slots_++;
       num_global_slots_++;
-      // Each global variable occupies two slots in the context: for reads
-      // and writes.
-      num_heap_slots_ += 2;
     } else {
       // There must be only DYNAMIC_GLOBAL in the script scope.
       DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode());
     } else {
       // There must be only DYNAMIC_GLOBAL in the script scope.
       DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode());
@@ -1600,11 +1597,12 @@ int Scope::ContextLocalCount() const {
   if (num_heap_slots() == 0) return 0;
   bool is_function_var_in_context =
       function_ != NULL && function_->proxy()->var()->IsContextSlot();
   if (num_heap_slots() == 0) return 0;
   bool is_function_var_in_context =
       function_ != NULL && function_->proxy()->var()->IsContextSlot();
-  return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
-         2 * num_global_slots() - (is_function_var_in_context ? 1 : 0);
+  return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() -
+         (is_function_var_in_context ? 1 : 0);
 }
 
 
 int Scope::ContextGlobalCount() const { return num_global_slots(); }
 }
 
 
 int Scope::ContextGlobalCount() const { return num_global_slots(); }
+
 }  // namespace internal
 }  // namespace v8
 }  // namespace internal
 }  // namespace v8