| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/code-assembler.h" | 5 #include "src/compiler/code-assembler.h" |
| 6 | 6 |
| 7 #include <ostream> | 7 #include <ostream> |
| 8 | 8 |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/compiler/graph.h" | 10 #include "src/compiler/graph.h" |
| 11 #include "src/compiler/instruction-selector.h" | 11 #include "src/compiler/instruction-selector.h" |
| 12 #include "src/compiler/linkage.h" | 12 #include "src/compiler/linkage.h" |
| 13 #include "src/compiler/node-matchers.h" | 13 #include "src/compiler/node-matchers.h" |
| 14 #include "src/compiler/pipeline.h" | 14 #include "src/compiler/pipeline.h" |
| 15 #include "src/compiler/raw-machine-assembler.h" | 15 #include "src/compiler/raw-machine-assembler.h" |
| 16 #include "src/compiler/schedule.h" | 16 #include "src/compiler/schedule.h" |
| 17 #include "src/frames.h" | 17 #include "src/frames.h" |
| 18 #include "src/interface-descriptors.h" | 18 #include "src/interface-descriptors.h" |
| 19 #include "src/interpreter/bytecodes.h" | 19 #include "src/interpreter/bytecodes.h" |
| 20 #include "src/machine-type.h" | 20 #include "src/machine-type.h" |
| 21 #include "src/macro-assembler.h" | 21 #include "src/macro-assembler.h" |
| 22 #include "src/utils.h" | 22 #include "src/utils.h" |
| 23 #include "src/zone/zone.h" | 23 #include "src/zone/zone.h" |
| 24 | 24 |
| 25 namespace v8 { | 25 namespace v8 { |
| 26 namespace internal { | 26 namespace internal { |
| 27 namespace compiler { | 27 namespace compiler { |
| 28 | 28 |
| 29 CodeAssembler::CodeAssembler(Isolate* isolate, Zone* zone, | 29 CodeAssemblerState::CodeAssemblerState( |
| 30 const CallInterfaceDescriptor& descriptor, | 30 Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor, |
| 31 Code::Flags flags, const char* name, | 31 Code::Flags flags, const char* name, size_t result_size) |
| 32 size_t result_size) | 32 : CodeAssemblerState( |
| 33 : CodeAssembler( | |
| 34 isolate, zone, | 33 isolate, zone, |
| 35 Linkage::GetStubCallDescriptor( | 34 Linkage::GetStubCallDescriptor( |
| 36 isolate, zone, descriptor, descriptor.GetStackParameterCount(), | 35 isolate, zone, descriptor, descriptor.GetStackParameterCount(), |
| 37 CallDescriptor::kNoFlags, Operator::kNoProperties, | 36 CallDescriptor::kNoFlags, Operator::kNoProperties, |
| 38 MachineType::AnyTagged(), result_size), | 37 MachineType::AnyTagged(), result_size), |
| 39 flags, name) {} | 38 flags, name) {} |
| 40 | 39 |
| 41 CodeAssembler::CodeAssembler(Isolate* isolate, Zone* zone, int parameter_count, | 40 CodeAssemblerState::CodeAssemblerState(Isolate* isolate, Zone* zone, |
| 42 Code::Flags flags, const char* name) | 41 int parameter_count, Code::Flags flags, |
| 43 : CodeAssembler(isolate, zone, | 42 const char* name) |
| 44 Linkage::GetJSCallDescriptor( | 43 : CodeAssemblerState(isolate, zone, |
| 45 zone, false, parameter_count, | 44 Linkage::GetJSCallDescriptor( |
| 46 Code::ExtractKindFromFlags(flags) == Code::BUILTIN | 45 zone, false, parameter_count, |
| 47 ? CallDescriptor::kPushArgumentCount | 46 Code::ExtractKindFromFlags(flags) == Code::BUILTIN |
| 48 : CallDescriptor::kNoFlags), | 47 ? CallDescriptor::kPushArgumentCount |
| 49 flags, name) {} | 48 : CallDescriptor::kNoFlags), |
| 49 flags, name) {} |
| 50 | 50 |
| 51 CodeAssembler::CodeAssembler(Isolate* isolate, Zone* zone, | 51 CodeAssemblerState::CodeAssemblerState(Isolate* isolate, Zone* zone, |
| 52 CallDescriptor* call_descriptor, Code::Flags flags, | 52 CallDescriptor* call_descriptor, |
| 53 const char* name) | 53 Code::Flags flags, const char* name) |
| 54 : raw_assembler_(new RawMachineAssembler( | 54 : raw_assembler_(new RawMachineAssembler( |
| 55 isolate, new (zone) Graph(zone), call_descriptor, | 55 isolate, new (zone) Graph(zone), call_descriptor, |
| 56 MachineType::PointerRepresentation(), | 56 MachineType::PointerRepresentation(), |
| 57 InstructionSelector::SupportedMachineOperatorFlags(), | 57 InstructionSelector::SupportedMachineOperatorFlags(), |
| 58 InstructionSelector::AlignmentRequirements())), | 58 InstructionSelector::AlignmentRequirements())), |
| 59 flags_(flags), | 59 flags_(flags), |
| 60 name_(name), | 60 name_(name), |
| 61 code_generated_(false), | 61 code_generated_(false), |
| 62 variables_(zone) {} | 62 variables_(zone) {} |
| 63 | 63 |
| 64 CodeAssemblerState::~CodeAssemblerState() {} |
| 65 |
| 64 CodeAssembler::~CodeAssembler() {} | 66 CodeAssembler::~CodeAssembler() {} |
| 65 | 67 |
| 66 void CodeAssembler::CallPrologue() {} | 68 void CodeAssembler::CallPrologue() {} |
| 67 | 69 |
| 68 void CodeAssembler::CallEpilogue() {} | 70 void CodeAssembler::CallEpilogue() {} |
| 69 | 71 |
| 70 Handle<Code> CodeAssembler::GenerateCode() { | 72 // static |
| 71 DCHECK(!code_generated_); | 73 Handle<Code> CodeAssembler::GenerateCode(CodeAssemblerState* state) { |
| 74 DCHECK(!state->code_generated_); |
| 72 | 75 |
| 73 Schedule* schedule = raw_assembler_->Export(); | 76 RawMachineAssembler* rasm = state->raw_assembler_.get(); |
| 77 Schedule* schedule = rasm->Export(); |
| 74 Handle<Code> code = Pipeline::GenerateCodeForCodeStub( | 78 Handle<Code> code = Pipeline::GenerateCodeForCodeStub( |
| 75 isolate(), raw_assembler_->call_descriptor(), raw_assembler_->graph(), | 79 rasm->isolate(), rasm->call_descriptor(), rasm->graph(), schedule, |
| 76 schedule, flags_, name_); | 80 state->flags_, state->name_); |
| 77 | 81 |
| 78 code_generated_ = true; | 82 state->code_generated_ = true; |
| 79 return code; | 83 return code; |
| 80 } | 84 } |
| 81 | 85 |
| 82 bool CodeAssembler::Is64() const { return raw_assembler_->machine()->Is64(); } | 86 bool CodeAssembler::Is64() const { return raw_assembler()->machine()->Is64(); } |
| 83 | 87 |
| 84 bool CodeAssembler::IsFloat64RoundUpSupported() const { | 88 bool CodeAssembler::IsFloat64RoundUpSupported() const { |
| 85 return raw_assembler_->machine()->Float64RoundUp().IsSupported(); | 89 return raw_assembler()->machine()->Float64RoundUp().IsSupported(); |
| 86 } | 90 } |
| 87 | 91 |
| 88 bool CodeAssembler::IsFloat64RoundDownSupported() const { | 92 bool CodeAssembler::IsFloat64RoundDownSupported() const { |
| 89 return raw_assembler_->machine()->Float64RoundDown().IsSupported(); | 93 return raw_assembler()->machine()->Float64RoundDown().IsSupported(); |
| 90 } | 94 } |
| 91 | 95 |
| 92 bool CodeAssembler::IsFloat64RoundTruncateSupported() const { | 96 bool CodeAssembler::IsFloat64RoundTruncateSupported() const { |
| 93 return raw_assembler_->machine()->Float64RoundTruncate().IsSupported(); | 97 return raw_assembler()->machine()->Float64RoundTruncate().IsSupported(); |
| 94 } | 98 } |
| 95 | 99 |
| 96 Node* CodeAssembler::Int32Constant(int32_t value) { | 100 Node* CodeAssembler::Int32Constant(int32_t value) { |
| 97 return raw_assembler_->Int32Constant(value); | 101 return raw_assembler()->Int32Constant(value); |
| 98 } | 102 } |
| 99 | 103 |
| 100 Node* CodeAssembler::Int64Constant(int64_t value) { | 104 Node* CodeAssembler::Int64Constant(int64_t value) { |
| 101 return raw_assembler_->Int64Constant(value); | 105 return raw_assembler()->Int64Constant(value); |
| 102 } | 106 } |
| 103 | 107 |
| 104 Node* CodeAssembler::IntPtrConstant(intptr_t value) { | 108 Node* CodeAssembler::IntPtrConstant(intptr_t value) { |
| 105 return raw_assembler_->IntPtrConstant(value); | 109 return raw_assembler()->IntPtrConstant(value); |
| 106 } | 110 } |
| 107 | 111 |
| 108 Node* CodeAssembler::NumberConstant(double value) { | 112 Node* CodeAssembler::NumberConstant(double value) { |
| 109 return raw_assembler_->NumberConstant(value); | 113 return raw_assembler()->NumberConstant(value); |
| 110 } | 114 } |
| 111 | 115 |
| 112 Node* CodeAssembler::SmiConstant(Smi* value) { | 116 Node* CodeAssembler::SmiConstant(Smi* value) { |
| 113 return BitcastWordToTaggedSigned(IntPtrConstant(bit_cast<intptr_t>(value))); | 117 return BitcastWordToTaggedSigned(IntPtrConstant(bit_cast<intptr_t>(value))); |
| 114 } | 118 } |
| 115 | 119 |
| 116 Node* CodeAssembler::SmiConstant(int value) { | 120 Node* CodeAssembler::SmiConstant(int value) { |
| 117 return SmiConstant(Smi::FromInt(value)); | 121 return SmiConstant(Smi::FromInt(value)); |
| 118 } | 122 } |
| 119 | 123 |
| 120 Node* CodeAssembler::HeapConstant(Handle<HeapObject> object) { | 124 Node* CodeAssembler::HeapConstant(Handle<HeapObject> object) { |
| 121 return raw_assembler_->HeapConstant(object); | 125 return raw_assembler()->HeapConstant(object); |
| 122 } | 126 } |
| 123 | 127 |
| 124 Node* CodeAssembler::BooleanConstant(bool value) { | 128 Node* CodeAssembler::BooleanConstant(bool value) { |
| 125 return raw_assembler_->BooleanConstant(value); | 129 return raw_assembler()->BooleanConstant(value); |
| 126 } | 130 } |
| 127 | 131 |
| 128 Node* CodeAssembler::ExternalConstant(ExternalReference address) { | 132 Node* CodeAssembler::ExternalConstant(ExternalReference address) { |
| 129 return raw_assembler_->ExternalConstant(address); | 133 return raw_assembler()->ExternalConstant(address); |
| 130 } | 134 } |
| 131 | 135 |
| 132 Node* CodeAssembler::Float64Constant(double value) { | 136 Node* CodeAssembler::Float64Constant(double value) { |
| 133 return raw_assembler_->Float64Constant(value); | 137 return raw_assembler()->Float64Constant(value); |
| 134 } | 138 } |
| 135 | 139 |
| 136 Node* CodeAssembler::NaNConstant() { | 140 Node* CodeAssembler::NaNConstant() { |
| 137 return LoadRoot(Heap::kNanValueRootIndex); | 141 return LoadRoot(Heap::kNanValueRootIndex); |
| 138 } | 142 } |
| 139 | 143 |
| 140 bool CodeAssembler::ToInt32Constant(Node* node, int32_t& out_value) { | 144 bool CodeAssembler::ToInt32Constant(Node* node, int32_t& out_value) { |
| 141 Int64Matcher m(node); | 145 Int64Matcher m(node); |
| 142 if (m.HasValue() && | 146 if (m.HasValue() && |
| 143 m.IsInRange(std::numeric_limits<int32_t>::min(), | 147 m.IsInRange(std::numeric_limits<int32_t>::min(), |
| (...skipping 25 matching lines...) Expand all Loading... |
| 169 return false; | 173 return false; |
| 170 } | 174 } |
| 171 | 175 |
| 172 bool CodeAssembler::ToIntPtrConstant(Node* node, intptr_t& out_value) { | 176 bool CodeAssembler::ToIntPtrConstant(Node* node, intptr_t& out_value) { |
| 173 IntPtrMatcher m(node); | 177 IntPtrMatcher m(node); |
| 174 if (m.HasValue()) out_value = m.Value(); | 178 if (m.HasValue()) out_value = m.Value(); |
| 175 return m.HasValue(); | 179 return m.HasValue(); |
| 176 } | 180 } |
| 177 | 181 |
| 178 Node* CodeAssembler::Parameter(int value) { | 182 Node* CodeAssembler::Parameter(int value) { |
| 179 return raw_assembler_->Parameter(value); | 183 return raw_assembler()->Parameter(value); |
| 180 } | 184 } |
| 181 | 185 |
| 182 void CodeAssembler::Return(Node* value) { | 186 void CodeAssembler::Return(Node* value) { |
| 183 return raw_assembler_->Return(value); | 187 return raw_assembler()->Return(value); |
| 184 } | 188 } |
| 185 | 189 |
| 186 void CodeAssembler::PopAndReturn(Node* pop, Node* value) { | 190 void CodeAssembler::PopAndReturn(Node* pop, Node* value) { |
| 187 return raw_assembler_->PopAndReturn(pop, value); | 191 return raw_assembler()->PopAndReturn(pop, value); |
| 188 } | 192 } |
| 189 | 193 |
| 190 void CodeAssembler::DebugBreak() { raw_assembler_->DebugBreak(); } | 194 void CodeAssembler::DebugBreak() { raw_assembler()->DebugBreak(); } |
| 191 | 195 |
| 192 void CodeAssembler::Comment(const char* format, ...) { | 196 void CodeAssembler::Comment(const char* format, ...) { |
| 193 if (!FLAG_code_comments) return; | 197 if (!FLAG_code_comments) return; |
| 194 char buffer[4 * KB]; | 198 char buffer[4 * KB]; |
| 195 StringBuilder builder(buffer, arraysize(buffer)); | 199 StringBuilder builder(buffer, arraysize(buffer)); |
| 196 va_list arguments; | 200 va_list arguments; |
| 197 va_start(arguments, format); | 201 va_start(arguments, format); |
| 198 builder.AddFormattedList(format, arguments); | 202 builder.AddFormattedList(format, arguments); |
| 199 va_end(arguments); | 203 va_end(arguments); |
| 200 | 204 |
| 201 // Copy the string before recording it in the assembler to avoid | 205 // Copy the string before recording it in the assembler to avoid |
| 202 // issues when the stack allocated buffer goes out of scope. | 206 // issues when the stack allocated buffer goes out of scope. |
| 203 const int prefix_len = 2; | 207 const int prefix_len = 2; |
| 204 int length = builder.position() + 1; | 208 int length = builder.position() + 1; |
| 205 char* copy = reinterpret_cast<char*>(malloc(length + prefix_len)); | 209 char* copy = reinterpret_cast<char*>(malloc(length + prefix_len)); |
| 206 MemCopy(copy + prefix_len, builder.Finalize(), length); | 210 MemCopy(copy + prefix_len, builder.Finalize(), length); |
| 207 copy[0] = ';'; | 211 copy[0] = ';'; |
| 208 copy[1] = ' '; | 212 copy[1] = ' '; |
| 209 raw_assembler_->Comment(copy); | 213 raw_assembler()->Comment(copy); |
| 210 } | 214 } |
| 211 | 215 |
| 212 void CodeAssembler::Bind(CodeAssembler::Label* label) { return label->Bind(); } | 216 void CodeAssembler::Bind(CodeAssembler::Label* label) { return label->Bind(); } |
| 213 | 217 |
| 214 Node* CodeAssembler::LoadFramePointer() { | 218 Node* CodeAssembler::LoadFramePointer() { |
| 215 return raw_assembler_->LoadFramePointer(); | 219 return raw_assembler()->LoadFramePointer(); |
| 216 } | 220 } |
| 217 | 221 |
| 218 Node* CodeAssembler::LoadParentFramePointer() { | 222 Node* CodeAssembler::LoadParentFramePointer() { |
| 219 return raw_assembler_->LoadParentFramePointer(); | 223 return raw_assembler()->LoadParentFramePointer(); |
| 220 } | 224 } |
| 221 | 225 |
| 222 Node* CodeAssembler::LoadStackPointer() { | 226 Node* CodeAssembler::LoadStackPointer() { |
| 223 return raw_assembler_->LoadStackPointer(); | 227 return raw_assembler()->LoadStackPointer(); |
| 224 } | 228 } |
| 225 | 229 |
| 226 #define DEFINE_CODE_ASSEMBLER_BINARY_OP(name) \ | 230 #define DEFINE_CODE_ASSEMBLER_BINARY_OP(name) \ |
| 227 Node* CodeAssembler::name(Node* a, Node* b) { \ | 231 Node* CodeAssembler::name(Node* a, Node* b) { \ |
| 228 return raw_assembler_->name(a, b); \ | 232 return raw_assembler()->name(a, b); \ |
| 229 } | 233 } |
| 230 CODE_ASSEMBLER_BINARY_OP_LIST(DEFINE_CODE_ASSEMBLER_BINARY_OP) | 234 CODE_ASSEMBLER_BINARY_OP_LIST(DEFINE_CODE_ASSEMBLER_BINARY_OP) |
| 231 #undef DEFINE_CODE_ASSEMBLER_BINARY_OP | 235 #undef DEFINE_CODE_ASSEMBLER_BINARY_OP |
| 232 | 236 |
| 233 Node* CodeAssembler::WordShl(Node* value, int shift) { | 237 Node* CodeAssembler::WordShl(Node* value, int shift) { |
| 234 return (shift != 0) ? raw_assembler_->WordShl(value, IntPtrConstant(shift)) | 238 return (shift != 0) ? raw_assembler()->WordShl(value, IntPtrConstant(shift)) |
| 235 : value; | 239 : value; |
| 236 } | 240 } |
| 237 | 241 |
| 238 Node* CodeAssembler::WordShr(Node* value, int shift) { | 242 Node* CodeAssembler::WordShr(Node* value, int shift) { |
| 239 return (shift != 0) ? raw_assembler_->WordShr(value, IntPtrConstant(shift)) | 243 return (shift != 0) ? raw_assembler()->WordShr(value, IntPtrConstant(shift)) |
| 240 : value; | 244 : value; |
| 241 } | 245 } |
| 242 | 246 |
| 243 Node* CodeAssembler::Word32Shr(Node* value, int shift) { | 247 Node* CodeAssembler::Word32Shr(Node* value, int shift) { |
| 244 return (shift != 0) ? raw_assembler_->Word32Shr(value, Int32Constant(shift)) | 248 return (shift != 0) ? raw_assembler()->Word32Shr(value, Int32Constant(shift)) |
| 245 : value; | 249 : value; |
| 246 } | 250 } |
| 247 | 251 |
| 248 Node* CodeAssembler::ChangeUint32ToWord(Node* value) { | 252 Node* CodeAssembler::ChangeUint32ToWord(Node* value) { |
| 249 if (raw_assembler_->machine()->Is64()) { | 253 if (raw_assembler()->machine()->Is64()) { |
| 250 value = raw_assembler_->ChangeUint32ToUint64(value); | 254 value = raw_assembler()->ChangeUint32ToUint64(value); |
| 251 } | 255 } |
| 252 return value; | 256 return value; |
| 253 } | 257 } |
| 254 | 258 |
| 255 Node* CodeAssembler::ChangeInt32ToIntPtr(Node* value) { | 259 Node* CodeAssembler::ChangeInt32ToIntPtr(Node* value) { |
| 256 if (raw_assembler_->machine()->Is64()) { | 260 if (raw_assembler()->machine()->Is64()) { |
| 257 value = raw_assembler_->ChangeInt32ToInt64(value); | 261 value = raw_assembler()->ChangeInt32ToInt64(value); |
| 258 } | 262 } |
| 259 return value; | 263 return value; |
| 260 } | 264 } |
| 261 | 265 |
| 262 Node* CodeAssembler::RoundIntPtrToFloat64(Node* value) { | 266 Node* CodeAssembler::RoundIntPtrToFloat64(Node* value) { |
| 263 if (raw_assembler_->machine()->Is64()) { | 267 if (raw_assembler()->machine()->Is64()) { |
| 264 return raw_assembler_->RoundInt64ToFloat64(value); | 268 return raw_assembler()->RoundInt64ToFloat64(value); |
| 265 } | 269 } |
| 266 return raw_assembler_->ChangeInt32ToFloat64(value); | 270 return raw_assembler()->ChangeInt32ToFloat64(value); |
| 267 } | 271 } |
| 268 | 272 |
| 269 #define DEFINE_CODE_ASSEMBLER_UNARY_OP(name) \ | 273 #define DEFINE_CODE_ASSEMBLER_UNARY_OP(name) \ |
| 270 Node* CodeAssembler::name(Node* a) { return raw_assembler_->name(a); } | 274 Node* CodeAssembler::name(Node* a) { return raw_assembler()->name(a); } |
| 271 CODE_ASSEMBLER_UNARY_OP_LIST(DEFINE_CODE_ASSEMBLER_UNARY_OP) | 275 CODE_ASSEMBLER_UNARY_OP_LIST(DEFINE_CODE_ASSEMBLER_UNARY_OP) |
| 272 #undef DEFINE_CODE_ASSEMBLER_UNARY_OP | 276 #undef DEFINE_CODE_ASSEMBLER_UNARY_OP |
| 273 | 277 |
| 274 Node* CodeAssembler::Load(MachineType rep, Node* base) { | 278 Node* CodeAssembler::Load(MachineType rep, Node* base) { |
| 275 return raw_assembler_->Load(rep, base); | 279 return raw_assembler()->Load(rep, base); |
| 276 } | 280 } |
| 277 | 281 |
| 278 Node* CodeAssembler::Load(MachineType rep, Node* base, Node* index) { | 282 Node* CodeAssembler::Load(MachineType rep, Node* base, Node* index) { |
| 279 return raw_assembler_->Load(rep, base, index); | 283 return raw_assembler()->Load(rep, base, index); |
| 280 } | 284 } |
| 281 | 285 |
| 282 Node* CodeAssembler::AtomicLoad(MachineType rep, Node* base, Node* index) { | 286 Node* CodeAssembler::AtomicLoad(MachineType rep, Node* base, Node* index) { |
| 283 return raw_assembler_->AtomicLoad(rep, base, index); | 287 return raw_assembler()->AtomicLoad(rep, base, index); |
| 284 } | 288 } |
| 285 | 289 |
| 286 Node* CodeAssembler::LoadRoot(Heap::RootListIndex root_index) { | 290 Node* CodeAssembler::LoadRoot(Heap::RootListIndex root_index) { |
| 287 if (isolate()->heap()->RootCanBeTreatedAsConstant(root_index)) { | 291 if (isolate()->heap()->RootCanBeTreatedAsConstant(root_index)) { |
| 288 Handle<Object> root = isolate()->heap()->root_handle(root_index); | 292 Handle<Object> root = isolate()->heap()->root_handle(root_index); |
| 289 if (root->IsSmi()) { | 293 if (root->IsSmi()) { |
| 290 return SmiConstant(Smi::cast(*root)); | 294 return SmiConstant(Smi::cast(*root)); |
| 291 } else { | 295 } else { |
| 292 return HeapConstant(Handle<HeapObject>::cast(root)); | 296 return HeapConstant(Handle<HeapObject>::cast(root)); |
| 293 } | 297 } |
| 294 } | 298 } |
| 295 | 299 |
| 296 Node* roots_array_start = | 300 Node* roots_array_start = |
| 297 ExternalConstant(ExternalReference::roots_array_start(isolate())); | 301 ExternalConstant(ExternalReference::roots_array_start(isolate())); |
| 298 return Load(MachineType::AnyTagged(), roots_array_start, | 302 return Load(MachineType::AnyTagged(), roots_array_start, |
| 299 IntPtrConstant(root_index * kPointerSize)); | 303 IntPtrConstant(root_index * kPointerSize)); |
| 300 } | 304 } |
| 301 | 305 |
| 302 Node* CodeAssembler::Store(MachineRepresentation rep, Node* base, Node* value) { | 306 Node* CodeAssembler::Store(MachineRepresentation rep, Node* base, Node* value) { |
| 303 return raw_assembler_->Store(rep, base, value, kFullWriteBarrier); | 307 return raw_assembler()->Store(rep, base, value, kFullWriteBarrier); |
| 304 } | 308 } |
| 305 | 309 |
| 306 Node* CodeAssembler::Store(MachineRepresentation rep, Node* base, Node* index, | 310 Node* CodeAssembler::Store(MachineRepresentation rep, Node* base, Node* index, |
| 307 Node* value) { | 311 Node* value) { |
| 308 return raw_assembler_->Store(rep, base, index, value, kFullWriteBarrier); | 312 return raw_assembler()->Store(rep, base, index, value, kFullWriteBarrier); |
| 309 } | 313 } |
| 310 | 314 |
| 311 Node* CodeAssembler::StoreNoWriteBarrier(MachineRepresentation rep, Node* base, | 315 Node* CodeAssembler::StoreNoWriteBarrier(MachineRepresentation rep, Node* base, |
| 312 Node* value) { | 316 Node* value) { |
| 313 return raw_assembler_->Store(rep, base, value, kNoWriteBarrier); | 317 return raw_assembler()->Store(rep, base, value, kNoWriteBarrier); |
| 314 } | 318 } |
| 315 | 319 |
| 316 Node* CodeAssembler::StoreNoWriteBarrier(MachineRepresentation rep, Node* base, | 320 Node* CodeAssembler::StoreNoWriteBarrier(MachineRepresentation rep, Node* base, |
| 317 Node* index, Node* value) { | 321 Node* index, Node* value) { |
| 318 return raw_assembler_->Store(rep, base, index, value, kNoWriteBarrier); | 322 return raw_assembler()->Store(rep, base, index, value, kNoWriteBarrier); |
| 319 } | 323 } |
| 320 | 324 |
| 321 Node* CodeAssembler::AtomicStore(MachineRepresentation rep, Node* base, | 325 Node* CodeAssembler::AtomicStore(MachineRepresentation rep, Node* base, |
| 322 Node* index, Node* value) { | 326 Node* index, Node* value) { |
| 323 return raw_assembler_->AtomicStore(rep, base, index, value); | 327 return raw_assembler()->AtomicStore(rep, base, index, value); |
| 324 } | 328 } |
| 325 | 329 |
| 326 Node* CodeAssembler::StoreRoot(Heap::RootListIndex root_index, Node* value) { | 330 Node* CodeAssembler::StoreRoot(Heap::RootListIndex root_index, Node* value) { |
| 327 DCHECK(Heap::RootCanBeWrittenAfterInitialization(root_index)); | 331 DCHECK(Heap::RootCanBeWrittenAfterInitialization(root_index)); |
| 328 Node* roots_array_start = | 332 Node* roots_array_start = |
| 329 ExternalConstant(ExternalReference::roots_array_start(isolate())); | 333 ExternalConstant(ExternalReference::roots_array_start(isolate())); |
| 330 return StoreNoWriteBarrier(MachineRepresentation::kTagged, roots_array_start, | 334 return StoreNoWriteBarrier(MachineRepresentation::kTagged, roots_array_start, |
| 331 IntPtrConstant(root_index * kPointerSize), value); | 335 IntPtrConstant(root_index * kPointerSize), value); |
| 332 } | 336 } |
| 333 | 337 |
| 334 Node* CodeAssembler::Retain(Node* value) { | 338 Node* CodeAssembler::Retain(Node* value) { |
| 335 return raw_assembler_->Retain(value); | 339 return raw_assembler()->Retain(value); |
| 336 } | 340 } |
| 337 | 341 |
| 338 Node* CodeAssembler::Projection(int index, Node* value) { | 342 Node* CodeAssembler::Projection(int index, Node* value) { |
| 339 return raw_assembler_->Projection(index, value); | 343 return raw_assembler()->Projection(index, value); |
| 340 } | 344 } |
| 341 | 345 |
| 342 void CodeAssembler::GotoIfException(Node* node, Label* if_exception, | 346 void CodeAssembler::GotoIfException(Node* node, Label* if_exception, |
| 343 Variable* exception_var) { | 347 Variable* exception_var) { |
| 344 Label success(this), exception(this, Label::kDeferred); | 348 Label success(this), exception(this, Label::kDeferred); |
| 345 success.MergeVariables(); | 349 success.MergeVariables(); |
| 346 exception.MergeVariables(); | 350 exception.MergeVariables(); |
| 347 DCHECK(!node->op()->HasProperty(Operator::kNoThrow)); | 351 DCHECK(!node->op()->HasProperty(Operator::kNoThrow)); |
| 348 | 352 |
| 349 raw_assembler_->Continuations(node, success.label_, exception.label_); | 353 raw_assembler()->Continuations(node, success.label_, exception.label_); |
| 350 | 354 |
| 351 Bind(&exception); | 355 Bind(&exception); |
| 352 const Operator* op = raw_assembler_->common()->IfException(); | 356 const Operator* op = raw_assembler()->common()->IfException(); |
| 353 Node* exception_value = raw_assembler_->AddNode(op, node, node); | 357 Node* exception_value = raw_assembler()->AddNode(op, node, node); |
| 354 if (exception_var != nullptr) { | 358 if (exception_var != nullptr) { |
| 355 exception_var->Bind(exception_value); | 359 exception_var->Bind(exception_value); |
| 356 } | 360 } |
| 357 Goto(if_exception); | 361 Goto(if_exception); |
| 358 | 362 |
| 359 Bind(&success); | 363 Bind(&success); |
| 360 } | 364 } |
| 361 | 365 |
| 362 Node* CodeAssembler::CallN(CallDescriptor* descriptor, Node* code_target, | 366 Node* CodeAssembler::CallN(CallDescriptor* descriptor, Node* code_target, |
| 363 Node** args) { | 367 Node** args) { |
| 364 CallPrologue(); | 368 CallPrologue(); |
| 365 Node* return_value = raw_assembler_->CallN(descriptor, code_target, args); | 369 Node* return_value = raw_assembler()->CallN(descriptor, code_target, args); |
| 366 CallEpilogue(); | 370 CallEpilogue(); |
| 367 return return_value; | 371 return return_value; |
| 368 } | 372 } |
| 369 | 373 |
| 370 Node* CodeAssembler::TailCallN(CallDescriptor* descriptor, Node* code_target, | 374 Node* CodeAssembler::TailCallN(CallDescriptor* descriptor, Node* code_target, |
| 371 Node** args) { | 375 Node** args) { |
| 372 return raw_assembler_->TailCallN(descriptor, code_target, args); | 376 return raw_assembler()->TailCallN(descriptor, code_target, args); |
| 373 } | 377 } |
| 374 | 378 |
| 375 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, | 379 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, |
| 376 Node* context) { | 380 Node* context) { |
| 377 CallPrologue(); | 381 CallPrologue(); |
| 378 Node* return_value = raw_assembler_->CallRuntime0(function_id, context); | 382 Node* return_value = raw_assembler()->CallRuntime0(function_id, context); |
| 379 CallEpilogue(); | 383 CallEpilogue(); |
| 380 return return_value; | 384 return return_value; |
| 381 } | 385 } |
| 382 | 386 |
| 383 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, | 387 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, |
| 384 Node* arg1) { | 388 Node* arg1) { |
| 385 CallPrologue(); | 389 CallPrologue(); |
| 386 Node* return_value = raw_assembler_->CallRuntime1(function_id, arg1, context); | 390 Node* return_value = |
| 391 raw_assembler()->CallRuntime1(function_id, arg1, context); |
| 387 CallEpilogue(); | 392 CallEpilogue(); |
| 388 return return_value; | 393 return return_value; |
| 389 } | 394 } |
| 390 | 395 |
| 391 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, | 396 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, |
| 392 Node* arg1, Node* arg2) { | 397 Node* arg1, Node* arg2) { |
| 393 CallPrologue(); | 398 CallPrologue(); |
| 394 Node* return_value = | 399 Node* return_value = |
| 395 raw_assembler_->CallRuntime2(function_id, arg1, arg2, context); | 400 raw_assembler()->CallRuntime2(function_id, arg1, arg2, context); |
| 396 CallEpilogue(); | 401 CallEpilogue(); |
| 397 return return_value; | 402 return return_value; |
| 398 } | 403 } |
| 399 | 404 |
| 400 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, | 405 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, |
| 401 Node* arg1, Node* arg2, Node* arg3) { | 406 Node* arg1, Node* arg2, Node* arg3) { |
| 402 CallPrologue(); | 407 CallPrologue(); |
| 403 Node* return_value = | 408 Node* return_value = |
| 404 raw_assembler_->CallRuntime3(function_id, arg1, arg2, arg3, context); | 409 raw_assembler()->CallRuntime3(function_id, arg1, arg2, arg3, context); |
| 405 CallEpilogue(); | 410 CallEpilogue(); |
| 406 return return_value; | 411 return return_value; |
| 407 } | 412 } |
| 408 | 413 |
| 409 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, | 414 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, |
| 410 Node* arg1, Node* arg2, Node* arg3, | 415 Node* arg1, Node* arg2, Node* arg3, |
| 411 Node* arg4) { | 416 Node* arg4) { |
| 412 CallPrologue(); | 417 CallPrologue(); |
| 413 Node* return_value = raw_assembler_->CallRuntime4(function_id, arg1, arg2, | 418 Node* return_value = raw_assembler()->CallRuntime4(function_id, arg1, arg2, |
| 414 arg3, arg4, context); | 419 arg3, arg4, context); |
| 415 CallEpilogue(); | 420 CallEpilogue(); |
| 416 return return_value; | 421 return return_value; |
| 417 } | 422 } |
| 418 | 423 |
| 419 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, | 424 Node* CodeAssembler::CallRuntime(Runtime::FunctionId function_id, Node* context, |
| 420 Node* arg1, Node* arg2, Node* arg3, Node* arg4, | 425 Node* arg1, Node* arg2, Node* arg3, Node* arg4, |
| 421 Node* arg5) { | 426 Node* arg5) { |
| 422 CallPrologue(); | 427 CallPrologue(); |
| 423 Node* return_value = raw_assembler_->CallRuntime5(function_id, arg1, arg2, | 428 Node* return_value = raw_assembler()->CallRuntime5(function_id, arg1, arg2, |
| 424 arg3, arg4, arg5, context); | 429 arg3, arg4, arg5, context); |
| 425 CallEpilogue(); | 430 CallEpilogue(); |
| 426 return return_value; | 431 return return_value; |
| 427 } | 432 } |
| 428 | 433 |
| 429 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, | 434 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, |
| 430 Node* context) { | 435 Node* context) { |
| 431 return raw_assembler_->TailCallRuntime0(function_id, context); | 436 return raw_assembler()->TailCallRuntime0(function_id, context); |
| 432 } | 437 } |
| 433 | 438 |
| 434 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, | 439 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, |
| 435 Node* context, Node* arg1) { | 440 Node* context, Node* arg1) { |
| 436 return raw_assembler_->TailCallRuntime1(function_id, arg1, context); | 441 return raw_assembler()->TailCallRuntime1(function_id, arg1, context); |
| 437 } | 442 } |
| 438 | 443 |
| 439 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, | 444 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, |
| 440 Node* context, Node* arg1, Node* arg2) { | 445 Node* context, Node* arg1, Node* arg2) { |
| 441 return raw_assembler_->TailCallRuntime2(function_id, arg1, arg2, context); | 446 return raw_assembler()->TailCallRuntime2(function_id, arg1, arg2, context); |
| 442 } | 447 } |
| 443 | 448 |
| 444 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, | 449 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, |
| 445 Node* context, Node* arg1, Node* arg2, | 450 Node* context, Node* arg1, Node* arg2, |
| 446 Node* arg3) { | 451 Node* arg3) { |
| 447 return raw_assembler_->TailCallRuntime3(function_id, arg1, arg2, arg3, | 452 return raw_assembler()->TailCallRuntime3(function_id, arg1, arg2, arg3, |
| 448 context); | 453 context); |
| 449 } | 454 } |
| 450 | 455 |
| 451 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, | 456 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, |
| 452 Node* context, Node* arg1, Node* arg2, | 457 Node* context, Node* arg1, Node* arg2, |
| 453 Node* arg3, Node* arg4) { | 458 Node* arg3, Node* arg4) { |
| 454 return raw_assembler_->TailCallRuntime4(function_id, arg1, arg2, arg3, arg4, | 459 return raw_assembler()->TailCallRuntime4(function_id, arg1, arg2, arg3, arg4, |
| 455 context); | 460 context); |
| 456 } | 461 } |
| 457 | 462 |
| 458 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, | 463 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, |
| 459 Node* context, Node* arg1, Node* arg2, | 464 Node* context, Node* arg1, Node* arg2, |
| 460 Node* arg3, Node* arg4, Node* arg5) { | 465 Node* arg3, Node* arg4, Node* arg5) { |
| 461 return raw_assembler_->TailCallRuntime5(function_id, arg1, arg2, arg3, arg4, | 466 return raw_assembler()->TailCallRuntime5(function_id, arg1, arg2, arg3, arg4, |
| 462 arg5, context); | 467 arg5, context); |
| 463 } | 468 } |
| 464 | 469 |
| 465 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, | 470 Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function_id, |
| 466 Node* context, Node* arg1, Node* arg2, | 471 Node* context, Node* arg1, Node* arg2, |
| 467 Node* arg3, Node* arg4, Node* arg5, | 472 Node* arg3, Node* arg4, Node* arg5, |
| 468 Node* arg6) { | 473 Node* arg6) { |
| 469 return raw_assembler_->TailCallRuntime6(function_id, arg1, arg2, arg3, arg4, | 474 return raw_assembler()->TailCallRuntime6(function_id, arg1, arg2, arg3, arg4, |
| 470 arg5, arg6, context); | 475 arg5, arg6, context); |
| 471 } | 476 } |
| 472 | 477 |
| 473 Node* CodeAssembler::CallStub(Callable const& callable, Node* context, | 478 Node* CodeAssembler::CallStub(Callable const& callable, Node* context, |
| 474 Node* arg1, size_t result_size) { | 479 Node* arg1, size_t result_size) { |
| 475 Node* target = HeapConstant(callable.code()); | 480 Node* target = HeapConstant(callable.code()); |
| 476 return CallStub(callable.descriptor(), target, context, arg1, result_size); | 481 return CallStub(callable.descriptor(), target, context, arg1, result_size); |
| 477 } | 482 } |
| 478 | 483 |
| 479 Node* CodeAssembler::CallStub(Callable const& callable, Node* context, | 484 Node* CodeAssembler::CallStub(Callable const& callable, Node* context, |
| 480 Node* arg1, Node* arg2, size_t result_size) { | 485 Node* arg1, Node* arg2, size_t result_size) { |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 size_t result_size) { | 750 size_t result_size) { |
| 746 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 751 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
| 747 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), | 752 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), |
| 748 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, | 753 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, |
| 749 MachineType::AnyTagged(), result_size); | 754 MachineType::AnyTagged(), result_size); |
| 750 | 755 |
| 751 Node** args = zone()->NewArray<Node*>(2); | 756 Node** args = zone()->NewArray<Node*>(2); |
| 752 args[0] = arg1; | 757 args[0] = arg1; |
| 753 args[1] = context; | 758 args[1] = context; |
| 754 | 759 |
| 755 return raw_assembler_->TailCallN(call_descriptor, target, args); | 760 return raw_assembler()->TailCallN(call_descriptor, target, args); |
| 756 } | 761 } |
| 757 | 762 |
| 758 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, | 763 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, |
| 759 Node* target, Node* context, Node* arg1, | 764 Node* target, Node* context, Node* arg1, |
| 760 Node* arg2, size_t result_size) { | 765 Node* arg2, size_t result_size) { |
| 761 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 766 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
| 762 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), | 767 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), |
| 763 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, | 768 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, |
| 764 MachineType::AnyTagged(), result_size); | 769 MachineType::AnyTagged(), result_size); |
| 765 | 770 |
| 766 Node** args = zone()->NewArray<Node*>(3); | 771 Node** args = zone()->NewArray<Node*>(3); |
| 767 args[0] = arg1; | 772 args[0] = arg1; |
| 768 args[1] = arg2; | 773 args[1] = arg2; |
| 769 args[2] = context; | 774 args[2] = context; |
| 770 | 775 |
| 771 return raw_assembler_->TailCallN(call_descriptor, target, args); | 776 return raw_assembler()->TailCallN(call_descriptor, target, args); |
| 772 } | 777 } |
| 773 | 778 |
| 774 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, | 779 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, |
| 775 Node* target, Node* context, Node* arg1, | 780 Node* target, Node* context, Node* arg1, |
| 776 Node* arg2, Node* arg3, size_t result_size) { | 781 Node* arg2, Node* arg3, size_t result_size) { |
| 777 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 782 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
| 778 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), | 783 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), |
| 779 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, | 784 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, |
| 780 MachineType::AnyTagged(), result_size); | 785 MachineType::AnyTagged(), result_size); |
| 781 | 786 |
| 782 Node** args = zone()->NewArray<Node*>(4); | 787 Node** args = zone()->NewArray<Node*>(4); |
| 783 args[0] = arg1; | 788 args[0] = arg1; |
| 784 args[1] = arg2; | 789 args[1] = arg2; |
| 785 args[2] = arg3; | 790 args[2] = arg3; |
| 786 args[3] = context; | 791 args[3] = context; |
| 787 | 792 |
| 788 return raw_assembler_->TailCallN(call_descriptor, target, args); | 793 return raw_assembler()->TailCallN(call_descriptor, target, args); |
| 789 } | 794 } |
| 790 | 795 |
| 791 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, | 796 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, |
| 792 Node* target, Node* context, Node* arg1, | 797 Node* target, Node* context, Node* arg1, |
| 793 Node* arg2, Node* arg3, Node* arg4, | 798 Node* arg2, Node* arg3, Node* arg4, |
| 794 size_t result_size) { | 799 size_t result_size) { |
| 795 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 800 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
| 796 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), | 801 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), |
| 797 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, | 802 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, |
| 798 MachineType::AnyTagged(), result_size); | 803 MachineType::AnyTagged(), result_size); |
| 799 | 804 |
| 800 Node** args = zone()->NewArray<Node*>(5); | 805 Node** args = zone()->NewArray<Node*>(5); |
| 801 args[0] = arg1; | 806 args[0] = arg1; |
| 802 args[1] = arg2; | 807 args[1] = arg2; |
| 803 args[2] = arg3; | 808 args[2] = arg3; |
| 804 args[3] = arg4; | 809 args[3] = arg4; |
| 805 args[4] = context; | 810 args[4] = context; |
| 806 | 811 |
| 807 return raw_assembler_->TailCallN(call_descriptor, target, args); | 812 return raw_assembler()->TailCallN(call_descriptor, target, args); |
| 808 } | 813 } |
| 809 | 814 |
| 810 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, | 815 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, |
| 811 Node* target, Node* context, Node* arg1, | 816 Node* target, Node* context, Node* arg1, |
| 812 Node* arg2, Node* arg3, Node* arg4, | 817 Node* arg2, Node* arg3, Node* arg4, |
| 813 Node* arg5, size_t result_size) { | 818 Node* arg5, size_t result_size) { |
| 814 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 819 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
| 815 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), | 820 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), |
| 816 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, | 821 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, |
| 817 MachineType::AnyTagged(), result_size); | 822 MachineType::AnyTagged(), result_size); |
| 818 | 823 |
| 819 Node** args = zone()->NewArray<Node*>(6); | 824 Node** args = zone()->NewArray<Node*>(6); |
| 820 args[0] = arg1; | 825 args[0] = arg1; |
| 821 args[1] = arg2; | 826 args[1] = arg2; |
| 822 args[2] = arg3; | 827 args[2] = arg3; |
| 823 args[3] = arg4; | 828 args[3] = arg4; |
| 824 args[4] = arg5; | 829 args[4] = arg5; |
| 825 args[5] = context; | 830 args[5] = context; |
| 826 | 831 |
| 827 return raw_assembler_->TailCallN(call_descriptor, target, args); | 832 return raw_assembler()->TailCallN(call_descriptor, target, args); |
| 828 } | 833 } |
| 829 | 834 |
| 830 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, | 835 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, |
| 831 Node* target, Node* context, Node* arg1, | 836 Node* target, Node* context, Node* arg1, |
| 832 Node* arg2, Node* arg3, Node* arg4, | 837 Node* arg2, Node* arg3, Node* arg4, |
| 833 Node* arg5, Node* arg6, size_t result_size) { | 838 Node* arg5, Node* arg6, size_t result_size) { |
| 834 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 839 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
| 835 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), | 840 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), |
| 836 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, | 841 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, |
| 837 MachineType::AnyTagged(), result_size); | 842 MachineType::AnyTagged(), result_size); |
| 838 | 843 |
| 839 Node** args = zone()->NewArray<Node*>(7); | 844 Node** args = zone()->NewArray<Node*>(7); |
| 840 args[0] = arg1; | 845 args[0] = arg1; |
| 841 args[1] = arg2; | 846 args[1] = arg2; |
| 842 args[2] = arg3; | 847 args[2] = arg3; |
| 843 args[3] = arg4; | 848 args[3] = arg4; |
| 844 args[4] = arg5; | 849 args[4] = arg5; |
| 845 args[5] = arg6; | 850 args[5] = arg6; |
| 846 args[6] = context; | 851 args[6] = context; |
| 847 | 852 |
| 848 return raw_assembler_->TailCallN(call_descriptor, target, args); | 853 return raw_assembler()->TailCallN(call_descriptor, target, args); |
| 849 } | 854 } |
| 850 | 855 |
| 851 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, | 856 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, |
| 852 Node* target, Node* context, const Arg& arg1, | 857 Node* target, Node* context, const Arg& arg1, |
| 853 const Arg& arg2, const Arg& arg3, | 858 const Arg& arg2, const Arg& arg3, |
| 854 const Arg& arg4, size_t result_size) { | 859 const Arg& arg4, size_t result_size) { |
| 855 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 860 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
| 856 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), | 861 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), |
| 857 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, | 862 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, |
| 858 MachineType::AnyTagged(), result_size); | 863 MachineType::AnyTagged(), result_size); |
| 859 | 864 |
| 860 const int kArgsCount = 5; | 865 const int kArgsCount = 5; |
| 861 Node** args = zone()->NewArray<Node*>(kArgsCount); | 866 Node** args = zone()->NewArray<Node*>(kArgsCount); |
| 862 DCHECK((std::fill(&args[0], &args[kArgsCount], nullptr), true)); | 867 DCHECK((std::fill(&args[0], &args[kArgsCount], nullptr), true)); |
| 863 args[arg1.index] = arg1.value; | 868 args[arg1.index] = arg1.value; |
| 864 args[arg2.index] = arg2.value; | 869 args[arg2.index] = arg2.value; |
| 865 args[arg3.index] = arg3.value; | 870 args[arg3.index] = arg3.value; |
| 866 args[arg4.index] = arg4.value; | 871 args[arg4.index] = arg4.value; |
| 867 args[kArgsCount - 1] = context; | 872 args[kArgsCount - 1] = context; |
| 868 DCHECK_EQ(0, std::count(&args[0], &args[kArgsCount], nullptr)); | 873 DCHECK_EQ(0, std::count(&args[0], &args[kArgsCount], nullptr)); |
| 869 | 874 |
| 870 return raw_assembler_->TailCallN(call_descriptor, target, args); | 875 return raw_assembler()->TailCallN(call_descriptor, target, args); |
| 871 } | 876 } |
| 872 | 877 |
| 873 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, | 878 Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, |
| 874 Node* target, Node* context, const Arg& arg1, | 879 Node* target, Node* context, const Arg& arg1, |
| 875 const Arg& arg2, const Arg& arg3, | 880 const Arg& arg2, const Arg& arg3, |
| 876 const Arg& arg4, const Arg& arg5, | 881 const Arg& arg4, const Arg& arg5, |
| 877 size_t result_size) { | 882 size_t result_size) { |
| 878 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( | 883 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
| 879 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), | 884 isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), |
| 880 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, | 885 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, |
| 881 MachineType::AnyTagged(), result_size); | 886 MachineType::AnyTagged(), result_size); |
| 882 | 887 |
| 883 const int kArgsCount = 6; | 888 const int kArgsCount = 6; |
| 884 Node** args = zone()->NewArray<Node*>(kArgsCount); | 889 Node** args = zone()->NewArray<Node*>(kArgsCount); |
| 885 DCHECK((std::fill(&args[0], &args[kArgsCount], nullptr), true)); | 890 DCHECK((std::fill(&args[0], &args[kArgsCount], nullptr), true)); |
| 886 args[arg1.index] = arg1.value; | 891 args[arg1.index] = arg1.value; |
| 887 args[arg2.index] = arg2.value; | 892 args[arg2.index] = arg2.value; |
| 888 args[arg3.index] = arg3.value; | 893 args[arg3.index] = arg3.value; |
| 889 args[arg4.index] = arg4.value; | 894 args[arg4.index] = arg4.value; |
| 890 args[arg5.index] = arg5.value; | 895 args[arg5.index] = arg5.value; |
| 891 args[kArgsCount - 1] = context; | 896 args[kArgsCount - 1] = context; |
| 892 DCHECK_EQ(0, std::count(&args[0], &args[kArgsCount], nullptr)); | 897 DCHECK_EQ(0, std::count(&args[0], &args[kArgsCount], nullptr)); |
| 893 | 898 |
| 894 return raw_assembler_->TailCallN(call_descriptor, target, args); | 899 return raw_assembler()->TailCallN(call_descriptor, target, args); |
| 895 } | 900 } |
| 896 | 901 |
| 897 Node* CodeAssembler::TailCallBytecodeDispatch( | 902 Node* CodeAssembler::TailCallBytecodeDispatch( |
| 898 const CallInterfaceDescriptor& interface_descriptor, | 903 const CallInterfaceDescriptor& interface_descriptor, |
| 899 Node* code_target_address, Node** args) { | 904 Node* code_target_address, Node** args) { |
| 900 CallDescriptor* descriptor = Linkage::GetBytecodeDispatchCallDescriptor( | 905 CallDescriptor* descriptor = Linkage::GetBytecodeDispatchCallDescriptor( |
| 901 isolate(), zone(), interface_descriptor, | 906 isolate(), zone(), interface_descriptor, |
| 902 interface_descriptor.GetStackParameterCount()); | 907 interface_descriptor.GetStackParameterCount()); |
| 903 return raw_assembler_->TailCallN(descriptor, code_target_address, args); | 908 return raw_assembler()->TailCallN(descriptor, code_target_address, args); |
| 904 } | 909 } |
| 905 | 910 |
| 906 Node* CodeAssembler::CallJS(Callable const& callable, Node* context, | 911 Node* CodeAssembler::CallJS(Callable const& callable, Node* context, |
| 907 Node* function, Node* receiver, | 912 Node* function, Node* receiver, |
| 908 size_t result_size) { | 913 size_t result_size) { |
| 909 const int argc = 0; | 914 const int argc = 0; |
| 910 Node* target = HeapConstant(callable.code()); | 915 Node* target = HeapConstant(callable.code()); |
| 911 | 916 |
| 912 Node** args = zone()->NewArray<Node*>(argc + 4); | 917 Node** args = zone()->NewArray<Node*>(argc + 4); |
| 913 args[0] = function; | 918 args[0] = function; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 966 args[5] = arg3; | 971 args[5] = arg3; |
| 967 args[6] = context; | 972 args[6] = context; |
| 968 | 973 |
| 969 return CallStubN(callable.descriptor(), argc + 1, target, args, result_size); | 974 return CallStubN(callable.descriptor(), argc + 1, target, args, result_size); |
| 970 } | 975 } |
| 971 | 976 |
| 972 Node* CodeAssembler::CallCFunction2(MachineType return_type, | 977 Node* CodeAssembler::CallCFunction2(MachineType return_type, |
| 973 MachineType arg0_type, | 978 MachineType arg0_type, |
| 974 MachineType arg1_type, Node* function, | 979 MachineType arg1_type, Node* function, |
| 975 Node* arg0, Node* arg1) { | 980 Node* arg0, Node* arg1) { |
| 976 return raw_assembler_->CallCFunction2(return_type, arg0_type, arg1_type, | 981 return raw_assembler()->CallCFunction2(return_type, arg0_type, arg1_type, |
| 977 function, arg0, arg1); | 982 function, arg0, arg1); |
| 978 } | 983 } |
| 979 | 984 |
| 980 void CodeAssembler::Goto(CodeAssembler::Label* label) { | 985 void CodeAssembler::Goto(CodeAssembler::Label* label) { |
| 981 label->MergeVariables(); | 986 label->MergeVariables(); |
| 982 raw_assembler_->Goto(label->label_); | 987 raw_assembler()->Goto(label->label_); |
| 983 } | 988 } |
| 984 | 989 |
| 985 void CodeAssembler::GotoIf(Node* condition, Label* true_label) { | 990 void CodeAssembler::GotoIf(Node* condition, Label* true_label) { |
| 986 Label false_label(this); | 991 Label false_label(this); |
| 987 Branch(condition, true_label, &false_label); | 992 Branch(condition, true_label, &false_label); |
| 988 Bind(&false_label); | 993 Bind(&false_label); |
| 989 } | 994 } |
| 990 | 995 |
| 991 void CodeAssembler::GotoUnless(Node* condition, Label* false_label) { | 996 void CodeAssembler::GotoUnless(Node* condition, Label* false_label) { |
| 992 Label true_label(this); | 997 Label true_label(this); |
| 993 Branch(condition, &true_label, false_label); | 998 Branch(condition, &true_label, false_label); |
| 994 Bind(&true_label); | 999 Bind(&true_label); |
| 995 } | 1000 } |
| 996 | 1001 |
| 997 void CodeAssembler::Branch(Node* condition, CodeAssembler::Label* true_label, | 1002 void CodeAssembler::Branch(Node* condition, CodeAssembler::Label* true_label, |
| 998 CodeAssembler::Label* false_label) { | 1003 CodeAssembler::Label* false_label) { |
| 999 true_label->MergeVariables(); | 1004 true_label->MergeVariables(); |
| 1000 false_label->MergeVariables(); | 1005 false_label->MergeVariables(); |
| 1001 return raw_assembler_->Branch(condition, true_label->label_, | 1006 return raw_assembler()->Branch(condition, true_label->label_, |
| 1002 false_label->label_); | 1007 false_label->label_); |
| 1003 } | 1008 } |
| 1004 | 1009 |
| 1005 void CodeAssembler::Switch(Node* index, Label* default_label, | 1010 void CodeAssembler::Switch(Node* index, Label* default_label, |
| 1006 const int32_t* case_values, Label** case_labels, | 1011 const int32_t* case_values, Label** case_labels, |
| 1007 size_t case_count) { | 1012 size_t case_count) { |
| 1008 RawMachineLabel** labels = | 1013 RawMachineLabel** labels = |
| 1009 new (zone()->New(sizeof(RawMachineLabel*) * case_count)) | 1014 new (zone()->New(sizeof(RawMachineLabel*) * case_count)) |
| 1010 RawMachineLabel*[case_count]; | 1015 RawMachineLabel*[case_count]; |
| 1011 for (size_t i = 0; i < case_count; ++i) { | 1016 for (size_t i = 0; i < case_count; ++i) { |
| 1012 labels[i] = case_labels[i]->label_; | 1017 labels[i] = case_labels[i]->label_; |
| 1013 case_labels[i]->MergeVariables(); | 1018 case_labels[i]->MergeVariables(); |
| 1014 default_label->MergeVariables(); | 1019 default_label->MergeVariables(); |
| 1015 } | 1020 } |
| 1016 return raw_assembler_->Switch(index, default_label->label_, case_values, | 1021 return raw_assembler()->Switch(index, default_label->label_, case_values, |
| 1017 labels, case_count); | 1022 labels, case_count); |
| 1018 } | 1023 } |
| 1019 | 1024 |
| 1020 Node* CodeAssembler::Select(Node* condition, Node* true_value, | 1025 Node* CodeAssembler::Select(Node* condition, Node* true_value, |
| 1021 Node* false_value, MachineRepresentation rep) { | 1026 Node* false_value, MachineRepresentation rep) { |
| 1022 Variable value(this, rep); | 1027 Variable value(this, rep); |
| 1023 Label vtrue(this), vfalse(this), end(this); | 1028 Label vtrue(this), vfalse(this), end(this); |
| 1024 Branch(condition, &vtrue, &vfalse); | 1029 Branch(condition, &vtrue, &vfalse); |
| 1025 | 1030 |
| 1026 Bind(&vtrue); | 1031 Bind(&vtrue); |
| 1027 { | 1032 { |
| 1028 value.Bind(true_value); | 1033 value.Bind(true_value); |
| 1029 Goto(&end); | 1034 Goto(&end); |
| 1030 } | 1035 } |
| 1031 Bind(&vfalse); | 1036 Bind(&vfalse); |
| 1032 { | 1037 { |
| 1033 value.Bind(false_value); | 1038 value.Bind(false_value); |
| 1034 Goto(&end); | 1039 Goto(&end); |
| 1035 } | 1040 } |
| 1036 | 1041 |
| 1037 Bind(&end); | 1042 Bind(&end); |
| 1038 return value.value(); | 1043 return value.value(); |
| 1039 } | 1044 } |
| 1040 | 1045 |
| 1041 // RawMachineAssembler delegate helpers: | 1046 // RawMachineAssembler delegate helpers: |
| 1042 Isolate* CodeAssembler::isolate() const { return raw_assembler_->isolate(); } | 1047 Isolate* CodeAssembler::isolate() const { return raw_assembler()->isolate(); } |
| 1043 | 1048 |
| 1044 Factory* CodeAssembler::factory() const { return isolate()->factory(); } | 1049 Factory* CodeAssembler::factory() const { return isolate()->factory(); } |
| 1045 | 1050 |
| 1046 Zone* CodeAssembler::zone() const { return raw_assembler_->zone(); } | 1051 Zone* CodeAssembler::zone() const { return raw_assembler()->zone(); } |
| 1052 |
| 1053 RawMachineAssembler* CodeAssembler::raw_assembler() const { |
| 1054 return state_->raw_assembler_.get(); |
| 1055 } |
| 1047 | 1056 |
| 1048 // The core implementation of Variable is stored through an indirection so | 1057 // The core implementation of Variable is stored through an indirection so |
| 1049 // that it can outlive the often block-scoped Variable declarations. This is | 1058 // that it can outlive the often block-scoped Variable declarations. This is |
| 1050 // needed to ensure that variable binding and merging through phis can | 1059 // needed to ensure that variable binding and merging through phis can |
| 1051 // properly be verified. | 1060 // properly be verified. |
| 1052 class CodeAssembler::Variable::Impl : public ZoneObject { | 1061 class CodeAssembler::Variable::Impl : public ZoneObject { |
| 1053 public: | 1062 public: |
| 1054 explicit Impl(MachineRepresentation rep) : value_(nullptr), rep_(rep) {} | 1063 explicit Impl(MachineRepresentation rep) : value_(nullptr), rep_(rep) {} |
| 1055 Node* value_; | 1064 Node* value_; |
| 1056 MachineRepresentation rep_; | 1065 MachineRepresentation rep_; |
| 1057 }; | 1066 }; |
| 1058 | 1067 |
| 1059 CodeAssembler::Variable::Variable(CodeAssembler* assembler, | 1068 CodeAssembler::Variable::Variable(CodeAssembler* assembler, |
| 1060 MachineRepresentation rep) | 1069 MachineRepresentation rep) |
| 1061 : impl_(new (assembler->zone()) Impl(rep)), assembler_(assembler) { | 1070 : impl_(new (assembler->zone()) Impl(rep)), state_(assembler->state_) { |
| 1062 assembler->variables_.insert(impl_); | 1071 state_->variables_.insert(impl_); |
| 1063 } | 1072 } |
| 1064 | 1073 |
| 1065 CodeAssembler::Variable::~Variable() { assembler_->variables_.erase(impl_); } | 1074 CodeAssembler::Variable::~Variable() { state_->variables_.erase(impl_); } |
| 1066 | 1075 |
| 1067 void CodeAssembler::Variable::Bind(Node* value) { impl_->value_ = value; } | 1076 void CodeAssembler::Variable::Bind(Node* value) { impl_->value_ = value; } |
| 1068 | 1077 |
| 1069 Node* CodeAssembler::Variable::value() const { | 1078 Node* CodeAssembler::Variable::value() const { |
| 1070 DCHECK_NOT_NULL(impl_->value_); | 1079 DCHECK_NOT_NULL(impl_->value_); |
| 1071 return impl_->value_; | 1080 return impl_->value_; |
| 1072 } | 1081 } |
| 1073 | 1082 |
| 1074 MachineRepresentation CodeAssembler::Variable::rep() const { | 1083 MachineRepresentation CodeAssembler::Variable::rep() const { |
| 1075 return impl_->rep_; | 1084 return impl_->rep_; |
| 1076 } | 1085 } |
| 1077 | 1086 |
| 1078 bool CodeAssembler::Variable::IsBound() const { | 1087 bool CodeAssembler::Variable::IsBound() const { |
| 1079 return impl_->value_ != nullptr; | 1088 return impl_->value_ != nullptr; |
| 1080 } | 1089 } |
| 1081 | 1090 |
| 1082 CodeAssembler::Label::Label(CodeAssembler* assembler, size_t vars_count, | 1091 CodeAssembler::Label::Label(CodeAssembler* assembler, size_t vars_count, |
| 1083 Variable** vars, CodeAssembler::Label::Type type) | 1092 Variable** vars, CodeAssembler::Label::Type type) |
| 1084 : bound_(false), merge_count_(0), assembler_(assembler), label_(nullptr) { | 1093 : bound_(false), |
| 1094 merge_count_(0), |
| 1095 state_(assembler->state_), |
| 1096 label_(nullptr) { |
| 1085 void* buffer = assembler->zone()->New(sizeof(RawMachineLabel)); | 1097 void* buffer = assembler->zone()->New(sizeof(RawMachineLabel)); |
| 1086 label_ = new (buffer) | 1098 label_ = new (buffer) |
| 1087 RawMachineLabel(type == kDeferred ? RawMachineLabel::kDeferred | 1099 RawMachineLabel(type == kDeferred ? RawMachineLabel::kDeferred |
| 1088 : RawMachineLabel::kNonDeferred); | 1100 : RawMachineLabel::kNonDeferred); |
| 1089 for (size_t i = 0; i < vars_count; ++i) { | 1101 for (size_t i = 0; i < vars_count; ++i) { |
| 1090 variable_phis_[vars[i]->impl_] = nullptr; | 1102 variable_phis_[vars[i]->impl_] = nullptr; |
| 1091 } | 1103 } |
| 1092 } | 1104 } |
| 1093 | 1105 |
| 1094 void CodeAssembler::Label::MergeVariables() { | 1106 void CodeAssembler::Label::MergeVariables() { |
| 1095 ++merge_count_; | 1107 ++merge_count_; |
| 1096 for (auto var : assembler_->variables_) { | 1108 for (auto var : state_->variables_) { |
| 1097 size_t count = 0; | 1109 size_t count = 0; |
| 1098 Node* node = var->value_; | 1110 Node* node = var->value_; |
| 1099 if (node != nullptr) { | 1111 if (node != nullptr) { |
| 1100 auto i = variable_merges_.find(var); | 1112 auto i = variable_merges_.find(var); |
| 1101 if (i != variable_merges_.end()) { | 1113 if (i != variable_merges_.end()) { |
| 1102 i->second.push_back(node); | 1114 i->second.push_back(node); |
| 1103 count = i->second.size(); | 1115 count = i->second.size(); |
| 1104 } else { | 1116 } else { |
| 1105 count = 1; | 1117 count = 1; |
| 1106 variable_merges_[var] = std::vector<Node*>(1, node); | 1118 variable_merges_[var] = std::vector<Node*>(1, node); |
| 1107 } | 1119 } |
| 1108 } | 1120 } |
| 1109 // If the following asserts, then you've jumped to a label without a bound | 1121 // If the following asserts, then you've jumped to a label without a bound |
| 1110 // variable along that path that expects to merge its value into a phi. | 1122 // variable along that path that expects to merge its value into a phi. |
| 1111 DCHECK(variable_phis_.find(var) == variable_phis_.end() || | 1123 DCHECK(variable_phis_.find(var) == variable_phis_.end() || |
| 1112 count == merge_count_); | 1124 count == merge_count_); |
| 1113 USE(count); | 1125 USE(count); |
| 1114 | 1126 |
| 1115 // If the label is already bound, we already know the set of variables to | 1127 // If the label is already bound, we already know the set of variables to |
| 1116 // merge and phi nodes have already been created. | 1128 // merge and phi nodes have already been created. |
| 1117 if (bound_) { | 1129 if (bound_) { |
| 1118 auto phi = variable_phis_.find(var); | 1130 auto phi = variable_phis_.find(var); |
| 1119 if (phi != variable_phis_.end()) { | 1131 if (phi != variable_phis_.end()) { |
| 1120 DCHECK_NOT_NULL(phi->second); | 1132 DCHECK_NOT_NULL(phi->second); |
| 1121 assembler_->raw_assembler_->AppendPhiInput(phi->second, node); | 1133 state_->raw_assembler_->AppendPhiInput(phi->second, node); |
| 1122 } else { | 1134 } else { |
| 1123 auto i = variable_merges_.find(var); | 1135 auto i = variable_merges_.find(var); |
| 1124 if (i != variable_merges_.end()) { | 1136 if (i != variable_merges_.end()) { |
| 1125 // If the following assert fires, then you've declared a variable that | 1137 // If the following assert fires, then you've declared a variable that |
| 1126 // has the same bound value along all paths up until the point you | 1138 // has the same bound value along all paths up until the point you |
| 1127 // bound this label, but then later merged a path with a new value for | 1139 // bound this label, but then later merged a path with a new value for |
| 1128 // the variable after the label bind (it's not possible to add phis to | 1140 // the variable after the label bind (it's not possible to add phis to |
| 1129 // the bound label after the fact, just make sure to list the variable | 1141 // the bound label after the fact, just make sure to list the variable |
| 1130 // in the label's constructor's list of merged variables). | 1142 // in the label's constructor's list of merged variables). |
| 1131 DCHECK(find_if(i->second.begin(), i->second.end(), | 1143 DCHECK(find_if(i->second.begin(), i->second.end(), |
| 1132 [node](Node* e) -> bool { return node != e; }) == | 1144 [node](Node* e) -> bool { return node != e; }) == |
| 1133 i->second.end()); | 1145 i->second.end()); |
| 1134 } | 1146 } |
| 1135 } | 1147 } |
| 1136 } | 1148 } |
| 1137 } | 1149 } |
| 1138 } | 1150 } |
| 1139 | 1151 |
| 1140 void CodeAssembler::Label::Bind() { | 1152 void CodeAssembler::Label::Bind() { |
| 1141 DCHECK(!bound_); | 1153 DCHECK(!bound_); |
| 1142 assembler_->raw_assembler_->Bind(label_); | 1154 state_->raw_assembler_->Bind(label_); |
| 1143 | 1155 |
| 1144 // Make sure that all variables that have changed along any path up to this | 1156 // Make sure that all variables that have changed along any path up to this |
| 1145 // point are marked as merge variables. | 1157 // point are marked as merge variables. |
| 1146 for (auto var : assembler_->variables_) { | 1158 for (auto var : state_->variables_) { |
| 1147 Node* shared_value = nullptr; | 1159 Node* shared_value = nullptr; |
| 1148 auto i = variable_merges_.find(var); | 1160 auto i = variable_merges_.find(var); |
| 1149 if (i != variable_merges_.end()) { | 1161 if (i != variable_merges_.end()) { |
| 1150 for (auto value : i->second) { | 1162 for (auto value : i->second) { |
| 1151 DCHECK(value != nullptr); | 1163 DCHECK(value != nullptr); |
| 1152 if (value != shared_value) { | 1164 if (value != shared_value) { |
| 1153 if (shared_value == nullptr) { | 1165 if (shared_value == nullptr) { |
| 1154 shared_value = value; | 1166 shared_value = value; |
| 1155 } else { | 1167 } else { |
| 1156 variable_phis_[var] = nullptr; | 1168 variable_phis_[var] = nullptr; |
| 1157 } | 1169 } |
| 1158 } | 1170 } |
| 1159 } | 1171 } |
| 1160 } | 1172 } |
| 1161 } | 1173 } |
| 1162 | 1174 |
| 1163 for (auto var : variable_phis_) { | 1175 for (auto var : variable_phis_) { |
| 1164 CodeAssembler::Variable::Impl* var_impl = var.first; | 1176 CodeAssembler::Variable::Impl* var_impl = var.first; |
| 1165 auto i = variable_merges_.find(var_impl); | 1177 auto i = variable_merges_.find(var_impl); |
| 1166 // If the following assert fires, then a variable that has been marked as | 1178 // If the following assert fires, then a variable that has been marked as |
| 1167 // being merged at the label--either by explicitly marking it so in the | 1179 // being merged at the label--either by explicitly marking it so in the |
| 1168 // label constructor or by having seen different bound values at branches | 1180 // label constructor or by having seen different bound values at branches |
| 1169 // into the label--doesn't have a bound value along all of the paths that | 1181 // into the label--doesn't have a bound value along all of the paths that |
| 1170 // have been merged into the label up to this point. | 1182 // have been merged into the label up to this point. |
| 1171 DCHECK(i != variable_merges_.end() && i->second.size() == merge_count_); | 1183 DCHECK(i != variable_merges_.end() && i->second.size() == merge_count_); |
| 1172 Node* phi = assembler_->raw_assembler_->Phi( | 1184 Node* phi = state_->raw_assembler_->Phi( |
| 1173 var.first->rep_, static_cast<int>(merge_count_), &(i->second[0])); | 1185 var.first->rep_, static_cast<int>(merge_count_), &(i->second[0])); |
| 1174 variable_phis_[var_impl] = phi; | 1186 variable_phis_[var_impl] = phi; |
| 1175 } | 1187 } |
| 1176 | 1188 |
| 1177 // Bind all variables to a merge phi, the common value along all paths or | 1189 // Bind all variables to a merge phi, the common value along all paths or |
| 1178 // null. | 1190 // null. |
| 1179 for (auto var : assembler_->variables_) { | 1191 for (auto var : state_->variables_) { |
| 1180 auto i = variable_phis_.find(var); | 1192 auto i = variable_phis_.find(var); |
| 1181 if (i != variable_phis_.end()) { | 1193 if (i != variable_phis_.end()) { |
| 1182 var->value_ = i->second; | 1194 var->value_ = i->second; |
| 1183 } else { | 1195 } else { |
| 1184 auto j = variable_merges_.find(var); | 1196 auto j = variable_merges_.find(var); |
| 1185 if (j != variable_merges_.end() && j->second.size() == merge_count_) { | 1197 if (j != variable_merges_.end() && j->second.size() == merge_count_) { |
| 1186 var->value_ = j->second.back(); | 1198 var->value_ = j->second.back(); |
| 1187 } else { | 1199 } else { |
| 1188 var->value_ = nullptr; | 1200 var->value_ = nullptr; |
| 1189 } | 1201 } |
| 1190 } | 1202 } |
| 1191 } | 1203 } |
| 1192 | 1204 |
| 1193 bound_ = true; | 1205 bound_ = true; |
| 1194 } | 1206 } |
| 1195 | 1207 |
| 1196 } // namespace compiler | 1208 } // namespace compiler |
| 1197 } // namespace internal | 1209 } // namespace internal |
| 1198 } // namespace v8 | 1210 } // namespace v8 |
| OLD | NEW |