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

Unified Diff: src/mips/full-codegen-mips.cc

Issue 8112008: MIPS: port all relevant commits since the new-gc was landed. (Closed)
Patch Set: rebased on r9598. Created 9 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/mips/code-stubs-mips.cc ('k') | src/mips/ic-mips.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mips/full-codegen-mips.cc
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index dca171359ff0897152e7dc3d9fb80da622538895..b3f0540872dbd0c32099d53f8796d6d535b46cc7 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -278,7 +278,7 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
// constant.
if (scope()->is_function_scope() && scope()->function() != NULL) {
int ignored = 0;
- EmitDeclaration(scope()->function(), Variable::CONST, NULL, &ignored);
+ EmitDeclaration(scope()->function(), CONST, NULL, &ignored);
}
VisitDeclarations(scope()->declarations());
}
@@ -721,7 +721,7 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state,
void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
- Variable::Mode mode,
+ VariableMode mode,
FunctionLiteral* function,
int* global_count) {
// If it was not possible to allocate the variable at compile time, we
@@ -739,7 +739,7 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
Comment cmnt(masm_, "[ Declaration");
VisitForAccumulatorValue(function);
__ sw(result_register(), StackOperand(variable));
- } else if (mode == Variable::CONST || mode == Variable::LET) {
+ } else if (mode == CONST || mode == LET) {
Comment cmnt(masm_, "[ Declaration");
__ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
__ sw(t0, StackOperand(variable));
@@ -775,7 +775,7 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
EMIT_REMEMBERED_SET,
OMIT_SMI_CHECK);
PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
- } else if (mode == Variable::CONST || mode == Variable::LET) {
+ } else if (mode == CONST || mode == LET) {
Comment cmnt(masm_, "[ Declaration");
__ LoadRoot(at, Heap::kTheHoleValueRootIndex);
__ sw(at, ContextOperand(cp, variable->index()));
@@ -788,10 +788,8 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
Comment cmnt(masm_, "[ Declaration");
__ li(a2, Operand(variable->name()));
// Declaration nodes are always introduced in one of three modes.
- ASSERT(mode == Variable::VAR ||
- mode == Variable::CONST ||
- mode == Variable::LET);
- PropertyAttributes attr = (mode == Variable::CONST) ? READ_ONLY : NONE;
+ ASSERT(mode == VAR || mode == CONST || mode == LET);
+ PropertyAttributes attr = (mode == CONST) ? READ_ONLY : NONE;
__ li(a1, Operand(Smi::FromInt(attr)));
// Push initial value, if any.
// Note: For variables we must not push an initial value (such as
@@ -801,7 +799,7 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
__ Push(cp, a2, a1);
// Push initial value for function declaration.
VisitForStackValue(function);
- } else if (mode == Variable::CONST || mode == Variable::LET) {
+ } else if (mode == CONST || mode == LET) {
__ LoadRoot(a0, Heap::kTheHoleValueRootIndex);
__ Push(cp, a2, a1, a0);
} else {
@@ -1223,17 +1221,25 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(Variable* var,
// introducing variables. In those cases, we do not want to
// perform a runtime call for all variables in the scope
// containing the eval.
- if (var->mode() == Variable::DYNAMIC_GLOBAL) {
+ if (var->mode() == DYNAMIC_GLOBAL) {
EmitLoadGlobalCheckExtensions(var, typeof_state, slow);
__ Branch(done);
- } else if (var->mode() == Variable::DYNAMIC_LOCAL) {
+ } else if (var->mode() == DYNAMIC_LOCAL) {
Variable* local = var->local_if_not_shadowed();
__ lw(v0, ContextSlotOperandCheckExtensions(local, slow));
- if (local->mode() == Variable::CONST) {
+ if (local->mode() == CONST ||
+ local->mode() == LET) {
__ LoadRoot(at, Heap::kTheHoleValueRootIndex);
__ subu(at, v0, at); // Sub as compare: at == 0 on eq.
- __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
- __ movz(v0, a0, at); // Conditional move: return Undefined if TheHole.
+ if (local->mode() == CONST) {
+ __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
+ __ movz(v0, a0, at); // Conditional move: return Undefined if TheHole.
+ } else { // LET
+ __ Branch(done, ne, at, Operand(zero_reg));
+ __ li(a0, Operand(var->name()));
+ __ push(a0);
+ __ CallRuntime(Runtime::kThrowReferenceError, 1);
+ }
}
__ Branch(done);
}
@@ -1266,14 +1272,14 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
Comment cmnt(masm_, var->IsContextSlot()
? "Context variable"
: "Stack variable");
- if (var->mode() != Variable::LET && var->mode() != Variable::CONST) {
+ if (var->mode() != LET && var->mode() != CONST) {
context()->Plug(var);
} else {
// Let and const need a read barrier.
GetVar(v0, var);
__ LoadRoot(at, Heap::kTheHoleValueRootIndex);
__ subu(at, v0, at); // Sub as compare: at == 0 on eq.
- if (var->mode() == Variable::LET) {
+ if (var->mode() == LET) {
Label done;
__ Branch(&done, ne, at, Operand(zero_reg));
__ li(a0, Operand(var->name()));
@@ -1513,15 +1519,23 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
VisitForAccumulatorValue(subexpr);
// Store the subexpression value in the array's elements.
- __ lw(a1, MemOperand(sp)); // Copy of array literal.
- __ lw(a1, FieldMemOperand(a1, JSObject::kElementsOffset));
+ __ lw(t6, MemOperand(sp)); // Copy of array literal.
+ __ lw(a1, FieldMemOperand(t6, JSObject::kElementsOffset));
int offset = FixedArray::kHeaderSize + (i * kPointerSize);
__ sw(result_register(), FieldMemOperand(a1, offset));
+ Label no_map_change;
+ __ JumpIfSmi(result_register(), &no_map_change);
// Update the write barrier for the array store with v0 as the scratch
// register.
__ RecordWriteField(
- a1, offset, result_register(), a2, kRAHasBeenSaved, kDontSaveFPRegs);
+ a1, offset, result_register(), a2, kRAHasBeenSaved, kDontSaveFPRegs,
+ EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+ __ lw(a3, FieldMemOperand(a1, HeapObject::kMapOffset));
+ __ CheckFastSmiOnlyElements(a3, a2, &no_map_change);
+ __ push(t6); // Copy of array literal.
+ __ CallRuntime(Runtime::kNonSmiElementStored, 1);
+ __ bind(&no_map_change);
PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
}
@@ -1873,7 +1887,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
__ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
}
- } else if (var->mode() == Variable::LET && op != Token::INIT_LET) {
+ } else if (var->mode() == LET && op != Token::INIT_LET) {
// Non-initializing assignment to let variable needs a write barrier.
if (var->IsLookupSlot()) {
__ push(v0); // Value.
@@ -1903,7 +1917,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
}
}
- } else if (var->mode() != Variable::CONST) {
+ } else if (var->mode() != CONST) {
// Assignment to var or initializing assignment to let.
if (var->IsStackAllocated() || var->IsContextSlot()) {
MemOperand location = VarOperand(var, a1);
@@ -2194,7 +2208,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// context lookup in the runtime system.
Label done;
Variable* var = proxy->var();
- if (!var->IsUnallocated() && var->mode() == Variable::DYNAMIC_GLOBAL) {
+ if (!var->IsUnallocated() && var->mode() == DYNAMIC_GLOBAL) {
Label slow;
EmitLoadGlobalCheckExtensions(var, NOT_INSIDE_TYPEOF, &slow);
// Push the function and resolve eval.
@@ -2695,18 +2709,23 @@ void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) {
// Check that the object is a JS object but take special care of JS
// functions to make sure they have 'Function' as their class.
+ // Assume that there are only two callable types, and one of them is at
+ // either end of the type range for JS object types. Saves extra comparisons.
+ STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
__ GetObjectType(v0, v0, a1); // Map is now in v0.
__ Branch(&null, lt, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
- // As long as LAST_CALLABLE_SPEC_OBJECT_TYPE is the last instance type, and
- // FIRST_CALLABLE_SPEC_OBJECT_TYPE comes right after
- // LAST_NONCALLABLE_SPEC_OBJECT_TYPE, we can avoid checking for the latter.
- STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
- STATIC_ASSERT(FIRST_CALLABLE_SPEC_OBJECT_TYPE ==
- LAST_NONCALLABLE_SPEC_OBJECT_TYPE + 1);
- __ Branch(&function, ge, a1, Operand(FIRST_CALLABLE_SPEC_OBJECT_TYPE));
+ STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
+ FIRST_SPEC_OBJECT_TYPE + 1);
+ __ Branch(&function, eq, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
+
+ STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
+ LAST_SPEC_OBJECT_TYPE - 1);
+ __ Branch(&function, eq, a1, Operand(LAST_SPEC_OBJECT_TYPE));
+ // Assume that there is no larger type.
+ STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE - 1);
- // Check if the constructor in the map is a function.
+ // Check if the constructor in the map is a JS function.
__ lw(v0, FieldMemOperand(v0, Map::kConstructorOffset));
__ GetObjectType(v0, a1, a1);
__ Branch(&non_function_constructor, ne, a1, Operand(JS_FUNCTION_TYPE));
@@ -3193,10 +3212,16 @@ void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) {
// pauses in the middle of scanning a single object. Therefore the
// incremental marker is not disturbed, so we don't need to call the
// RecordWrite stub that notifies the incremental marker.
- __ RememberedSetHelper(
- index1, scratch2, kDontSaveFPRegs, MacroAssembler::kFallThroughAtEnd);
- __ RememberedSetHelper(
- index2, scratch2, kDontSaveFPRegs, MacroAssembler::kFallThroughAtEnd);
+ __ RememberedSetHelper(elements,
+ index1,
+ scratch2,
+ kDontSaveFPRegs,
+ MacroAssembler::kFallThroughAtEnd);
+ __ RememberedSetHelper(elements,
+ index2,
+ scratch2,
+ kDontSaveFPRegs,
+ MacroAssembler::kFallThroughAtEnd);
__ bind(&no_remembered_set);
// We are done. Drop elements from the stack, and return undefined.
@@ -4003,10 +4028,11 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
Split(ne, a1, Operand(zero_reg), if_true, if_false, fall_through);
} else if (check->Equals(isolate()->heap()->function_symbol())) {
__ JumpIfSmi(v0, if_false);
- __ GetObjectType(v0, a1, v0); // Leave map in a1.
- Split(ge, v0, Operand(FIRST_CALLABLE_SPEC_OBJECT_TYPE),
- if_true, if_false, fall_through);
-
+ STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
+ __ GetObjectType(v0, v0, a1);
+ __ Branch(if_true, eq, a1, Operand(JS_FUNCTION_TYPE));
+ Split(eq, a1, Operand(JS_FUNCTION_PROXY_TYPE),
+ if_true, if_false, fall_through);
} else if (check->Equals(isolate()->heap()->object_symbol())) {
__ JumpIfSmi(v0, if_false);
if (!FLAG_harmony_typeof) {
« no previous file with comments | « src/mips/code-stubs-mips.cc ('k') | src/mips/ic-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698