Commit aec46ca5 authored by dslomov's avatar dslomov Committed by Commit bot

Stack allocate lexical locals + hoist stack slots

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

Cr-Commit-Position: refs/heads/master@{#28008}
parent b3a8f612
......@@ -1022,10 +1022,15 @@ void AstGraphBuilder::VisitBlock(Block* stmt) {
VisitStatements(stmt->statements());
} else {
// Visit declarations and statements in a block scope.
Node* context = BuildLocalBlockContext(stmt->scope());
ContextScope scope(this, stmt->scope(), context);
VisitDeclarations(stmt->scope()->declarations());
VisitStatements(stmt->statements());
if (stmt->scope()->ContextLocalCount() > 0) {
Node* context = BuildLocalBlockContext(stmt->scope());
ContextScope scope(this, stmt->scope(), context);
VisitDeclarations(stmt->scope()->declarations());
VisitStatements(stmt->statements());
} else {
VisitDeclarations(stmt->scope()->declarations());
VisitStatements(stmt->statements());
}
}
if (stmt->labels() != NULL) block.EndBlock();
}
......@@ -1480,10 +1485,15 @@ void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) {
VisitClassLiteralContents(expr);
} else {
// Visit declarations and class literal in a block scope.
Node* context = BuildLocalBlockContext(expr->scope());
ContextScope scope(this, expr->scope(), context);
VisitDeclarations(expr->scope()->declarations());
VisitClassLiteralContents(expr);
if (expr->scope()->ContextLocalCount() > 0) {
Node* context = BuildLocalBlockContext(expr->scope());
ContextScope scope(this, expr->scope(), context);
VisitDeclarations(expr->scope()->declarations());
VisitClassLiteralContents(expr);
} else {
VisitDeclarations(expr->scope()->declarations());
VisitClassLiteralContents(expr);
}
}
}
......
......@@ -1814,22 +1814,27 @@ bool BackEdgeTable::Verify(Isolate* isolate, Code* unoptimized) {
FullCodeGenerator::EnterBlockScopeIfNeeded::EnterBlockScopeIfNeeded(
FullCodeGenerator* codegen, Scope* scope, BailoutId entry_id,
BailoutId declarations_id, BailoutId exit_id)
: codegen_(codegen), scope_(scope), exit_id_(exit_id) {
: codegen_(codegen), exit_id_(exit_id) {
saved_scope_ = codegen_->scope();
if (scope == NULL) {
codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS);
needs_block_context_ = false;
} else {
needs_block_context_ = scope->ContextLocalCount() > 0;
codegen_->scope_ = scope;
{
Comment cmnt(masm(), "[ Extend block context");
__ Push(scope->GetScopeInfo(codegen->isolate()));
codegen_->PushFunctionArgumentForContextAllocation();
__ CallRuntime(Runtime::kPushBlockContext, 2);
// Replace the context stored in the frame.
codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset,
codegen_->context_register());
if (needs_block_context_) {
Comment cmnt(masm(), "[ Extend block context");
__ Push(scope->GetScopeInfo(codegen->isolate()));
codegen_->PushFunctionArgumentForContextAllocation();
__ CallRuntime(Runtime::kPushBlockContext, 2);
// Replace the context stored in the frame.
codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset,
codegen_->context_register());
}
CHECK_EQ(0, scope->num_stack_slots());
codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS);
}
{
......@@ -1842,7 +1847,7 @@ FullCodeGenerator::EnterBlockScopeIfNeeded::EnterBlockScopeIfNeeded(
FullCodeGenerator::EnterBlockScopeIfNeeded::~EnterBlockScopeIfNeeded() {
if (scope_ != NULL) {
if (needs_block_context_) {
codegen_->LoadContextField(codegen_->context_register(),
Context::PREVIOUS_INDEX);
// Update local stack frame context field.
......
......@@ -16,6 +16,7 @@
#include "src/compiler.h"
#include "src/globals.h"
#include "src/objects.h"
#include "src/scopes.h"
namespace v8 {
namespace internal {
......@@ -220,8 +221,9 @@ class FullCodeGenerator: public AstVisitor {
virtual ~NestedBlock() {}
virtual NestedStatement* Exit(int* stack_depth, int* context_length) {
if (statement()->AsBlock()->scope() != NULL) {
++(*context_length);
auto block_scope = statement()->AsBlock()->scope();
if (block_scope != nullptr) {
if (block_scope->ContextLocalCount() > 0) ++(*context_length);
}
return previous_;
}
......@@ -968,9 +970,9 @@ class FullCodeGenerator: public AstVisitor {
MacroAssembler* masm() const { return codegen_->masm(); }
FullCodeGenerator* codegen_;
Scope* scope_;
Scope* saved_scope_;
BailoutId exit_id_;
bool needs_block_context_;
};
MacroAssembler* masm_;
......
......@@ -4512,26 +4512,29 @@ void HOptimizedGraphBuilder::VisitBlock(Block* stmt) {
{ BreakAndContinueScope push(&break_info, this);
if (scope != NULL) {
// Load the function object.
Scope* declaration_scope = scope->DeclarationScope();
HInstruction* function;
HValue* outer_context = environment()->context();
if (declaration_scope->is_script_scope() ||
declaration_scope->is_eval_scope()) {
function = new(zone()) HLoadContextSlot(
outer_context, Context::CLOSURE_INDEX, HLoadContextSlot::kNoCheck);
} else {
function = New<HThisFunction>();
}
AddInstruction(function);
// Allocate a block context and store it to the stack frame.
HInstruction* inner_context = Add<HAllocateBlockContext>(
outer_context, function, scope->GetScopeInfo(isolate()));
HInstruction* instr = Add<HStoreFrameContext>(inner_context);
set_scope(scope);
environment()->BindContext(inner_context);
if (instr->HasObservableSideEffects()) {
AddSimulate(stmt->EntryId(), REMOVABLE_SIMULATE);
if (scope->ContextLocalCount() > 0) {
// Load the function object.
Scope* declaration_scope = scope->DeclarationScope();
HInstruction* function;
HValue* outer_context = environment()->context();
if (declaration_scope->is_script_scope() ||
declaration_scope->is_eval_scope()) {
function = new (zone())
HLoadContextSlot(outer_context, Context::CLOSURE_INDEX,
HLoadContextSlot::kNoCheck);
} else {
function = New<HThisFunction>();
}
AddInstruction(function);
// Allocate a block context and store it to the stack frame.
HInstruction* inner_context = Add<HAllocateBlockContext>(
outer_context, function, scope->GetScopeInfo(isolate()));
HInstruction* instr = Add<HStoreFrameContext>(inner_context);
set_scope(scope);
environment()->BindContext(inner_context);
if (instr->HasObservableSideEffects()) {
AddSimulate(stmt->EntryId(), REMOVABLE_SIMULATE);
}
}
VisitDeclarations(scope->declarations());
AddSimulate(stmt->DeclsId(), REMOVABLE_SIMULATE);
......@@ -4539,7 +4542,8 @@ void HOptimizedGraphBuilder::VisitBlock(Block* stmt) {
CHECK_BAILOUT(VisitStatements(stmt->statements()));
}
set_scope(outer_scope);
if (scope != NULL && current_block() != NULL) {
if (scope != NULL && current_block() != NULL &&
scope->ContextLocalCount() > 0) {
HValue* inner_context = environment()->context();
HValue* outer_context = Add<HLoadNamedField>(
inner_context, nullptr,
......
......@@ -4288,6 +4288,9 @@ class ScopeInfo : public FixedArray {
// Return the name of the given stack local.
String* StackLocalName(int var);
// Return the name of the given stack local.
int StackLocalIndex(int var);
// Return the name of the given context local.
String* ContextLocalName(int var);
......@@ -4396,33 +4399,38 @@ class ScopeInfo : public FixedArray {
// slot is used per parameter, so in total this part occupies
// ParameterCount() slots in the array. For other scopes than function
// scopes ParameterCount() is 0.
// 2. StackLocalEntries:
// 2. StackLocalFirstSlot:
// Index of a first stack slot for stack local. Stack locals belonging to
// this scope are located on a stack at slots starting from this index.
// 3. StackLocalEntries:
// Contains the names of local variables that are allocated on the stack,
// in increasing order of the stack slot index. One slot is used per stack
// local, so in total this part occupies StackLocalCount() slots in the
// array.
// 3. ContextLocalNameEntries:
// in increasing order of the stack slot index. First local variable has
// a stack slot index defined in StackLocalFirstSlot (point 2 above).
// One slot is used per stack local, so in total this part occupies
// StackLocalCount() slots in the array.
// 4. ContextLocalNameEntries:
// Contains the names of local variables and parameters that are allocated
// in the context. They are stored in increasing order of the context slot
// index starting with Context::MIN_CONTEXT_SLOTS. One slot is used per
// context local, so in total this part occupies ContextLocalCount() slots
// in the array.
// 4. ContextLocalInfoEntries:
// 5. ContextLocalInfoEntries:
// Contains the variable modes and initialization flags corresponding to
// the context locals in ContextLocalNameEntries. One slot is used per
// context local, so in total this part occupies ContextLocalCount()
// slots in the array.
// 5. StrongModeFreeVariableNameEntries:
// 6. StrongModeFreeVariableNameEntries:
// Stores the names of strong mode free variables.
// 6. StrongModeFreeVariablePositionEntries:
// 7. StrongModeFreeVariablePositionEntries:
// Stores the locations (start and end position) of strong mode free
// variables.
// 7. FunctionNameEntryIndex:
// 8. FunctionNameEntryIndex:
// If the scope belongs to a named function expression this part contains
// information about the function variable. It always occupies two array
// slots: a. The name of the function variable.
// b. The context or stack slot index for the variable.
int ParameterEntriesIndex();
int StackLocalFirstSlotIndex();
int StackLocalEntriesIndex();
int ContextLocalNameEntriesIndex();
int ContextLocalInfoEntriesIndex();
......
......@@ -519,6 +519,7 @@ void ParserTraits::CheckPossibleEvalCall(Expression* expression,
if (callee != NULL &&
callee->raw_name() == parser_->ast_value_factory()->eval_string()) {
scope->DeclarationScope()->RecordEvalCall();
scope->RecordEvalCall();
}
}
......@@ -3339,8 +3340,8 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
clear_first =
factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
}
Statement* clear_first_or_next =
factory()->NewIfStatement(compare, clear_first, next, next->position());
Statement* clear_first_or_next = factory()->NewIfStatement(
compare, clear_first, next, RelocInfo::kNoPosition);
inner_block->AddStatement(clear_first_or_next, zone());
}
......@@ -4048,6 +4049,10 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
parenthesized_function_ = false; // The bit was set for this function only.
if (is_lazily_parsed) {
for (Scope* s = scope_->outer_scope();
s != nullptr && (s != s->DeclarationScope()); s = s->outer_scope()) {
s->ForceContextAllocation();
}
SkipLazyFunctionBody(&materialized_literal_count,
&expected_property_count, CHECK_OK);
} else {
......
This diff is collapsed.
......@@ -27,7 +27,6 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
const int strong_mode_free_variable_count =
strong_mode_free_variables.length();
// Make sure we allocate the correct amount.
DCHECK(scope->StackLocalCount() == stack_local_count);
DCHECK(scope->ContextLocalCount() == context_local_count);
bool simple_parameter_list =
......@@ -54,8 +53,8 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
const bool has_function_name = function_name_info != NONE;
const int parameter_count = scope->num_parameters();
const int length = kVariablePartIndex + parameter_count + stack_local_count +
2 * context_local_count +
const int length = kVariablePartIndex + parameter_count +
(1 + stack_local_count) + 2 * context_local_count +
3 * strong_mode_free_variable_count +
(has_function_name ? 2 : 0);
......@@ -89,9 +88,17 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
// Add stack locals' names. We are assuming that the stack locals'
// slots are allocated in increasing order, so we can simply add
// them to the ScopeInfo object.
int first_slot_index;
if (stack_local_count > 0) {
first_slot_index = stack_locals[0]->index();
} else {
first_slot_index = 0;
}
DCHECK(index == scope_info->StackLocalFirstSlotIndex());
scope_info->set(index++, Smi::FromInt(first_slot_index));
DCHECK(index == scope_info->StackLocalEntriesIndex());
for (int i = 0; i < stack_local_count; ++i) {
DCHECK(stack_locals[i]->index() == i);
DCHECK(stack_locals[i]->index() == first_slot_index + i);
scope_info->set(index++, *stack_locals[i]->name());
}
......@@ -145,16 +152,12 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
int var_index = scope->function()->proxy()->var()->index();
scope_info->set(index++, *scope->function()->proxy()->name());
scope_info->set(index++, Smi::FromInt(var_index));
DCHECK(function_name_info != STACK ||
(var_index == scope_info->StackLocalCount() &&
var_index == scope_info->StackSlotCount() - 1));
DCHECK(function_name_info != CONTEXT ||
var_index == scope_info->ContextLength() - 1);
}
DCHECK(index == scope_info->length());
DCHECK(scope->num_parameters() == scope_info->ParameterCount());
DCHECK(scope->num_stack_slots() == scope_info->StackSlotCount());
DCHECK(scope->num_heap_slots() == scope_info->ContextLength() ||
(scope->num_heap_slots() == kVariablePartIndex &&
scope_info->ContextLength() == 0));
......@@ -269,6 +272,13 @@ String* ScopeInfo::StackLocalName(int var) {
}
int ScopeInfo::StackLocalIndex(int var) {
DCHECK(0 <= var && var < StackLocalCount());
int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value();
return first_slot_index + var;
}
String* ScopeInfo::ContextLocalName(int var) {
DCHECK(0 <= var && var < ContextLocalCount());
int info_index = ContextLocalNameEntriesIndex() + var;
......@@ -343,11 +353,12 @@ int ScopeInfo::StrongModeFreeVariableEndPosition(int var) {
int ScopeInfo::StackSlotIndex(String* name) {
DCHECK(name->IsInternalizedString());
if (length() > 0) {
int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value();
int start = StackLocalEntriesIndex();
int end = StackLocalEntriesIndex() + StackLocalCount();
for (int i = start; i < end; ++i) {
if (name == get(i)) {
return i - start;
return i - start + first_slot_index;
}
}
}
......@@ -453,7 +464,7 @@ bool ScopeInfo::CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
if (scope_info->LocalIsSynthetic(first_context_var + i)) continue;
int context_index = Context::MIN_CONTEXT_SLOTS + i;
Handle<Object> value = Handle<Object>(context->get(context_index), isolate);
// Do not reflect variables under TDZ in scope object.
// Reflect variables under TDZ as undefined in scope object.
if (value->IsTheHole()) continue;
RETURN_ON_EXCEPTION_VALUE(
isolate, Runtime::DefineObjectProperty(
......@@ -472,11 +483,16 @@ int ScopeInfo::ParameterEntriesIndex() {
}
int ScopeInfo::StackLocalEntriesIndex() {
int ScopeInfo::StackLocalFirstSlotIndex() {
return ParameterEntriesIndex() + ParameterCount();
}
int ScopeInfo::StackLocalEntriesIndex() {
return StackLocalFirstSlotIndex() + 1;
}
int ScopeInfo::ContextLocalNameEntriesIndex() {
return StackLocalEntriesIndex() + StackLocalCount();
}
......
......@@ -371,6 +371,7 @@ Scope* Scope::FinalizeBlockScope() {
if (uses_arguments()) outer_scope_->RecordArgumentsUsage();
if (uses_super_property()) outer_scope_->RecordSuperPropertyUsage();
if (uses_this()) outer_scope_->RecordThisUsage();
if (scope_calls_eval_) outer_scope_->RecordEvalCall();
return NULL;
}
......@@ -381,13 +382,13 @@ Variable* Scope::LookupLocal(const AstRawString* name) {
if (result != NULL || scope_info_.is_null()) {
return result;
}
Handle<String> name_handle = name->string();
// The Scope is backed up by ScopeInfo. This means it cannot operate in a
// heap-independent mode, and all strings must be internalized immediately. So
// it's ok to get the Handle<String> here.
Handle<String> name_handle = name->string();
// If we have a serialized scope info, we might find the variable there.
// There should be no local slot with the given name.
DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0);
DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0 || is_block_scope());
// Check context slot lookup.
VariableMode mode;
......@@ -706,6 +707,7 @@ bool Scope::HasLazyCompilableOuterContext() const {
bool found_non_trivial_declarations = false;
for (const Scope* scope = outer; scope != NULL; scope = scope->outer_scope_) {
if (scope->is_with_scope() && !found_non_trivial_declarations) return false;
if (scope->is_block_scope() && !scope->decls_.is_empty()) return false;
if (scope->is_declaration_scope() && scope->num_heap_slots() > 0) {
found_non_trivial_declarations = true;
}
......@@ -1288,7 +1290,7 @@ bool Scope::MustAllocateInContext(Variable* var) {
if (has_forced_context_allocation()) return true;
if (var->mode() == TEMPORARY) return false;
if (var->mode() == INTERNAL) return true;
if (is_catch_scope() || is_block_scope() || is_module_scope()) return true;
if (is_catch_scope() || is_module_scope()) return true;
if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true;
return var->has_forced_context_allocation() ||
scope_calls_eval_ ||
......@@ -1309,7 +1311,11 @@ bool Scope::HasArgumentsParameter(Isolate* isolate) {
void Scope::AllocateStackSlot(Variable* var) {
var->AllocateTo(Variable::LOCAL, num_stack_slots_++);
if (is_block_scope()) {
DeclarationScope()->AllocateStackSlot(var);
} else {
var->AllocateTo(Variable::LOCAL, num_stack_slots_++);
}
}
......@@ -1434,6 +1440,9 @@ void Scope::AllocateNonParameterLocals(Isolate* isolate) {
void Scope::AllocateVariablesRecursively(Isolate* isolate) {
if (!already_resolved()) {
num_stack_slots_ = 0;
}
// Allocate variables for inner scopes.
for (int i = 0; i < inner_scopes_.length(); i++) {
inner_scopes_[i]->AllocateVariablesRecursively(isolate);
......@@ -1443,7 +1452,6 @@ void Scope::AllocateVariablesRecursively(Isolate* isolate) {
// variables in inner scopes which might not had been resolved yet.
if (already_resolved()) return;
// The number of slots required for variables.
num_stack_slots_ = 0;
num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
// Allocate variables for this scope.
......
......@@ -52,6 +52,7 @@ function listener(event, exec_state, event_data, data) {
}
} catch (e) {
exception = e;
print(e + e.stack);
}
}
......
......@@ -1054,10 +1054,9 @@ BeginTest("Classes and methods 1");
listener_delegate = function(exec_state) {
"use strict"
CheckScopeChain([debug.ScopeType.Local,
debug.ScopeType.Block,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({C1: class { m() { debugger; }} }, 1, exec_state);
CheckScopeContent({}, 1, exec_state);
};
(function() {
......
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --min-preparse-length=0
'use strict';
let xxx = 1;
let f = undefined;
{
let inner_x = xxx;
f = function() { return inner_x; };
}
assertSame(1, f());
xxx = 42;
{
f = function() { return inner_x1; };
let inner_x1 = xxx;
}
assertSame(42, f());
xxx = 31;
{
let inner_x1 = xxx;
try {
throw new Error();
} catch (e) {
f = function() { return inner_x1; };
}
}
assertSame(31, f());
......@@ -498,7 +498,47 @@ listener_delegate = function(exec_state) {
debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({}, 0, exec_state);
CheckScopeContent({x:undefined}, 0, exec_state);
};
uninitialized_1();
EndTest();
// Block scopes shadowing
BeginTest("Block scopes shadowing 1");
function shadowing_1() {
let i = 0;
{
let i = 5;
debugger;
assertEquals(27, i);
}
assertEquals(0, i);
debugger;
assertEquals(27, i);
}
listener_delegate = function (exec_state) {
exec_state.frame(0).evaluate("i = 27");
}
shadowing_1();
EndTest();
// Block scopes shadowing
BeginTest("Block scopes shadowing 2");
function shadowing_2() {
let i = 0;
{
let j = 5;
debugger;
assertEquals(27, j);
}
assertEquals(0, i);
}
listener_delegate = function (exec_state) {
exec_state.frame(0).evaluate("j = 27");
}
shadowing_2();
EndTest();
......@@ -107,13 +107,10 @@ var f2 = (function() {
var mirror = Debug.MakeMirror(f2);
assertEquals(6, mirror.scopeCount());
// Implementation artifact: l4 isn't used in closure, but still it is saved.
CheckScope(mirror.scope(0), { l4: 11 }, ScopeType.Block);
assertEquals(5, mirror.scopeCount());
CheckScope(mirror.scope(1), { l3: 9 }, ScopeType.Block);
CheckScope(mirror.scope(2), { l1: 6, l2: 7 }, ScopeType.Block);
CheckScope(mirror.scope(3), { v1:3, l0: 0, v3: 5, v6: 11 }, ScopeType.Closure);
CheckScope(mirror.scope(4), { top_level_let: 255 }, ScopeType.Script);
CheckScope(mirror.scope(5), {}, ScopeType.Global);
CheckScope(mirror.scope(0), { l3: 9 }, ScopeType.Block);
CheckScope(mirror.scope(1), { l2: 7 }, ScopeType.Block);
CheckScope(mirror.scope(2), { v1:3, l0: 0, v3: 5, v6: 11 }, ScopeType.Closure);
CheckScope(mirror.scope(3), { top_level_let: 255 }, ScopeType.Script);
CheckScope(mirror.scope(4), {}, ScopeType.Global);
......@@ -9,7 +9,7 @@ var exception = null;
var break_count = 0;
var expected_values =
[ReferenceError, ReferenceError, 0, 0, 0, 0, 0, 1, ReferenceError, ReferenceError];
[ReferenceError, undefined, 0, 0, 0, 0, 1, ReferenceError, ReferenceError];
function listener(event, exec_state, event_data, data) {
try {
......@@ -39,6 +39,7 @@ function listener(event, exec_state, event_data, data) {
assertTrue(v instanceof ReferenceError);
} else {
assertSame(expected_values[break_count], v);
}
++break_count;
......@@ -62,14 +63,14 @@ var sum = 0;
debugger; // Break 0.
for (let i=0; // Break 1.
i < 1; // Break 2. // Break 3. // Break 6. // Break 7.
i < 1; // Break 2. // Break 5. // Break 6.
i++) {
let key = i; // Break 4.
sum += key; // Break 5.
let key = i; // Break 3.
sum += key; // Break 4.
}
}()); // Break 8.
}()); // Break 7.
assertNull(exception); // Break 9.
assertNull(exception); // Break 8.
assertEquals(expected_breaks, break_count);
Debug.setListener(null);
......@@ -114,6 +114,14 @@
'debug-listbreakpoints': [PASS, NO_VARIANTS], # arm64 nosnap with turbofan
'debug-enable-disable-breakpoints': [PASS, NO_VARIANTS], #arm64 nosnap with turbofan.
# Issue 4035: unexpected frame->context() in debugger
'regress/regress-crbug-107996': [PASS, NO_VARIANTS],
'regress/regress-crbug-171715': [PASS, NO_VARIANTS],
'regress/regress-crbug-222893': [PASS, NO_VARIANTS],
'regress/regress-325676': [PASS, NO_VARIANTS],
'debug-evaluate-closure': [PASS, NO_VARIANTS],
'debug-evaluate-with': [PASS, NO_VARIANTS],
# TODO(mstarzinger): Optimizing top-level code flushed out some correctness
# issues on ARM and ARM64.
'es6/math-log2-log10': [PASS, NO_VARIANTS], # on ARM and ARM64.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment