vendor/v8/src/arm/lithium-arm.cc in mustang-0.0.1 vs vendor/v8/src/arm/lithium-arm.cc in mustang-0.1.0

- old
+ new

@@ -23,10 +23,12 @@ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include "v8.h" + #include "lithium-allocator-inl.h" #include "arm/lithium-arm.h" #include "arm/lithium-codegen-arm.h" namespace v8 { @@ -380,12 +382,13 @@ stream->Add("] <- "); value()->PrintTo(stream); } -LChunk::LChunk(HGraph* graph) +LChunk::LChunk(CompilationInfo* info, HGraph* graph) : spill_slot_count_(0), + info_(info), graph_(graph), instructions_(32), pointer_maps_(8), inlined_closures_(1) { } @@ -472,19 +475,19 @@ int LChunk::GetParameterStackSlot(int index) const { // The receiver is at index 0, the first parameter at index 1, so we // shift all parameter indexes down by the number of parameters, and // make sure they end up negative so they are distinguishable from // spill slots. - int result = index - graph()->info()->scope()->num_parameters() - 1; + int result = index - info()->scope()->num_parameters() - 1; ASSERT(result < 0); return result; } // A parameter relative to ebp in the arguments stub. int LChunk::ParameterAt(int index) { ASSERT(-1 <= index); // -1 is the receiver. - return (1 + graph()->info()->scope()->num_parameters() - index) * + return (1 + info()->scope()->num_parameters() - index) * kPointerSize; } LGap* LChunk::GetGapAt(int index) const { @@ -519,11 +522,11 @@ } LChunk* LChunkBuilder::Build() { ASSERT(is_unused()); - chunk_ = new LChunk(graph()); + chunk_ = new LChunk(info(), graph()); HPhase phase("Building chunk", chunk_); status_ = BUILDING; const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); for (int i = 0; i < blocks->length(); i++) { HBasicBlock* next = NULL; @@ -536,12 +539,12 @@ } void LChunkBuilder::Abort(const char* format, ...) { if (FLAG_trace_bailout) { - SmartPointer<char> debug_name = graph()->debug_name()->ToCString(); - PrintF("Aborting LChunk building in @\"%s\": ", *debug_name); + SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); + PrintF("Aborting LChunk building in @\"%s\": ", *name); va_list arguments; va_start(arguments, format); OS::VPrint(format, arguments); va_end(arguments); PrintF("\n"); @@ -871,10 +874,11 @@ LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, HArithmeticBinaryOperation* instr) { ASSERT(instr->representation().IsDouble()); ASSERT(instr->left()->representation().IsDouble()); ASSERT(instr->right()->representation().IsDouble()); + ASSERT(op != Token::MOD); LOperand* left = UseRegisterAtStart(instr->left()); LOperand* right = UseRegisterAtStart(instr->right()); LArithmeticD* result = new LArithmeticD(op, left, right); return DefineSameAsFirst(result); } @@ -1152,12 +1156,11 @@ LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( HInstanceOfKnownGlobal* instr) { LInstanceOfKnownGlobal* result = new LInstanceOfKnownGlobal(UseFixed(instr->value(), r0), FixedTemp(r4)); - MarkAsSaveDoubles(result); - return AssignEnvironment(AssignPointerMap(DefineFixed(result, r0))); + return MarkAsCall(DefineFixed(result, r0), instr); } LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { LOperand* function = UseFixed(instr->function(), r1); @@ -1209,37 +1212,33 @@ } LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { BuiltinFunctionId op = instr->op(); - LOperand* input = UseRegisterAtStart(instr->value()); - LOperand* temp = (op == kMathFloor) ? TempRegister() : NULL; - LUnaryMathOperation* result = new LUnaryMathOperation(input, temp); - switch (op) { - case kMathAbs: - return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); - case kMathFloor: - return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); - case kMathSqrt: - return DefineSameAsFirst(result); - case kMathRound: - return AssignEnvironment(DefineAsRegister(result)); - case kMathPowHalf: - Abort("MathPowHalf LUnaryMathOperation not implemented"); - return NULL; - case kMathLog: - Abort("MathLog LUnaryMathOperation not implemented"); - return NULL; - case kMathCos: - Abort("MathCos LUnaryMathOperation not implemented"); - return NULL; - case kMathSin: - Abort("MathSin LUnaryMathOperation not implemented"); - return NULL; - default: - UNREACHABLE(); - return NULL; + if (op == kMathLog || op == kMathSin || op == kMathCos) { + LOperand* input = UseFixedDouble(instr->value(), d2); + LUnaryMathOperation* result = new LUnaryMathOperation(input, NULL); + return MarkAsCall(DefineFixedDouble(result, d2), instr); + } else { + LOperand* input = UseRegisterAtStart(instr->value()); + LOperand* temp = (op == kMathFloor) ? TempRegister() : NULL; + LUnaryMathOperation* result = new LUnaryMathOperation(input, temp); + switch (op) { + case kMathAbs: + return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); + case kMathFloor: + return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); + case kMathSqrt: + return DefineSameAsFirst(result); + case kMathRound: + return AssignEnvironment(DefineAsRegister(result)); + case kMathPowHalf: + return DefineSameAsFirst(result); + default: + UNREACHABLE(); + return NULL; + } } } LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { @@ -1344,22 +1343,29 @@ } LInstruction* LChunkBuilder::DoMod(HMod* instr) { if (instr->representation().IsInteger32()) { - // TODO(1042) The fixed register allocation - // is needed because we call GenericBinaryOpStub from - // the generated code, which requires registers r0 - // and r1 to be used. We should remove that - // when we provide a native implementation. ASSERT(instr->left()->representation().IsInteger32()); ASSERT(instr->right()->representation().IsInteger32()); - LOperand* value = UseFixed(instr->left(), r0); - LOperand* divisor = UseFixed(instr->right(), r1); - LInstruction* result = DefineFixed(new LModI(value, divisor), r0); - result = AssignEnvironment(AssignPointerMap(result)); - return result; + + LModI* mod; + if (instr->HasPowerOf2Divisor()) { + ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); + LOperand* value = UseRegisterAtStart(instr->left()); + mod = new LModI(value, UseOrConstant(instr->right())); + } else { + LOperand* dividend = UseRegister(instr->left()); + LOperand* divisor = UseRegisterAtStart(instr->right()); + mod = new LModI(dividend, + divisor, + TempRegister(), + FixedTemp(d1), + FixedTemp(d2)); + } + + return AssignEnvironment(DefineSameAsFirst(mod)); } else if (instr->representation().IsTagged()) { return DoArithmeticT(Token::MOD, instr); } else { ASSERT(instr->representation().IsDouble()); // We call a C function for double modulo. It can't trigger a GC. @@ -1520,11 +1526,11 @@ LInstruction* LChunkBuilder::DoGetCachedArrayIndex( HGetCachedArrayIndex* instr) { ASSERT(instr->value()->representation().IsTagged()); - LOperand* value = UseRegister(instr->value()); + LOperand* value = UseRegisterAtStart(instr->value()); return DefineAsRegister(new LGetCachedArrayIndex(value)); } @@ -1548,13 +1554,14 @@ LOperand* array = UseRegisterAtStart(instr->value()); return DefineAsRegister(new LJSArrayLength(array)); } -LInstruction* LChunkBuilder::DoPixelArrayLength(HPixelArrayLength* instr) { +LInstruction* LChunkBuilder::DoExternalArrayLength( + HExternalArrayLength* instr) { LOperand* array = UseRegisterAtStart(instr->value()); - return DefineAsRegister(new LPixelArrayLength(array)); + return DefineAsRegister(new LExternalArrayLength(array)); } LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { LOperand* array = UseRegisterAtStart(instr->value()); @@ -1599,16 +1606,19 @@ } else { ASSERT(to.IsInteger32()); LOperand* value = UseRegister(instr->value()); bool needs_check = !instr->value()->type().IsSmi(); LInstruction* res = NULL; - if (needs_check) { - res = DefineSameAsFirst(new LTaggedToI(value, FixedTemp(d1))); - } else { + if (!needs_check) { res = DefineSameAsFirst(new LSmiUntag(value, needs_check)); - } - if (needs_check) { + } else { + LOperand* temp1 = TempRegister(); + LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister() + : NULL; + LOperand* temp3 = instr->CanTruncateToInt32() ? FixedTemp(d3) + : NULL; + res = DefineSameAsFirst(new LTaggedToI(value, temp1, temp2, temp3)); res = AssignEnvironment(res); } return res; } } else if (from.IsDouble()) { @@ -1624,11 +1634,14 @@ Define(result, result_temp); return AssignPointerMap(result); } else { ASSERT(to.IsInteger32()); LOperand* value = UseRegister(instr->value()); - LDoubleToI* res = new LDoubleToI(value, TempRegister()); + LDoubleToI* res = + new LDoubleToI(value, + TempRegister(), + instr->CanTruncateToInt32() ? TempRegister() : NULL); return AssignEnvironment(DefineAsRegister(res)); } } else if (from.IsInteger32()) { if (to.IsTagged()) { HValue* val = instr->value(); @@ -1650,11 +1663,11 @@ } LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { LOperand* value = UseRegisterAtStart(instr->value()); - return AssignEnvironment(new LCheckSmi(value, eq)); + return AssignEnvironment(new LCheckNonSmi(value)); } LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { LOperand* value = UseRegisterAtStart(instr->value()); @@ -1671,11 +1684,11 @@ } LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { LOperand* value = UseRegisterAtStart(instr->value()); - return AssignEnvironment(new LCheckSmi(value, ne)); + return AssignEnvironment(new LCheckSmi(value)); } LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { LOperand* value = UseRegisterAtStart(instr->value()); @@ -1708,18 +1721,25 @@ return NULL; } } -LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { - LLoadGlobal* result = new LLoadGlobal(); +LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { + LLoadGlobalCell* result = new LLoadGlobalCell; return instr->check_hole_value() ? AssignEnvironment(DefineAsRegister(result)) : DefineAsRegister(result); } +LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { + LOperand* global_object = UseFixed(instr->global_object(), r0); + LLoadGlobalGeneric* result = new LLoadGlobalGeneric(global_object); + return MarkAsCall(DefineFixed(result, r0), instr); +} + + LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { if (instr->check_hole_value()) { LOperand* temp = TempRegister(); LOperand* value = UseRegister(instr->value()); return AssignEnvironment(new LStoreGlobal(value, temp)); @@ -1754,10 +1774,25 @@ return DefineAsRegister( new LLoadNamedField(UseRegisterAtStart(instr->object()))); } +LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic( + HLoadNamedFieldPolymorphic* instr) { + ASSERT(instr->representation().IsTagged()); + if (instr->need_generic()) { + LOperand* obj = UseFixed(instr->object(), r0); + LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj); + return MarkAsCall(DefineFixed(result, r0), instr); + } else { + LOperand* obj = UseRegisterAtStart(instr->object()); + LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj); + return AssignEnvironment(DefineAsRegister(result)); + } +} + + LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { LOperand* object = UseFixed(instr->object(), r0); LInstruction* result = DefineFixed(new LLoadNamedGeneric(object), r0); return MarkAsCall(result, instr); } @@ -1774,14 +1809,14 @@ LOperand* input = UseRegisterAtStart(instr->value()); return DefineAsRegister(new LLoadElements(input)); } -LInstruction* LChunkBuilder::DoLoadPixelArrayExternalPointer( - HLoadPixelArrayExternalPointer* instr) { +LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( + HLoadExternalArrayPointer* instr) { LOperand* input = UseRegisterAtStart(instr->value()); - return DefineAsRegister(new LLoadPixelArrayExternalPointer(input)); + return DefineAsRegister(new LLoadExternalArrayPointer(input)); } LInstruction* LChunkBuilder::DoLoadKeyedFastElement( HLoadKeyedFastElement* instr) { @@ -1792,19 +1827,26 @@ LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); return AssignEnvironment(DefineSameAsFirst(result)); } -LInstruction* LChunkBuilder::DoLoadPixelArrayElement( - HLoadPixelArrayElement* instr) { +LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( + HLoadKeyedSpecializedArrayElement* instr) { + // TODO(danno): Add support for other external array types. + if (instr->array_type() != kExternalPixelArray) { + Abort("unsupported load for external array type."); + return NULL; + } + ASSERT(instr->representation().IsInteger32()); ASSERT(instr->key()->representation().IsInteger32()); LOperand* external_pointer = UseRegisterAtStart(instr->external_pointer()); LOperand* key = UseRegisterAtStart(instr->key()); - LLoadPixelArrayElement* result = - new LLoadPixelArrayElement(external_pointer, key); + LLoadKeyedSpecializedArrayElement* result = + new LLoadKeyedSpecializedArrayElement(external_pointer, + key); return DefineAsRegister(result); } LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { @@ -1834,14 +1876,29 @@ return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); } -LInstruction* LChunkBuilder::DoStorePixelArrayElement( - HStorePixelArrayElement* instr) { - Abort("DoStorePixelArrayElement not implemented"); - return NULL; +LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( + HStoreKeyedSpecializedArrayElement* instr) { + // TODO(danno): Add support for other external array types. + if (instr->array_type() != kExternalPixelArray) { + Abort("unsupported store for external array type."); + return NULL; + } + + ASSERT(instr->value()->representation().IsInteger32()); + ASSERT(instr->external_pointer()->representation().IsExternal()); + ASSERT(instr->key()->representation().IsInteger32()); + + LOperand* external_pointer = UseRegister(instr->external_pointer()); + LOperand* value = UseTempRegister(instr->value()); // changed by clamp. + LOperand* key = UseRegister(instr->key()); + + return new LStoreKeyedSpecializedArrayElement(external_pointer, + key, + value); } LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { LOperand* obj = UseFixed(instr->object(), r2); @@ -1886,10 +1943,17 @@ LStringCharCodeAt* result = new LStringCharCodeAt(string, index); return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); } +LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { + LOperand* char_code = UseRegister(instr->value()); + LStringCharFromCode* result = new LStringCharFromCode(char_code); + return AssignPointerMap(DefineAsRegister(result)); +} + + LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { LOperand* string = UseRegisterAtStart(instr->value()); return DefineAsRegister(new LStringLength(string)); } @@ -1960,9 +2024,16 @@ LOperand* arguments = UseRegister(instr->arguments()); LOperand* length = UseTempRegister(instr->length()); LOperand* index = UseRegister(instr->index()); LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index); return AssignEnvironment(DefineAsRegister(result)); +} + + +LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) { + LOperand* object = UseFixed(instr->value(), r0); + LToFastProperties* result = new LToFastProperties(object); + return MarkAsCall(DefineFixed(result, r0), instr); } LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { LTypeof* result = new LTypeof(UseFixed(instr->value(), r0));