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));