| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/code-factory.h" | 5 #include "src/code-factory.h" |
| 6 #include "src/code-stubs.h" | 6 #include "src/code-stubs.h" |
| 7 #include "src/compiler/common-operator.h" | 7 #include "src/compiler/common-operator.h" |
| 8 #include "src/compiler/js-generic-lowering.h" | 8 #include "src/compiler/js-generic-lowering.h" |
| 9 #include "src/compiler/machine-operator.h" | 9 #include "src/compiler/machine-operator.h" |
| 10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| 11 #include "src/compiler/node-properties.h" | 11 #include "src/compiler/node-properties.h" |
| 12 #include "src/compiler/operator-properties.h" | 12 #include "src/compiler/operator-properties.h" |
| 13 #include "src/unique.h" | 13 #include "src/unique.h" |
| 14 | 14 |
| 15 namespace v8 { | 15 namespace v8 { |
| 16 namespace internal { | 16 namespace internal { |
| 17 namespace compiler { | 17 namespace compiler { |
| 18 | 18 |
| 19 JSGenericLowering::JSGenericLowering(bool is_typing_enabled, JSGraph* jsgraph) | 19 JSGenericLowering::JSGenericLowering(bool is_typing_enabled, JSGraph* jsgraph) |
| 20 : is_typing_enabled_(is_typing_enabled), jsgraph_(jsgraph) {} | 20 : is_typing_enabled_(is_typing_enabled), jsgraph_(jsgraph) {} |
| 21 | 21 |
| 22 | 22 |
| 23 void JSGenericLowering::PatchOperator(Node* node, const Operator* op) { | |
| 24 node->set_op(op); | |
| 25 } | |
| 26 | |
| 27 | |
| 28 void JSGenericLowering::PatchInsertInput(Node* node, int index, Node* input) { | |
| 29 node->InsertInput(zone(), index, input); | |
| 30 } | |
| 31 | |
| 32 | |
| 33 Reduction JSGenericLowering::Reduce(Node* node) { | 23 Reduction JSGenericLowering::Reduce(Node* node) { |
| 34 switch (node->opcode()) { | 24 switch (node->opcode()) { |
| 35 #define DECLARE_CASE(x) \ | 25 #define DECLARE_CASE(x) \ |
| 36 case IrOpcode::k##x: \ | 26 case IrOpcode::k##x: \ |
| 37 Lower##x(node); \ | 27 Lower##x(node); \ |
| 38 break; | 28 break; |
| 39 JS_OP_LIST(DECLARE_CASE) | 29 JS_OP_LIST(DECLARE_CASE) |
| 40 #undef DECLARE_CASE | 30 #undef DECLARE_CASE |
| 41 case IrOpcode::kBranch: | 31 case IrOpcode::kBranch: |
| 42 // TODO(mstarzinger): If typing is enabled then simplified lowering will | 32 // TODO(mstarzinger): If typing is enabled then simplified lowering will |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 | 184 |
| 195 // Finally patch the original node to select a boolean. | 185 // Finally patch the original node to select a boolean. |
| 196 NodeProperties::ReplaceWithValue(node, node, compare); | 186 NodeProperties::ReplaceWithValue(node, node, compare); |
| 197 // TODO(mstarzinger): Just a work-around because SelectLowering might | 187 // TODO(mstarzinger): Just a work-around because SelectLowering might |
| 198 // otherwise introduce a Phi without any uses, making Scheduler unhappy. | 188 // otherwise introduce a Phi without any uses, making Scheduler unhappy. |
| 199 if (node->UseCount() == 0) return; | 189 if (node->UseCount() == 0) return; |
| 200 node->TrimInputCount(3); | 190 node->TrimInputCount(3); |
| 201 node->ReplaceInput(0, booleanize); | 191 node->ReplaceInput(0, booleanize); |
| 202 node->ReplaceInput(1, true_value); | 192 node->ReplaceInput(1, true_value); |
| 203 node->ReplaceInput(2, false_value); | 193 node->ReplaceInput(2, false_value); |
| 204 PatchOperator(node, common()->Select(kMachAnyTagged)); | 194 node->set_op(common()->Select(kMachAnyTagged)); |
| 205 } | 195 } |
| 206 | 196 |
| 207 | 197 |
| 208 void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable, | 198 void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable, |
| 209 CallDescriptor::Flags flags) { | 199 CallDescriptor::Flags flags) { |
| 210 Operator::Properties properties = node->op()->properties(); | 200 Operator::Properties properties = node->op()->properties(); |
| 211 CallDescriptor* desc = | 201 CallDescriptor* desc = |
| 212 Linkage::GetStubCallDescriptor(isolate(), zone(), callable.descriptor(), | 202 Linkage::GetStubCallDescriptor(isolate(), zone(), callable.descriptor(), |
| 213 0, flags | FlagsForNode(node), properties); | 203 0, flags | FlagsForNode(node), properties); |
| 214 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | 204 Node* stub_code = jsgraph()->HeapConstant(callable.code()); |
| 215 PatchInsertInput(node, 0, stub_code); | 205 node->InsertInput(zone(), 0, stub_code); |
| 216 PatchOperator(node, common()->Call(desc)); | 206 node->set_op(common()->Call(desc)); |
| 217 } | 207 } |
| 218 | 208 |
| 219 | 209 |
| 220 void JSGenericLowering::ReplaceWithBuiltinCall(Node* node, | 210 void JSGenericLowering::ReplaceWithBuiltinCall(Node* node, |
| 221 Builtins::JavaScript id, | 211 Builtins::JavaScript id, |
| 222 int nargs) { | 212 int nargs) { |
| 223 Operator::Properties properties = node->op()->properties(); | 213 Operator::Properties properties = node->op()->properties(); |
| 224 Callable callable = | 214 Callable callable = |
| 225 CodeFactory::CallFunction(isolate(), nargs - 1, NO_CALL_FUNCTION_FLAGS); | 215 CodeFactory::CallFunction(isolate(), nargs - 1, NO_CALL_FUNCTION_FLAGS); |
| 226 CallDescriptor* desc = | 216 CallDescriptor* desc = |
| 227 Linkage::GetStubCallDescriptor(isolate(), zone(), callable.descriptor(), | 217 Linkage::GetStubCallDescriptor(isolate(), zone(), callable.descriptor(), |
| 228 nargs, FlagsForNode(node), properties); | 218 nargs, FlagsForNode(node), properties); |
| 229 Node* global_object = graph()->NewNode( | 219 Node* global_object = graph()->NewNode( |
| 230 machine()->Load(kMachAnyTagged), NodeProperties::GetContextInput(node), | 220 machine()->Load(kMachAnyTagged), NodeProperties::GetContextInput(node), |
| 231 jsgraph()->IntPtrConstant( | 221 jsgraph()->IntPtrConstant( |
| 232 Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)), | 222 Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)), |
| 233 NodeProperties::GetEffectInput(node), graph()->start()); | 223 NodeProperties::GetEffectInput(node), graph()->start()); |
| 234 Node* builtins_object = graph()->NewNode( | 224 Node* builtins_object = graph()->NewNode( |
| 235 machine()->Load(kMachAnyTagged), global_object, | 225 machine()->Load(kMachAnyTagged), global_object, |
| 236 jsgraph()->IntPtrConstant(GlobalObject::kBuiltinsOffset - kHeapObjectTag), | 226 jsgraph()->IntPtrConstant(GlobalObject::kBuiltinsOffset - kHeapObjectTag), |
| 237 NodeProperties::GetEffectInput(node), graph()->start()); | 227 NodeProperties::GetEffectInput(node), graph()->start()); |
| 238 Node* function = graph()->NewNode( | 228 Node* function = graph()->NewNode( |
| 239 machine()->Load(kMachAnyTagged), builtins_object, | 229 machine()->Load(kMachAnyTagged), builtins_object, |
| 240 jsgraph()->IntPtrConstant(JSBuiltinsObject::OffsetOfFunctionWithId(id) - | 230 jsgraph()->IntPtrConstant(JSBuiltinsObject::OffsetOfFunctionWithId(id) - |
| 241 kHeapObjectTag), | 231 kHeapObjectTag), |
| 242 NodeProperties::GetEffectInput(node), graph()->start()); | 232 NodeProperties::GetEffectInput(node), graph()->start()); |
| 243 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | 233 Node* stub_code = jsgraph()->HeapConstant(callable.code()); |
| 244 PatchInsertInput(node, 0, stub_code); | 234 node->InsertInput(zone(), 0, stub_code); |
| 245 PatchInsertInput(node, 1, function); | 235 node->InsertInput(zone(), 1, function); |
| 246 PatchOperator(node, common()->Call(desc)); | 236 node->set_op(common()->Call(desc)); |
| 247 } | 237 } |
| 248 | 238 |
| 249 | 239 |
| 250 void JSGenericLowering::ReplaceWithRuntimeCall(Node* node, | 240 void JSGenericLowering::ReplaceWithRuntimeCall(Node* node, |
| 251 Runtime::FunctionId f, | 241 Runtime::FunctionId f, |
| 252 int nargs_override) { | 242 int nargs_override) { |
| 253 Operator::Properties properties = node->op()->properties(); | 243 Operator::Properties properties = node->op()->properties(); |
| 254 const Runtime::Function* fun = Runtime::FunctionForId(f); | 244 const Runtime::Function* fun = Runtime::FunctionForId(f); |
| 255 int nargs = (nargs_override < 0) ? fun->nargs : nargs_override; | 245 int nargs = (nargs_override < 0) ? fun->nargs : nargs_override; |
| 256 CallDescriptor* desc = | 246 CallDescriptor* desc = |
| 257 Linkage::GetRuntimeCallDescriptor(zone(), f, nargs, properties); | 247 Linkage::GetRuntimeCallDescriptor(zone(), f, nargs, properties); |
| 258 Node* ref = jsgraph()->ExternalConstant(ExternalReference(f, isolate())); | 248 Node* ref = jsgraph()->ExternalConstant(ExternalReference(f, isolate())); |
| 259 Node* arity = jsgraph()->Int32Constant(nargs); | 249 Node* arity = jsgraph()->Int32Constant(nargs); |
| 260 PatchInsertInput(node, 0, jsgraph()->CEntryStubConstant(fun->result_size)); | 250 node->InsertInput(zone(), 0, jsgraph()->CEntryStubConstant(fun->result_size)); |
| 261 PatchInsertInput(node, nargs + 1, ref); | 251 node->InsertInput(zone(), nargs + 1, ref); |
| 262 PatchInsertInput(node, nargs + 2, arity); | 252 node->InsertInput(zone(), nargs + 2, arity); |
| 263 PatchOperator(node, common()->Call(desc)); | 253 node->set_op(common()->Call(desc)); |
| 264 } | 254 } |
| 265 | 255 |
| 266 | 256 |
| 267 void JSGenericLowering::LowerJSUnaryNot(Node* node) { | 257 void JSGenericLowering::LowerJSUnaryNot(Node* node) { |
| 268 Callable callable = CodeFactory::ToBoolean( | 258 Callable callable = CodeFactory::ToBoolean( |
| 269 isolate(), ToBooleanStub::RESULT_AS_INVERSE_ODDBALL); | 259 isolate(), ToBooleanStub::RESULT_AS_INVERSE_ODDBALL); |
| 270 ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite); | 260 ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite); |
| 271 } | 261 } |
| 272 | 262 |
| 273 | 263 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 296 | 286 |
| 297 void JSGenericLowering::LowerJSToObject(Node* node) { | 287 void JSGenericLowering::LowerJSToObject(Node* node) { |
| 298 ReplaceWithBuiltinCall(node, Builtins::TO_OBJECT, 1); | 288 ReplaceWithBuiltinCall(node, Builtins::TO_OBJECT, 1); |
| 299 } | 289 } |
| 300 | 290 |
| 301 | 291 |
| 302 void JSGenericLowering::LowerJSLoadProperty(Node* node) { | 292 void JSGenericLowering::LowerJSLoadProperty(Node* node) { |
| 303 const LoadPropertyParameters& p = LoadPropertyParametersOf(node->op()); | 293 const LoadPropertyParameters& p = LoadPropertyParametersOf(node->op()); |
| 304 Callable callable = CodeFactory::KeyedLoadICInOptimizedCode(isolate()); | 294 Callable callable = CodeFactory::KeyedLoadICInOptimizedCode(isolate()); |
| 305 if (FLAG_vector_ics) { | 295 if (FLAG_vector_ics) { |
| 306 PatchInsertInput(node, 2, jsgraph()->SmiConstant(p.feedback().index())); | 296 node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index())); |
| 307 PatchInsertInput(node, 3, jsgraph()->HeapConstant(p.feedback().vector())); | 297 node->InsertInput(zone(), 3, |
| 298 jsgraph()->HeapConstant(p.feedback().vector())); |
| 308 } | 299 } |
| 309 ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite); | 300 ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite); |
| 310 } | 301 } |
| 311 | 302 |
| 312 | 303 |
| 313 void JSGenericLowering::LowerJSLoadNamed(Node* node) { | 304 void JSGenericLowering::LowerJSLoadNamed(Node* node) { |
| 314 const LoadNamedParameters& p = LoadNamedParametersOf(node->op()); | 305 const LoadNamedParameters& p = LoadNamedParametersOf(node->op()); |
| 315 Callable callable = | 306 Callable callable = |
| 316 CodeFactory::LoadICInOptimizedCode(isolate(), p.contextual_mode()); | 307 CodeFactory::LoadICInOptimizedCode(isolate(), p.contextual_mode()); |
| 317 PatchInsertInput(node, 1, jsgraph()->HeapConstant(p.name())); | 308 node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name())); |
| 318 if (FLAG_vector_ics) { | 309 if (FLAG_vector_ics) { |
| 319 PatchInsertInput(node, 2, jsgraph()->SmiConstant(p.feedback().index())); | 310 node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index())); |
| 320 PatchInsertInput(node, 3, jsgraph()->HeapConstant(p.feedback().vector())); | 311 node->InsertInput(zone(), 3, |
| 312 jsgraph()->HeapConstant(p.feedback().vector())); |
| 321 } | 313 } |
| 322 ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite); | 314 ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite); |
| 323 } | 315 } |
| 324 | 316 |
| 325 | 317 |
| 326 void JSGenericLowering::LowerJSStoreProperty(Node* node) { | 318 void JSGenericLowering::LowerJSStoreProperty(Node* node) { |
| 327 LanguageMode language_mode = OpParameter<LanguageMode>(node); | 319 LanguageMode language_mode = OpParameter<LanguageMode>(node); |
| 328 Callable callable = CodeFactory::KeyedStoreIC(isolate(), language_mode); | 320 Callable callable = CodeFactory::KeyedStoreIC(isolate(), language_mode); |
| 329 ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite); | 321 ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite); |
| 330 } | 322 } |
| 331 | 323 |
| 332 | 324 |
| 333 void JSGenericLowering::LowerJSStoreNamed(Node* node) { | 325 void JSGenericLowering::LowerJSStoreNamed(Node* node) { |
| 334 const StoreNamedParameters& p = StoreNamedParametersOf(node->op()); | 326 const StoreNamedParameters& p = StoreNamedParametersOf(node->op()); |
| 335 Callable callable = CodeFactory::StoreIC(isolate(), p.language_mode()); | 327 Callable callable = CodeFactory::StoreIC(isolate(), p.language_mode()); |
| 336 PatchInsertInput(node, 1, jsgraph()->HeapConstant(p.name())); | 328 node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name())); |
| 337 ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite); | 329 ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite); |
| 338 } | 330 } |
| 339 | 331 |
| 340 | 332 |
| 341 void JSGenericLowering::LowerJSDeleteProperty(Node* node) { | 333 void JSGenericLowering::LowerJSDeleteProperty(Node* node) { |
| 342 LanguageMode language_mode = OpParameter<LanguageMode>(node); | 334 LanguageMode language_mode = OpParameter<LanguageMode>(node); |
| 343 ReplaceWithBuiltinCall(node, Builtins::DELETE, 3); | 335 ReplaceWithBuiltinCall(node, Builtins::DELETE, 3); |
| 344 PatchInsertInput(node, 4, jsgraph()->SmiConstant(language_mode)); | 336 node->InsertInput(zone(), 4, jsgraph()->SmiConstant(language_mode)); |
| 345 } | 337 } |
| 346 | 338 |
| 347 | 339 |
| 348 void JSGenericLowering::LowerJSHasProperty(Node* node) { | 340 void JSGenericLowering::LowerJSHasProperty(Node* node) { |
| 349 ReplaceWithBuiltinCall(node, Builtins::IN, 2); | 341 ReplaceWithBuiltinCall(node, Builtins::IN, 2); |
| 350 } | 342 } |
| 351 | 343 |
| 352 | 344 |
| 353 void JSGenericLowering::LowerJSInstanceOf(Node* node) { | 345 void JSGenericLowering::LowerJSInstanceOf(Node* node) { |
| 354 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>( | 346 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>( |
| 355 InstanceofStub::kReturnTrueFalseObject | | 347 InstanceofStub::kReturnTrueFalseObject | |
| 356 InstanceofStub::kArgsInRegisters); | 348 InstanceofStub::kArgsInRegisters); |
| 357 InstanceofStub stub(isolate(), flags); | 349 InstanceofStub stub(isolate(), flags); |
| 358 CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor(); | 350 CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor(); |
| 359 CallDescriptor* desc = Linkage::GetStubCallDescriptor(isolate(), zone(), d, 0, | 351 CallDescriptor* desc = Linkage::GetStubCallDescriptor(isolate(), zone(), d, 0, |
| 360 FlagsForNode(node)); | 352 FlagsForNode(node)); |
| 361 Node* stub_code = jsgraph()->HeapConstant(stub.GetCode()); | 353 Node* stub_code = jsgraph()->HeapConstant(stub.GetCode()); |
| 362 PatchInsertInput(node, 0, stub_code); | 354 node->InsertInput(zone(), 0, stub_code); |
| 363 PatchOperator(node, common()->Call(desc)); | 355 node->set_op(common()->Call(desc)); |
| 364 } | 356 } |
| 365 | 357 |
| 366 | 358 |
| 367 void JSGenericLowering::LowerJSLoadContext(Node* node) { | 359 void JSGenericLowering::LowerJSLoadContext(Node* node) { |
| 368 const ContextAccess& access = ContextAccessOf(node->op()); | 360 const ContextAccess& access = ContextAccessOf(node->op()); |
| 369 for (size_t i = 0; i < access.depth(); ++i) { | 361 for (size_t i = 0; i < access.depth(); ++i) { |
| 370 node->ReplaceInput( | 362 node->ReplaceInput( |
| 371 0, graph()->NewNode(machine()->Load(kMachAnyTagged), | 363 0, graph()->NewNode(machine()->Load(kMachAnyTagged), |
| 372 NodeProperties::GetValueInput(node, 0), | 364 NodeProperties::GetValueInput(node, 0), |
| 373 jsgraph()->Int32Constant( | 365 jsgraph()->Int32Constant( |
| 374 Context::SlotOffset(Context::PREVIOUS_INDEX)), | 366 Context::SlotOffset(Context::PREVIOUS_INDEX)), |
| 375 NodeProperties::GetEffectInput(node), | 367 NodeProperties::GetEffectInput(node), |
| 376 graph()->start())); | 368 graph()->start())); |
| 377 } | 369 } |
| 378 node->ReplaceInput(1, jsgraph()->Int32Constant(Context::SlotOffset( | 370 node->ReplaceInput(1, jsgraph()->Int32Constant(Context::SlotOffset( |
| 379 static_cast<int>(access.index())))); | 371 static_cast<int>(access.index())))); |
| 380 node->AppendInput(zone(), graph()->start()); | 372 node->AppendInput(zone(), graph()->start()); |
| 381 PatchOperator(node, machine()->Load(kMachAnyTagged)); | 373 node->set_op(machine()->Load(kMachAnyTagged)); |
| 382 } | 374 } |
| 383 | 375 |
| 384 | 376 |
| 385 void JSGenericLowering::LowerJSStoreContext(Node* node) { | 377 void JSGenericLowering::LowerJSStoreContext(Node* node) { |
| 386 const ContextAccess& access = ContextAccessOf(node->op()); | 378 const ContextAccess& access = ContextAccessOf(node->op()); |
| 387 for (size_t i = 0; i < access.depth(); ++i) { | 379 for (size_t i = 0; i < access.depth(); ++i) { |
| 388 node->ReplaceInput( | 380 node->ReplaceInput( |
| 389 0, graph()->NewNode(machine()->Load(kMachAnyTagged), | 381 0, graph()->NewNode(machine()->Load(kMachAnyTagged), |
| 390 NodeProperties::GetValueInput(node, 0), | 382 NodeProperties::GetValueInput(node, 0), |
| 391 jsgraph()->Int32Constant( | 383 jsgraph()->Int32Constant( |
| 392 Context::SlotOffset(Context::PREVIOUS_INDEX)), | 384 Context::SlotOffset(Context::PREVIOUS_INDEX)), |
| 393 NodeProperties::GetEffectInput(node), | 385 NodeProperties::GetEffectInput(node), |
| 394 graph()->start())); | 386 graph()->start())); |
| 395 } | 387 } |
| 396 node->ReplaceInput(2, NodeProperties::GetValueInput(node, 1)); | 388 node->ReplaceInput(2, NodeProperties::GetValueInput(node, 1)); |
| 397 node->ReplaceInput(1, jsgraph()->Int32Constant(Context::SlotOffset( | 389 node->ReplaceInput(1, jsgraph()->Int32Constant(Context::SlotOffset( |
| 398 static_cast<int>(access.index())))); | 390 static_cast<int>(access.index())))); |
| 399 PatchOperator(node, machine()->Store(StoreRepresentation(kMachAnyTagged, | 391 node->set_op( |
| 400 kFullWriteBarrier))); | 392 machine()->Store(StoreRepresentation(kMachAnyTagged, kFullWriteBarrier))); |
| 401 } | 393 } |
| 402 | 394 |
| 403 | 395 |
| 404 void JSGenericLowering::LowerJSCreateCatchContext(Node* node) { | 396 void JSGenericLowering::LowerJSCreateCatchContext(Node* node) { |
| 405 Unique<String> name = OpParameter<Unique<String>>(node); | 397 Unique<String> name = OpParameter<Unique<String>>(node); |
| 406 PatchInsertInput(node, 0, jsgraph()->HeapConstant(name)); | 398 node->InsertInput(zone(), 0, jsgraph()->HeapConstant(name)); |
| 407 ReplaceWithRuntimeCall(node, Runtime::kPushCatchContext); | 399 ReplaceWithRuntimeCall(node, Runtime::kPushCatchContext); |
| 408 } | 400 } |
| 409 | 401 |
| 410 | 402 |
| 411 void JSGenericLowering::LowerJSCallConstruct(Node* node) { | 403 void JSGenericLowering::LowerJSCallConstruct(Node* node) { |
| 412 int arity = OpParameter<int>(node); | 404 int arity = OpParameter<int>(node); |
| 413 CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS); | 405 CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS); |
| 414 CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor(); | 406 CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor(); |
| 415 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 407 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 416 isolate(), zone(), d, arity, FlagsForNode(node)); | 408 isolate(), zone(), d, arity, FlagsForNode(node)); |
| 417 Node* stub_code = jsgraph()->HeapConstant(stub.GetCode()); | 409 Node* stub_code = jsgraph()->HeapConstant(stub.GetCode()); |
| 418 Node* construct = NodeProperties::GetValueInput(node, 0); | 410 Node* construct = NodeProperties::GetValueInput(node, 0); |
| 419 PatchInsertInput(node, 0, stub_code); | 411 node->InsertInput(zone(), 0, stub_code); |
| 420 PatchInsertInput(node, 1, jsgraph()->Int32Constant(arity - 1)); | 412 node->InsertInput(zone(), 1, jsgraph()->Int32Constant(arity - 1)); |
| 421 PatchInsertInput(node, 2, construct); | 413 node->InsertInput(zone(), 2, construct); |
| 422 PatchInsertInput(node, 3, jsgraph()->UndefinedConstant()); | 414 node->InsertInput(zone(), 3, jsgraph()->UndefinedConstant()); |
| 423 PatchOperator(node, common()->Call(desc)); | 415 node->set_op(common()->Call(desc)); |
| 424 } | 416 } |
| 425 | 417 |
| 426 | 418 |
| 427 bool JSGenericLowering::TryLowerDirectJSCall(Node* node) { | 419 bool JSGenericLowering::TryLowerDirectJSCall(Node* node) { |
| 428 // Lower to a direct call to a constant JSFunction if legal. | 420 // Lower to a direct call to a constant JSFunction if legal. |
| 429 const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); | 421 const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); |
| 430 int arg_count = static_cast<int>(p.arity() - 2); | 422 int arg_count = static_cast<int>(p.arity() - 2); |
| 431 | 423 |
| 432 // Check the function is a constant and is really a JSFunction. | 424 // Check the function is a constant and is really a JSFunction. |
| 433 HeapObjectMatcher<Object> function_const(node->InputAt(0)); | 425 HeapObjectMatcher<Object> function_const(node->InputAt(0)); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 451 // Remove this when the JSGraph canonicalizes heap constants. | 443 // Remove this when the JSGraph canonicalizes heap constants. |
| 452 Node* context = node->InputAt(index); | 444 Node* context = node->InputAt(index); |
| 453 HeapObjectMatcher<Context> context_const(context); | 445 HeapObjectMatcher<Context> context_const(context); |
| 454 if (!context_const.HasValue() || | 446 if (!context_const.HasValue() || |
| 455 *(context_const.Value().handle()) != function->context()) { | 447 *(context_const.Value().handle()) != function->context()) { |
| 456 context = jsgraph()->HeapConstant(Handle<Context>(function->context())); | 448 context = jsgraph()->HeapConstant(Handle<Context>(function->context())); |
| 457 } | 449 } |
| 458 node->ReplaceInput(index, context); | 450 node->ReplaceInput(index, context); |
| 459 CallDescriptor* desc = Linkage::GetJSCallDescriptor( | 451 CallDescriptor* desc = Linkage::GetJSCallDescriptor( |
| 460 zone(), false, 1 + arg_count, FlagsForNode(node)); | 452 zone(), false, 1 + arg_count, FlagsForNode(node)); |
| 461 PatchOperator(node, common()->Call(desc)); | 453 node->set_op(common()->Call(desc)); |
| 462 return true; | 454 return true; |
| 463 } | 455 } |
| 464 | 456 |
| 465 | 457 |
| 466 void JSGenericLowering::LowerJSCallFunction(Node* node) { | 458 void JSGenericLowering::LowerJSCallFunction(Node* node) { |
| 467 // Fast case: call function directly. | 459 // Fast case: call function directly. |
| 468 if (TryLowerDirectJSCall(node)) return; | 460 if (TryLowerDirectJSCall(node)) return; |
| 469 | 461 |
| 470 // General case: CallFunctionStub. | 462 // General case: CallFunctionStub. |
| 471 const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); | 463 const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); |
| 472 int arg_count = static_cast<int>(p.arity() - 2); | 464 int arg_count = static_cast<int>(p.arity() - 2); |
| 473 CallFunctionStub stub(isolate(), arg_count, p.flags()); | 465 CallFunctionStub stub(isolate(), arg_count, p.flags()); |
| 474 CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor(); | 466 CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor(); |
| 475 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 467 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 476 isolate(), zone(), d, static_cast<int>(p.arity() - 1), | 468 isolate(), zone(), d, static_cast<int>(p.arity() - 1), |
| 477 FlagsForNode(node)); | 469 FlagsForNode(node)); |
| 478 Node* stub_code = jsgraph()->HeapConstant(stub.GetCode()); | 470 Node* stub_code = jsgraph()->HeapConstant(stub.GetCode()); |
| 479 PatchInsertInput(node, 0, stub_code); | 471 node->InsertInput(zone(), 0, stub_code); |
| 480 PatchOperator(node, common()->Call(desc)); | 472 node->set_op(common()->Call(desc)); |
| 481 } | 473 } |
| 482 | 474 |
| 483 | 475 |
| 484 void JSGenericLowering::LowerJSCallRuntime(Node* node) { | 476 void JSGenericLowering::LowerJSCallRuntime(Node* node) { |
| 485 const CallRuntimeParameters& p = CallRuntimeParametersOf(node->op()); | 477 const CallRuntimeParameters& p = CallRuntimeParametersOf(node->op()); |
| 486 ReplaceWithRuntimeCall(node, p.id(), static_cast<int>(p.arity())); | 478 ReplaceWithRuntimeCall(node, p.id(), static_cast<int>(p.arity())); |
| 487 } | 479 } |
| 488 | 480 |
| 489 } // namespace compiler | 481 } // namespace compiler |
| 490 } // namespace internal | 482 } // namespace internal |
| 491 } // namespace v8 | 483 } // namespace v8 |
| OLD | NEW |