OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 | 395 |
396 | 396 |
397 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { | 397 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { |
398 ASSERT(instr->IsMarkedAsCall()); | 398 ASSERT(instr->IsMarkedAsCall()); |
399 ASSERT(ToRegister(instr->constructor()).is(x1)); | 399 ASSERT(ToRegister(instr->constructor()).is(x1)); |
400 | 400 |
401 __ Mov(x0, Operand(instr->arity())); | 401 __ Mov(x0, Operand(instr->arity())); |
402 __ Mov(x2, Operand(instr->hydrogen()->property_cell())); | 402 __ Mov(x2, Operand(instr->hydrogen()->property_cell())); |
403 | 403 |
404 ElementsKind kind = instr->hydrogen()->elements_kind(); | 404 ElementsKind kind = instr->hydrogen()->elements_kind(); |
405 bool disable_allocation_sites = | 405 AllocationSiteOverrideMode override_mode = |
406 (AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE); | 406 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) |
| 407 ? DISABLE_ALLOCATION_SITES |
| 408 : DONT_OVERRIDE; |
| 409 ContextCheckMode context_mode = CONTEXT_CHECK_NOT_REQUIRED; |
407 | 410 |
408 if (instr->arity() == 0) { | 411 if (instr->arity() == 0) { |
409 ArrayNoArgumentConstructorStub stub(kind, disable_allocation_sites); | 412 ArrayNoArgumentConstructorStub stub(kind, context_mode, override_mode); |
410 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 413 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
411 } else if (instr->arity() == 1) { | 414 } else if (instr->arity() == 1) { |
412 Label done; | 415 Label done; |
413 if (IsFastPackedElementsKind(kind)) { | 416 if (IsFastPackedElementsKind(kind)) { |
414 Label packed_case; | 417 Label packed_case; |
415 | 418 |
416 // We might need to create a holey array; look at the first argument. | 419 // We might need to create a holey array; look at the first argument. |
417 __ Peek(x10, 0); | 420 __ Peek(x10, 0); |
418 __ Cbz(x10, &packed_case); | 421 __ Cbz(x10, &packed_case); |
419 | 422 |
420 ElementsKind holey_kind = GetHoleyElementsKind(kind); | 423 ElementsKind holey_kind = GetHoleyElementsKind(kind); |
421 ArraySingleArgumentConstructorStub stub(holey_kind, | 424 ArraySingleArgumentConstructorStub stub(holey_kind, context_mode, |
422 disable_allocation_sites); | 425 override_mode); |
423 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 426 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
424 __ B(&done); | 427 __ B(&done); |
425 __ Bind(&packed_case); | 428 __ Bind(&packed_case); |
426 } | 429 } |
427 | 430 |
428 ArraySingleArgumentConstructorStub stub(kind, disable_allocation_sites); | 431 ArraySingleArgumentConstructorStub stub(kind, context_mode, override_mode); |
429 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 432 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
430 __ Bind(&done); | 433 __ Bind(&done); |
431 } else { | 434 } else { |
432 ArrayNArgumentsConstructorStub stub(kind, disable_allocation_sites); | 435 ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode); |
433 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 436 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
434 } | 437 } |
435 | 438 |
436 ASSERT(ToRegister(instr->result()).is(x0)); | 439 ASSERT(ToRegister(instr->result()).is(x0)); |
437 } | 440 } |
438 | 441 |
439 | 442 |
440 void LCodeGen::CallRuntime(const Runtime::Function* function, | 443 void LCodeGen::CallRuntime(const Runtime::Function* function, |
441 int num_arguments, | 444 int num_arguments, |
442 LInstruction* instr) { | 445 LInstruction* instr) { |
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1168 branch.Emit(chunk_->GetAssemblyLabel(left_block)); | 1171 branch.Emit(chunk_->GetAssemblyLabel(left_block)); |
1169 } else { | 1172 } else { |
1170 branch.Emit(chunk_->GetAssemblyLabel(left_block)); | 1173 branch.Emit(chunk_->GetAssemblyLabel(left_block)); |
1171 __ B(chunk_->GetAssemblyLabel(right_block)); | 1174 __ B(chunk_->GetAssemblyLabel(right_block)); |
1172 } | 1175 } |
1173 } | 1176 } |
1174 | 1177 |
1175 | 1178 |
1176 template<class InstrType> | 1179 template<class InstrType> |
1177 void LCodeGen::EmitBranch(InstrType instr, Condition condition) { | 1180 void LCodeGen::EmitBranch(InstrType instr, Condition condition) { |
| 1181 ASSERT((condition != al) && (condition != nv)); |
1178 BranchOnCondition branch(this, condition); | 1182 BranchOnCondition branch(this, condition); |
1179 EmitBranchGeneric(instr, branch); | 1183 EmitBranchGeneric(instr, branch); |
1180 } | 1184 } |
1181 | 1185 |
1182 | 1186 |
1183 template<class InstrType> | 1187 template<class InstrType> |
1184 void LCodeGen::EmitCompareAndBranch(InstrType instr, | 1188 void LCodeGen::EmitCompareAndBranch(InstrType instr, |
1185 Condition condition, | 1189 Condition condition, |
1186 const Register& lhs, | 1190 const Register& lhs, |
1187 const Operand& rhs) { | 1191 const Operand& rhs) { |
| 1192 ASSERT((condition != al) && (condition != nv)); |
1188 CompareAndBranch branch(this, condition, lhs, rhs); | 1193 CompareAndBranch branch(this, condition, lhs, rhs); |
1189 EmitBranchGeneric(instr, branch); | 1194 EmitBranchGeneric(instr, branch); |
1190 } | 1195 } |
1191 | 1196 |
1192 | 1197 |
1193 template<class InstrType> | 1198 template<class InstrType> |
1194 void LCodeGen::EmitTestAndBranch(InstrType instr, | 1199 void LCodeGen::EmitTestAndBranch(InstrType instr, |
1195 Condition condition, | 1200 Condition condition, |
1196 const Register& value, | 1201 const Register& value, |
1197 uint64_t mask) { | 1202 uint64_t mask) { |
| 1203 ASSERT((condition != al) && (condition != nv)); |
1198 TestAndBranch branch(this, condition, value, mask); | 1204 TestAndBranch branch(this, condition, value, mask); |
1199 EmitBranchGeneric(instr, branch); | 1205 EmitBranchGeneric(instr, branch); |
1200 } | 1206 } |
1201 | 1207 |
1202 | 1208 |
1203 template<class InstrType> | 1209 template<class InstrType> |
1204 void LCodeGen::EmitBranchIfNonZeroNumber(InstrType instr, | 1210 void LCodeGen::EmitBranchIfNonZeroNumber(InstrType instr, |
1205 const FPRegister& value, | 1211 const FPRegister& value, |
1206 const FPRegister& scratch) { | 1212 const FPRegister& scratch) { |
1207 BranchIfNonZeroNumber branch(this, value, scratch); | 1213 BranchIfNonZeroNumber branch(this, value, scratch); |
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2150 | 2156 |
2151 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { | 2157 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { |
2152 Register value = ToRegister(instr->value()); | 2158 Register value = ToRegister(instr->value()); |
2153 Register map = ToRegister(instr->temp()); | 2159 Register map = ToRegister(instr->temp()); |
2154 | 2160 |
2155 __ Ldr(map, FieldMemOperand(value, HeapObject::kMapOffset)); | 2161 __ Ldr(map, FieldMemOperand(value, HeapObject::kMapOffset)); |
2156 EmitCompareAndBranch(instr, eq, map, Operand(instr->map())); | 2162 EmitCompareAndBranch(instr, eq, map, Operand(instr->map())); |
2157 } | 2163 } |
2158 | 2164 |
2159 | 2165 |
2160 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { | 2166 void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) { |
2161 LOperand* left = instr->left(); | 2167 LOperand* left = instr->left(); |
2162 LOperand* right = instr->right(); | 2168 LOperand* right = instr->right(); |
2163 Condition cond = TokenToCondition(instr->op(), false); | 2169 Condition cond = TokenToCondition(instr->op(), false); |
2164 | 2170 |
2165 if (left->IsConstantOperand() && right->IsConstantOperand()) { | 2171 if (left->IsConstantOperand() && right->IsConstantOperand()) { |
2166 // We can statically evaluate the comparison. | 2172 // We can statically evaluate the comparison. |
2167 double left_val = ToDouble(LConstantOperand::cast(left)); | 2173 double left_val = ToDouble(LConstantOperand::cast(left)); |
2168 double right_val = ToDouble(LConstantOperand::cast(right)); | 2174 double right_val = ToDouble(LConstantOperand::cast(right)); |
2169 int next_block = EvalComparison(instr->op(), left_val, right_val) ? | 2175 int next_block = EvalComparison(instr->op(), left_val, right_val) ? |
2170 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_); | 2176 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_); |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2584 // Load the map's "bit field 2" into result. | 2590 // Load the map's "bit field 2" into result. |
2585 ASSERT((Map::kElementsKindBitCount + Map::kElementsKindShift) <= kByteSize); | 2591 ASSERT((Map::kElementsKindBitCount + Map::kElementsKindShift) <= kByteSize); |
2586 __ Ldrb(result.W(), FieldMemOperand(result, Map::kBitField2Offset)); | 2592 __ Ldrb(result.W(), FieldMemOperand(result, Map::kBitField2Offset)); |
2587 | 2593 |
2588 // Retrieve elements_kind from bit field 2. | 2594 // Retrieve elements_kind from bit field 2. |
2589 __ Ubfx(result.W(), result.W(), Map::kElementsKindShift, | 2595 __ Ubfx(result.W(), result.W(), Map::kElementsKindShift, |
2590 Map::kElementsKindBitCount); | 2596 Map::kElementsKindBitCount); |
2591 } | 2597 } |
2592 | 2598 |
2593 | 2599 |
2594 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) { | |
2595 Register result = ToRegister(instr->result()); | |
2596 Register array = ToRegister(instr->value()); | |
2597 __ Ldr(result, FieldMemOperand(array, FixedArrayBase::kLengthOffset)); | |
2598 } | |
2599 | |
2600 | |
2601 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { | 2600 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { |
2602 // FunctionLiteral instruction is marked as call, we can trash any register. | 2601 // FunctionLiteral instruction is marked as call, we can trash any register. |
2603 ASSERT(instr->IsMarkedAsCall()); | 2602 ASSERT(instr->IsMarkedAsCall()); |
2604 | 2603 |
2605 // Use the fast case closure allocation code that allocates in new | 2604 // Use the fast case closure allocation code that allocates in new |
2606 // space for nested functions that don't need literals cloning. | 2605 // space for nested functions that don't need literals cloning. |
2607 bool pretenure = instr->hydrogen()->pretenure(); | 2606 bool pretenure = instr->hydrogen()->pretenure(); |
2608 if (!pretenure && instr->hydrogen()->has_no_literals()) { | 2607 if (!pretenure && instr->hydrogen()->has_no_literals()) { |
2609 FastNewClosureStub stub(instr->hydrogen()->language_mode(), | 2608 FastNewClosureStub stub(instr->hydrogen()->language_mode(), |
2610 instr->hydrogen()->is_generator()); | 2609 instr->hydrogen()->is_generator()); |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2986 | 2985 |
2987 // Check the marker in the calling frame. | 2986 // Check the marker in the calling frame. |
2988 __ Bind(&check_frame_marker); | 2987 __ Bind(&check_frame_marker); |
2989 __ Ldr(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset)); | 2988 __ Ldr(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset)); |
2990 | 2989 |
2991 EmitCompareAndBranch( | 2990 EmitCompareAndBranch( |
2992 instr, eq, temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); | 2991 instr, eq, temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); |
2993 } | 2992 } |
2994 | 2993 |
2995 | 2994 |
| 2995 void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) { |
| 2996 Representation r = instr->hydrogen()->value()->representation(); |
| 2997 if (r.IsSmiOrInteger32() || r.IsDouble()) { |
| 2998 __ B(instr->TrueLabel(chunk_)); |
| 2999 } else { |
| 3000 ASSERT(r.IsTagged()); |
| 3001 Register value = ToRegister(instr->value()); |
| 3002 HType type = instr->hydrogen()->value()->type(); |
| 3003 if (type.IsTaggedNumber()) { |
| 3004 __ B(instr->TrueLabel(chunk_)); |
| 3005 } |
| 3006 __ JumpIfSmi(value, instr->TrueLabel(chunk_)); |
| 3007 // TODO(jbramley): Add an EmitBranch helper for this. |
| 3008 __ JumpForHeapNumber(value, NoReg, |
| 3009 instr->TrueLabel(chunk_), instr->FalseLabel(chunk_)); |
| 3010 } |
| 3011 } |
| 3012 |
| 3013 |
2996 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { | 3014 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { |
2997 Label* is_object = instr->TrueLabel(chunk_); | 3015 Label* is_object = instr->TrueLabel(chunk_); |
2998 Label* is_not_object = instr->FalseLabel(chunk_); | 3016 Label* is_not_object = instr->FalseLabel(chunk_); |
2999 Register value = ToRegister(instr->value()); | 3017 Register value = ToRegister(instr->value()); |
3000 Register map = ToRegister(instr->temp1()); | 3018 Register map = ToRegister(instr->temp1()); |
3001 Register scratch = ToRegister(instr->temp2()); | 3019 Register scratch = ToRegister(instr->temp2()); |
3002 | 3020 |
3003 __ JumpIfSmi(value, is_not_object); | 3021 __ JumpIfSmi(value, is_not_object); |
3004 __ JumpIfRoot(value, Heap::kNullValueRootIndex, is_object); | 3022 __ JumpIfRoot(value, Heap::kNullValueRootIndex, is_object); |
3005 | 3023 |
(...skipping 2549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5555 __ Bind(&out_of_object); | 5573 __ Bind(&out_of_object); |
5556 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5574 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
5557 // Index is equal to negated out of object property index plus 1. | 5575 // Index is equal to negated out of object property index plus 1. |
5558 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5576 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
5559 __ Ldr(result, FieldMemOperand(result, | 5577 __ Ldr(result, FieldMemOperand(result, |
5560 FixedArray::kHeaderSize - kPointerSize)); | 5578 FixedArray::kHeaderSize - kPointerSize)); |
5561 __ Bind(&done); | 5579 __ Bind(&done); |
5562 } | 5580 } |
5563 | 5581 |
5564 } } // namespace v8::internal | 5582 } } // namespace v8::internal |
OLD | NEW |