| 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/ast/scopes.h" | 5 #include "src/ast/scopes.h" |
| 6 #include "src/code-stubs.h" | 6 #include "src/code-stubs.h" |
| 7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
| 8 #include "src/compiler/common-operator.h" | 8 #include "src/compiler/common-operator.h" |
| 9 #include "src/compiler/frame.h" | 9 #include "src/compiler/frame.h" |
| 10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
| 11 #include "src/compiler/node.h" | 11 #include "src/compiler/node.h" |
| 12 #include "src/compiler/osr.h" | 12 #include "src/compiler/osr.h" |
| 13 #include "src/compiler/pipeline.h" | 13 #include "src/compiler/pipeline.h" |
| 14 | 14 |
| 15 namespace v8 { | 15 namespace v8 { |
| 16 namespace internal { | 16 namespace internal { |
| 17 namespace compiler { | 17 namespace compiler { |
| 18 | 18 |
| 19 namespace { | 19 namespace { |
| 20 LinkageLocation regloc(Register reg) { | 20 |
| 21 return LinkageLocation::ForRegister(reg.code()); | 21 LinkageLocation regloc(Register reg, MachineType type) { |
| 22 return LinkageLocation::ForRegister(reg.code(), type); |
| 22 } | 23 } |
| 23 | 24 |
| 24 | |
| 25 MachineType reptyp(Representation representation) { | 25 MachineType reptyp(Representation representation) { |
| 26 switch (representation.kind()) { | 26 switch (representation.kind()) { |
| 27 case Representation::kInteger8: | 27 case Representation::kInteger8: |
| 28 return MachineType::Int8(); | 28 return MachineType::Int8(); |
| 29 case Representation::kUInteger8: | 29 case Representation::kUInteger8: |
| 30 return MachineType::Uint8(); | 30 return MachineType::Uint8(); |
| 31 case Representation::kInteger16: | 31 case Representation::kInteger16: |
| 32 return MachineType::Int16(); | 32 return MachineType::Int16(); |
| 33 case Representation::kUInteger16: | 33 case Representation::kUInteger16: |
| 34 return MachineType::Uint16(); | 34 return MachineType::Uint16(); |
| 35 case Representation::kInteger32: | 35 case Representation::kInteger32: |
| 36 return MachineType::Int32(); | 36 return MachineType::Int32(); |
| 37 case Representation::kSmi: | 37 case Representation::kSmi: |
| 38 case Representation::kTagged: | 38 case Representation::kTagged: |
| 39 case Representation::kHeapObject: | 39 case Representation::kHeapObject: |
| 40 return MachineType::AnyTagged(); | 40 return MachineType::AnyTagged(); |
| 41 case Representation::kDouble: | 41 case Representation::kDouble: |
| 42 return MachineType::Float64(); | 42 return MachineType::Float64(); |
| 43 case Representation::kExternal: | 43 case Representation::kExternal: |
| 44 return MachineType::Pointer(); | 44 return MachineType::Pointer(); |
| 45 case Representation::kNone: | 45 case Representation::kNone: |
| 46 case Representation::kNumRepresentations: | 46 case Representation::kNumRepresentations: |
| 47 break; | 47 break; |
| 48 } | 48 } |
| 49 UNREACHABLE(); | 49 UNREACHABLE(); |
| 50 return MachineType::None(); | 50 return MachineType::None(); |
| 51 } | 51 } |
| 52 |
| 52 } // namespace | 53 } // namespace |
| 53 | 54 |
| 54 | 55 |
| 55 std::ostream& operator<<(std::ostream& os, const CallDescriptor::Kind& k) { | 56 std::ostream& operator<<(std::ostream& os, const CallDescriptor::Kind& k) { |
| 56 switch (k) { | 57 switch (k) { |
| 57 case CallDescriptor::kCallCodeObject: | 58 case CallDescriptor::kCallCodeObject: |
| 58 os << "Code"; | 59 os << "Code"; |
| 59 break; | 60 break; |
| 60 case CallDescriptor::kCallJSFunction: | 61 case CallDescriptor::kCallJSFunction: |
| 61 os << "JS"; | 62 os << "JS"; |
| 62 break; | 63 break; |
| 63 case CallDescriptor::kCallAddress: | 64 case CallDescriptor::kCallAddress: |
| 64 os << "Addr"; | 65 os << "Addr"; |
| 65 break; | 66 break; |
| 66 } | 67 } |
| 67 return os; | 68 return os; |
| 68 } | 69 } |
| 69 | 70 |
| 70 | 71 |
| 71 std::ostream& operator<<(std::ostream& os, const CallDescriptor& d) { | 72 std::ostream& operator<<(std::ostream& os, const CallDescriptor& d) { |
| 72 // TODO(svenpanne) Output properties etc. and be less cryptic. | 73 // TODO(svenpanne) Output properties etc. and be less cryptic. |
| 73 return os << d.kind() << ":" << d.debug_name() << ":r" << d.ReturnCount() | 74 return os << d.kind() << ":" << d.debug_name() << ":r" << d.ReturnCount() |
| 74 << "s" << d.StackParameterCount() << "i" << d.InputCount() << "f" | 75 << "s" << d.StackParameterCount() << "i" << d.InputCount() << "f" |
| 75 << d.FrameStateCount() << "t" << d.SupportsTailCalls(); | 76 << d.FrameStateCount() << "t" << d.SupportsTailCalls(); |
| 76 } | 77 } |
| 77 | 78 |
| 79 MachineSignature* CallDescriptor::GetMachineSignature(Zone* zone) const { |
| 80 size_t param_count = ParameterCount(); |
| 81 size_t return_count = ReturnCount(); |
| 82 MachineType* types = reinterpret_cast<MachineType*>( |
| 83 zone->New(sizeof(MachineType*) * (param_count + return_count))); |
| 84 int current = 0; |
| 85 for (size_t i = 0; i < return_count; ++i) { |
| 86 types[current++] = GetReturnType(i); |
| 87 } |
| 88 for (size_t i = 0; i < param_count; ++i) { |
| 89 types[current++] = GetParameterType(i); |
| 90 } |
| 91 return new (zone) MachineSignature(return_count, param_count, types); |
| 92 } |
| 78 | 93 |
| 79 bool CallDescriptor::HasSameReturnLocationsAs( | 94 bool CallDescriptor::HasSameReturnLocationsAs( |
| 80 const CallDescriptor* other) const { | 95 const CallDescriptor* other) const { |
| 81 if (ReturnCount() != other->ReturnCount()) return false; | 96 if (ReturnCount() != other->ReturnCount()) return false; |
| 82 for (size_t i = 0; i < ReturnCount(); ++i) { | 97 for (size_t i = 0; i < ReturnCount(); ++i) { |
| 83 if (GetReturnLocation(i) != other->GetReturnLocation(i)) return false; | 98 if (GetReturnLocation(i) != other->GetReturnLocation(i)) return false; |
| 84 } | 99 } |
| 85 return true; | 100 return true; |
| 86 } | 101 } |
| 87 | 102 |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 const size_t num_args_count = 1; | 227 const size_t num_args_count = 1; |
| 213 const size_t context_count = 1; | 228 const size_t context_count = 1; |
| 214 const size_t parameter_count = function_count + | 229 const size_t parameter_count = function_count + |
| 215 static_cast<size_t>(js_parameter_count) + | 230 static_cast<size_t>(js_parameter_count) + |
| 216 num_args_count + context_count; | 231 num_args_count + context_count; |
| 217 | 232 |
| 218 const Runtime::Function* function = Runtime::FunctionForId(function_id); | 233 const Runtime::Function* function = Runtime::FunctionForId(function_id); |
| 219 const size_t return_count = static_cast<size_t>(function->result_size); | 234 const size_t return_count = static_cast<size_t>(function->result_size); |
| 220 | 235 |
| 221 LocationSignature::Builder locations(zone, return_count, parameter_count); | 236 LocationSignature::Builder locations(zone, return_count, parameter_count); |
| 222 MachineSignature::Builder types(zone, return_count, parameter_count); | |
| 223 | 237 |
| 224 // Add returns. | 238 // Add returns. |
| 225 if (locations.return_count_ > 0) { | 239 if (locations.return_count_ > 0) { |
| 226 locations.AddReturn(regloc(kReturnRegister0)); | 240 locations.AddReturn(regloc(kReturnRegister0, MachineType::AnyTagged())); |
| 227 } | 241 } |
| 228 if (locations.return_count_ > 1) { | 242 if (locations.return_count_ > 1) { |
| 229 locations.AddReturn(regloc(kReturnRegister1)); | 243 locations.AddReturn(regloc(kReturnRegister1, MachineType::AnyTagged())); |
| 230 } | 244 } |
| 231 if (locations.return_count_ > 2) { | 245 if (locations.return_count_ > 2) { |
| 232 locations.AddReturn(regloc(kReturnRegister2)); | 246 locations.AddReturn(regloc(kReturnRegister2, MachineType::AnyTagged())); |
| 233 } | |
| 234 for (size_t i = 0; i < return_count; i++) { | |
| 235 types.AddReturn(MachineType::AnyTagged()); | |
| 236 } | 247 } |
| 237 | 248 |
| 238 // All parameters to the runtime call go on the stack. | 249 // All parameters to the runtime call go on the stack. |
| 239 for (int i = 0; i < js_parameter_count; i++) { | 250 for (int i = 0; i < js_parameter_count; i++) { |
| 240 locations.AddParam( | 251 locations.AddParam(LinkageLocation::ForCallerFrameSlot( |
| 241 LinkageLocation::ForCallerFrameSlot(i - js_parameter_count)); | 252 i - js_parameter_count, MachineType::AnyTagged())); |
| 242 types.AddParam(MachineType::AnyTagged()); | |
| 243 } | 253 } |
| 244 // Add runtime function itself. | 254 // Add runtime function itself. |
| 245 locations.AddParam(regloc(kRuntimeCallFunctionRegister)); | 255 locations.AddParam( |
| 246 types.AddParam(MachineType::AnyTagged()); | 256 regloc(kRuntimeCallFunctionRegister, MachineType::AnyTagged())); |
| 247 | 257 |
| 248 // Add runtime call argument count. | 258 // Add runtime call argument count. |
| 249 locations.AddParam(regloc(kRuntimeCallArgCountRegister)); | 259 locations.AddParam( |
| 250 types.AddParam(MachineType::Pointer()); | 260 regloc(kRuntimeCallArgCountRegister, MachineType::AnyTagged())); |
| 251 | 261 |
| 252 // Add context. | 262 // Add context. |
| 253 locations.AddParam(regloc(kContextRegister)); | 263 locations.AddParam(regloc(kContextRegister, MachineType::AnyTagged())); |
| 254 types.AddParam(MachineType::AnyTagged()); | |
| 255 | 264 |
| 256 if (!Linkage::NeedsFrameStateInput(function_id)) { | 265 if (!Linkage::NeedsFrameStateInput(function_id)) { |
| 257 flags = static_cast<CallDescriptor::Flags>( | 266 flags = static_cast<CallDescriptor::Flags>( |
| 258 flags & ~CallDescriptor::kNeedsFrameState); | 267 flags & ~CallDescriptor::kNeedsFrameState); |
| 259 } | 268 } |
| 260 | 269 |
| 261 // The target for runtime calls is a code object. | 270 // The target for runtime calls is a code object. |
| 262 MachineType target_type = MachineType::AnyTagged(); | 271 MachineType target_type = MachineType::AnyTagged(); |
| 263 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); | 272 LinkageLocation target_loc = |
| 273 LinkageLocation::ForAnyRegister(MachineType::AnyTagged()); |
| 264 return new (zone) CallDescriptor( // -- | 274 return new (zone) CallDescriptor( // -- |
| 265 CallDescriptor::kCallCodeObject, // kind | 275 CallDescriptor::kCallCodeObject, // kind |
| 266 target_type, // target MachineType | 276 target_type, // target MachineType |
| 267 target_loc, // target location | 277 target_loc, // target location |
| 268 types.Build(), // machine_sig | |
| 269 locations.Build(), // location_sig | 278 locations.Build(), // location_sig |
| 270 js_parameter_count, // stack_parameter_count | 279 js_parameter_count, // stack_parameter_count |
| 271 properties, // properties | 280 properties, // properties |
| 272 kNoCalleeSaved, // callee-saved | 281 kNoCalleeSaved, // callee-saved |
| 273 kNoCalleeSaved, // callee-saved fp | 282 kNoCalleeSaved, // callee-saved fp |
| 274 flags, // flags | 283 flags, // flags |
| 275 function->name); // debug name | 284 function->name); // debug name |
| 276 } | 285 } |
| 277 | 286 |
| 278 | 287 |
| 279 CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr, | 288 CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr, |
| 280 int js_parameter_count, | 289 int js_parameter_count, |
| 281 CallDescriptor::Flags flags) { | 290 CallDescriptor::Flags flags) { |
| 282 const size_t return_count = 1; | 291 const size_t return_count = 1; |
| 283 const size_t context_count = 1; | 292 const size_t context_count = 1; |
| 284 const size_t new_target_count = 1; | 293 const size_t new_target_count = 1; |
| 285 const size_t num_args_count = 1; | 294 const size_t num_args_count = 1; |
| 286 const size_t parameter_count = | 295 const size_t parameter_count = |
| 287 js_parameter_count + new_target_count + num_args_count + context_count; | 296 js_parameter_count + new_target_count + num_args_count + context_count; |
| 288 | 297 |
| 289 LocationSignature::Builder locations(zone, return_count, parameter_count); | 298 LocationSignature::Builder locations(zone, return_count, parameter_count); |
| 290 MachineSignature::Builder types(zone, return_count, parameter_count); | |
| 291 | 299 |
| 292 // All JS calls have exactly one return value. | 300 // All JS calls have exactly one return value. |
| 293 locations.AddReturn(regloc(kReturnRegister0)); | 301 locations.AddReturn(regloc(kReturnRegister0, MachineType::AnyTagged())); |
| 294 types.AddReturn(MachineType::AnyTagged()); | |
| 295 | 302 |
| 296 // All parameters to JS calls go on the stack. | 303 // All parameters to JS calls go on the stack. |
| 297 for (int i = 0; i < js_parameter_count; i++) { | 304 for (int i = 0; i < js_parameter_count; i++) { |
| 298 int spill_slot_index = i - js_parameter_count; | 305 int spill_slot_index = i - js_parameter_count; |
| 299 locations.AddParam(LinkageLocation::ForCallerFrameSlot(spill_slot_index)); | 306 locations.AddParam(LinkageLocation::ForCallerFrameSlot( |
| 300 types.AddParam(MachineType::AnyTagged()); | 307 spill_slot_index, MachineType::AnyTagged())); |
| 301 } | 308 } |
| 302 | 309 |
| 303 // Add JavaScript call new target value. | 310 // Add JavaScript call new target value. |
| 304 locations.AddParam(regloc(kJavaScriptCallNewTargetRegister)); | 311 locations.AddParam( |
| 305 types.AddParam(MachineType::AnyTagged()); | 312 regloc(kJavaScriptCallNewTargetRegister, MachineType::AnyTagged())); |
| 306 | 313 |
| 307 // Add JavaScript call argument count. | 314 // Add JavaScript call argument count. |
| 308 locations.AddParam(regloc(kJavaScriptCallArgCountRegister)); | 315 locations.AddParam( |
| 309 types.AddParam(MachineType::Int32()); | 316 regloc(kJavaScriptCallArgCountRegister, MachineType::Int32())); |
| 310 | 317 |
| 311 // Add context. | 318 // Add context. |
| 312 locations.AddParam(regloc(kContextRegister)); | 319 locations.AddParam(regloc(kContextRegister, MachineType::AnyTagged())); |
| 313 types.AddParam(MachineType::AnyTagged()); | |
| 314 | 320 |
| 315 // The target for JS function calls is the JSFunction object. | 321 // The target for JS function calls is the JSFunction object. |
| 316 MachineType target_type = MachineType::AnyTagged(); | 322 MachineType target_type = MachineType::AnyTagged(); |
| 317 // When entering into an OSR function from unoptimized code the JSFunction | 323 // When entering into an OSR function from unoptimized code the JSFunction |
| 318 // is not in a register, but it is on the stack in the marker spill slot. | 324 // is not in a register, but it is on the stack in the marker spill slot. |
| 319 LinkageLocation target_loc = is_osr | 325 LinkageLocation target_loc = |
| 320 ? LinkageLocation::ForSavedCallerFunction() | 326 is_osr ? LinkageLocation::ForSavedCallerFunction() |
| 321 : regloc(kJSFunctionRegister); | 327 : regloc(kJSFunctionRegister, MachineType::AnyTagged()); |
| 322 return new (zone) CallDescriptor( // -- | 328 return new (zone) CallDescriptor( // -- |
| 323 CallDescriptor::kCallJSFunction, // kind | 329 CallDescriptor::kCallJSFunction, // kind |
| 324 target_type, // target MachineType | 330 target_type, // target MachineType |
| 325 target_loc, // target location | 331 target_loc, // target location |
| 326 types.Build(), // machine_sig | |
| 327 locations.Build(), // location_sig | 332 locations.Build(), // location_sig |
| 328 js_parameter_count, // stack_parameter_count | 333 js_parameter_count, // stack_parameter_count |
| 329 Operator::kNoProperties, // properties | 334 Operator::kNoProperties, // properties |
| 330 kNoCalleeSaved, // callee-saved | 335 kNoCalleeSaved, // callee-saved |
| 331 kNoCalleeSaved, // callee-saved fp | 336 kNoCalleeSaved, // callee-saved fp |
| 332 CallDescriptor::kCanUseRoots | // flags | 337 CallDescriptor::kCanUseRoots | // flags |
| 333 flags, // flags | 338 flags, // flags |
| 334 "js-call"); | 339 "js-call"); |
| 335 } | 340 } |
| 336 | 341 |
| 337 // TODO(all): Add support for return representations/locations to | 342 // TODO(all): Add support for return representations/locations to |
| 338 // CallInterfaceDescriptor. | 343 // CallInterfaceDescriptor. |
| 339 // TODO(turbofan): cache call descriptors for code stub calls. | 344 // TODO(turbofan): cache call descriptors for code stub calls. |
| 340 CallDescriptor* Linkage::GetStubCallDescriptor( | 345 CallDescriptor* Linkage::GetStubCallDescriptor( |
| 341 Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor, | 346 Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor, |
| 342 int stack_parameter_count, CallDescriptor::Flags flags, | 347 int stack_parameter_count, CallDescriptor::Flags flags, |
| 343 Operator::Properties properties, MachineType return_type, | 348 Operator::Properties properties, MachineType return_type, |
| 344 size_t return_count) { | 349 size_t return_count) { |
| 345 const int register_parameter_count = descriptor.GetRegisterParameterCount(); | 350 const int register_parameter_count = descriptor.GetRegisterParameterCount(); |
| 346 const int js_parameter_count = | 351 const int js_parameter_count = |
| 347 register_parameter_count + stack_parameter_count; | 352 register_parameter_count + stack_parameter_count; |
| 348 const int context_count = 1; | 353 const int context_count = 1; |
| 349 const size_t parameter_count = | 354 const size_t parameter_count = |
| 350 static_cast<size_t>(js_parameter_count + context_count); | 355 static_cast<size_t>(js_parameter_count + context_count); |
| 351 | 356 |
| 352 LocationSignature::Builder locations(zone, return_count, parameter_count); | 357 LocationSignature::Builder locations(zone, return_count, parameter_count); |
| 353 MachineSignature::Builder types(zone, return_count, parameter_count); | |
| 354 | 358 |
| 355 // Add returns. | 359 // Add returns. |
| 356 if (locations.return_count_ > 0) { | 360 if (locations.return_count_ > 0) { |
| 357 locations.AddReturn(regloc(kReturnRegister0)); | 361 locations.AddReturn(regloc(kReturnRegister0, return_type)); |
| 358 } | 362 } |
| 359 if (locations.return_count_ > 1) { | 363 if (locations.return_count_ > 1) { |
| 360 locations.AddReturn(regloc(kReturnRegister1)); | 364 locations.AddReturn(regloc(kReturnRegister1, return_type)); |
| 361 } | 365 } |
| 362 if (locations.return_count_ > 2) { | 366 if (locations.return_count_ > 2) { |
| 363 locations.AddReturn(regloc(kReturnRegister2)); | 367 locations.AddReturn(regloc(kReturnRegister2, return_type)); |
| 364 } | |
| 365 for (size_t i = 0; i < return_count; i++) { | |
| 366 types.AddReturn(return_type); | |
| 367 } | 368 } |
| 368 | 369 |
| 369 // Add parameters in registers and on the stack. | 370 // Add parameters in registers and on the stack. |
| 370 for (int i = 0; i < js_parameter_count; i++) { | 371 for (int i = 0; i < js_parameter_count; i++) { |
| 371 if (i < register_parameter_count) { | 372 if (i < register_parameter_count) { |
| 372 // The first parameters go in registers. | 373 // The first parameters go in registers. |
| 373 Register reg = descriptor.GetRegisterParameter(i); | 374 Register reg = descriptor.GetRegisterParameter(i); |
| 374 Representation rep = | 375 MachineType type = |
| 375 RepresentationFromType(descriptor.GetParameterType(i)); | 376 reptyp(RepresentationFromType(descriptor.GetParameterType(i))); |
| 376 locations.AddParam(regloc(reg)); | 377 locations.AddParam(regloc(reg, type)); |
| 377 types.AddParam(reptyp(rep)); | |
| 378 } else { | 378 } else { |
| 379 // The rest of the parameters go on the stack. | 379 // The rest of the parameters go on the stack. |
| 380 int stack_slot = i - register_parameter_count - stack_parameter_count; | 380 int stack_slot = i - register_parameter_count - stack_parameter_count; |
| 381 locations.AddParam(LinkageLocation::ForCallerFrameSlot(stack_slot)); | 381 locations.AddParam(LinkageLocation::ForCallerFrameSlot( |
| 382 types.AddParam(MachineType::AnyTagged()); | 382 stack_slot, MachineType::AnyTagged())); |
| 383 } | 383 } |
| 384 } | 384 } |
| 385 // Add context. | 385 // Add context. |
| 386 locations.AddParam(regloc(kContextRegister)); | 386 locations.AddParam(regloc(kContextRegister, MachineType::AnyTagged())); |
| 387 types.AddParam(MachineType::AnyTagged()); | |
| 388 | 387 |
| 389 // The target for stub calls is a code object. | 388 // The target for stub calls is a code object. |
| 390 MachineType target_type = MachineType::AnyTagged(); | 389 MachineType target_type = MachineType::AnyTagged(); |
| 391 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); | 390 LinkageLocation target_loc = |
| 391 LinkageLocation::ForAnyRegister(MachineType::AnyTagged()); |
| 392 return new (zone) CallDescriptor( // -- | 392 return new (zone) CallDescriptor( // -- |
| 393 CallDescriptor::kCallCodeObject, // kind | 393 CallDescriptor::kCallCodeObject, // kind |
| 394 target_type, // target MachineType | 394 target_type, // target MachineType |
| 395 target_loc, // target location | 395 target_loc, // target location |
| 396 types.Build(), // machine_sig | |
| 397 locations.Build(), // location_sig | 396 locations.Build(), // location_sig |
| 398 stack_parameter_count, // stack_parameter_count | 397 stack_parameter_count, // stack_parameter_count |
| 399 properties, // properties | 398 properties, // properties |
| 400 kNoCalleeSaved, // callee-saved registers | 399 kNoCalleeSaved, // callee-saved registers |
| 401 kNoCalleeSaved, // callee-saved fp | 400 kNoCalleeSaved, // callee-saved fp |
| 402 CallDescriptor::kCanUseRoots | // flags | 401 CallDescriptor::kCanUseRoots | // flags |
| 403 flags, // flags | 402 flags, // flags |
| 404 descriptor.DebugName(isolate)); | 403 descriptor.DebugName(isolate)); |
| 405 } | 404 } |
| 406 | 405 |
| 407 // static | 406 // static |
| 408 CallDescriptor* Linkage::GetAllocateCallDescriptor(Zone* zone) { | 407 CallDescriptor* Linkage::GetAllocateCallDescriptor(Zone* zone) { |
| 409 LocationSignature::Builder locations(zone, 1, 1); | 408 LocationSignature::Builder locations(zone, 1, 1); |
| 410 MachineSignature::Builder types(zone, 1, 1); | |
| 411 | 409 |
| 412 locations.AddParam(regloc(kAllocateSizeRegister)); | 410 locations.AddParam(regloc(kAllocateSizeRegister, MachineType::Int32())); |
| 413 types.AddParam(MachineType::Int32()); | |
| 414 | 411 |
| 415 locations.AddReturn(regloc(kReturnRegister0)); | 412 locations.AddReturn(regloc(kReturnRegister0, MachineType::AnyTagged())); |
| 416 types.AddReturn(MachineType::AnyTagged()); | |
| 417 | 413 |
| 418 // The target for allocate calls is a code object. | 414 // The target for allocate calls is a code object. |
| 419 MachineType target_type = MachineType::AnyTagged(); | 415 MachineType target_type = MachineType::AnyTagged(); |
| 420 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); | 416 LinkageLocation target_loc = |
| 417 LinkageLocation::ForAnyRegister(MachineType::AnyTagged()); |
| 421 return new (zone) CallDescriptor( // -- | 418 return new (zone) CallDescriptor( // -- |
| 422 CallDescriptor::kCallCodeObject, // kind | 419 CallDescriptor::kCallCodeObject, // kind |
| 423 target_type, // target MachineType | 420 target_type, // target MachineType |
| 424 target_loc, // target location | 421 target_loc, // target location |
| 425 types.Build(), // machine_sig | |
| 426 locations.Build(), // location_sig | 422 locations.Build(), // location_sig |
| 427 0, // stack_parameter_count | 423 0, // stack_parameter_count |
| 428 Operator::kNoThrow, // properties | 424 Operator::kNoThrow, // properties |
| 429 kNoCalleeSaved, // callee-saved registers | 425 kNoCalleeSaved, // callee-saved registers |
| 430 kNoCalleeSaved, // callee-saved fp | 426 kNoCalleeSaved, // callee-saved fp |
| 431 CallDescriptor::kCanUseRoots, // flags | 427 CallDescriptor::kCanUseRoots, // flags |
| 432 "Allocate"); | 428 "Allocate"); |
| 433 } | 429 } |
| 434 | 430 |
| 435 // static | 431 // static |
| 436 CallDescriptor* Linkage::GetBytecodeDispatchCallDescriptor( | 432 CallDescriptor* Linkage::GetBytecodeDispatchCallDescriptor( |
| 437 Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor, | 433 Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor, |
| 438 int stack_parameter_count) { | 434 int stack_parameter_count) { |
| 439 const int register_parameter_count = descriptor.GetRegisterParameterCount(); | 435 const int register_parameter_count = descriptor.GetRegisterParameterCount(); |
| 440 const int parameter_count = register_parameter_count + stack_parameter_count; | 436 const int parameter_count = register_parameter_count + stack_parameter_count; |
| 441 | 437 |
| 442 LocationSignature::Builder locations(zone, 0, parameter_count); | 438 LocationSignature::Builder locations(zone, 0, parameter_count); |
| 443 MachineSignature::Builder types(zone, 0, parameter_count); | |
| 444 | 439 |
| 445 // Add parameters in registers and on the stack. | 440 // Add parameters in registers and on the stack. |
| 446 for (int i = 0; i < parameter_count; i++) { | 441 for (int i = 0; i < parameter_count; i++) { |
| 447 if (i < register_parameter_count) { | 442 if (i < register_parameter_count) { |
| 448 // The first parameters go in registers. | 443 // The first parameters go in registers. |
| 449 Register reg = descriptor.GetRegisterParameter(i); | 444 Register reg = descriptor.GetRegisterParameter(i); |
| 450 Representation rep = | 445 MachineType type = |
| 451 RepresentationFromType(descriptor.GetParameterType(i)); | 446 reptyp(RepresentationFromType(descriptor.GetParameterType(i))); |
| 452 locations.AddParam(regloc(reg)); | 447 locations.AddParam(regloc(reg, type)); |
| 453 types.AddParam(reptyp(rep)); | |
| 454 } else { | 448 } else { |
| 455 // The rest of the parameters go on the stack. | 449 // The rest of the parameters go on the stack. |
| 456 int stack_slot = i - register_parameter_count - stack_parameter_count; | 450 int stack_slot = i - register_parameter_count - stack_parameter_count; |
| 457 locations.AddParam(LinkageLocation::ForCallerFrameSlot(stack_slot)); | 451 locations.AddParam(LinkageLocation::ForCallerFrameSlot( |
| 458 types.AddParam(MachineType::AnyTagged()); | 452 stack_slot, MachineType::AnyTagged())); |
| 459 } | 453 } |
| 460 } | 454 } |
| 461 | 455 |
| 462 // The target for interpreter dispatches is a code entry address. | 456 // The target for interpreter dispatches is a code entry address. |
| 463 MachineType target_type = MachineType::Pointer(); | 457 MachineType target_type = MachineType::Pointer(); |
| 464 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); | 458 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(target_type); |
| 465 return new (zone) CallDescriptor( // -- | 459 return new (zone) CallDescriptor( // -- |
| 466 CallDescriptor::kCallAddress, // kind | 460 CallDescriptor::kCallAddress, // kind |
| 467 target_type, // target MachineType | 461 target_type, // target MachineType |
| 468 target_loc, // target location | 462 target_loc, // target location |
| 469 types.Build(), // machine_sig | |
| 470 locations.Build(), // location_sig | 463 locations.Build(), // location_sig |
| 471 stack_parameter_count, // stack_parameter_count | 464 stack_parameter_count, // stack_parameter_count |
| 472 Operator::kNoProperties, // properties | 465 Operator::kNoProperties, // properties |
| 473 kNoCalleeSaved, // callee-saved registers | 466 kNoCalleeSaved, // callee-saved registers |
| 474 kNoCalleeSaved, // callee-saved fp | 467 kNoCalleeSaved, // callee-saved fp |
| 475 CallDescriptor::kCanUseRoots | // flags | 468 CallDescriptor::kCanUseRoots | // flags |
| 476 CallDescriptor::kSupportsTailCalls, // flags | 469 CallDescriptor::kSupportsTailCalls, // flags |
| 477 descriptor.DebugName(isolate)); | 470 descriptor.DebugName(isolate)); |
| 478 } | 471 } |
| 479 | 472 |
| 480 LinkageLocation Linkage::GetOsrValueLocation(int index) const { | 473 LinkageLocation Linkage::GetOsrValueLocation(int index) const { |
| 481 CHECK(incoming_->IsJSFunctionCall()); | 474 CHECK(incoming_->IsJSFunctionCall()); |
| 482 int parameter_count = static_cast<int>(incoming_->JSParameterCount() - 1); | 475 int parameter_count = static_cast<int>(incoming_->JSParameterCount() - 1); |
| 483 int first_stack_slot = OsrHelper::FirstStackSlotIndex(parameter_count); | 476 int first_stack_slot = OsrHelper::FirstStackSlotIndex(parameter_count); |
| 484 | 477 |
| 485 if (index == kOsrContextSpillSlotIndex) { | 478 if (index == kOsrContextSpillSlotIndex) { |
| 486 // Context. Use the parameter location of the context spill slot. | 479 // Context. Use the parameter location of the context spill slot. |
| 487 // Parameter (arity + 2) is special for the context of the function frame. | 480 // Parameter (arity + 2) is special for the context of the function frame. |
| 488 // >> context_index = target + receiver + params + new_target + #args | 481 // >> context_index = target + receiver + params + new_target + #args |
| 489 int context_index = 1 + 1 + parameter_count + 1 + 1; | 482 int context_index = 1 + 1 + parameter_count + 1 + 1; |
| 490 return incoming_->GetInputLocation(context_index); | 483 return incoming_->GetInputLocation(context_index); |
| 491 } else if (index >= first_stack_slot) { | 484 } else if (index >= first_stack_slot) { |
| 492 // Local variable stored in this (callee) stack. | 485 // Local variable stored in this (callee) stack. |
| 493 int spill_index = | 486 int spill_index = |
| 494 index - first_stack_slot + StandardFrameConstants::kFixedSlotCount; | 487 index - first_stack_slot + StandardFrameConstants::kFixedSlotCount; |
| 495 return LinkageLocation::ForCalleeFrameSlot(spill_index); | 488 return LinkageLocation::ForCalleeFrameSlot(spill_index, |
| 489 MachineType::AnyTagged()); |
| 496 } else { | 490 } else { |
| 497 // Parameter. Use the assigned location from the incoming call descriptor. | 491 // Parameter. Use the assigned location from the incoming call descriptor. |
| 498 int parameter_index = 1 + index; // skip index 0, which is the target. | 492 int parameter_index = 1 + index; // skip index 0, which is the target. |
| 499 return incoming_->GetInputLocation(parameter_index); | 493 return incoming_->GetInputLocation(parameter_index); |
| 500 } | 494 } |
| 501 } | 495 } |
| 502 | 496 |
| 503 | 497 |
| 504 bool Linkage::ParameterHasSecondaryLocation(int index) const { | 498 bool Linkage::ParameterHasSecondaryLocation(int index) const { |
| 505 if (!incoming_->IsJSFunctionCall()) return false; | 499 if (!incoming_->IsJSFunctionCall()) return false; |
| 506 LinkageLocation loc = GetParameterLocation(index); | 500 LinkageLocation loc = GetParameterLocation(index); |
| 507 return (loc == regloc(kJSFunctionRegister) || | 501 return (loc == regloc(kJSFunctionRegister, MachineType::AnyTagged()) || |
| 508 loc == regloc(kContextRegister)); | 502 loc == regloc(kContextRegister, MachineType::AnyTagged())); |
| 509 } | 503 } |
| 510 | 504 |
| 511 LinkageLocation Linkage::GetParameterSecondaryLocation(int index) const { | 505 LinkageLocation Linkage::GetParameterSecondaryLocation(int index) const { |
| 512 DCHECK(ParameterHasSecondaryLocation(index)); | 506 DCHECK(ParameterHasSecondaryLocation(index)); |
| 513 LinkageLocation loc = GetParameterLocation(index); | 507 LinkageLocation loc = GetParameterLocation(index); |
| 514 | 508 |
| 515 if (loc == regloc(kJSFunctionRegister)) { | 509 if (loc == regloc(kJSFunctionRegister, MachineType::AnyTagged())) { |
| 516 return LinkageLocation::ForCalleeFrameSlot(Frame::kJSFunctionSlot); | 510 return LinkageLocation::ForCalleeFrameSlot(Frame::kJSFunctionSlot, |
| 511 MachineType::AnyTagged()); |
| 517 } else { | 512 } else { |
| 518 DCHECK(loc == regloc(kContextRegister)); | 513 DCHECK(loc == regloc(kContextRegister, MachineType::AnyTagged())); |
| 519 return LinkageLocation::ForCalleeFrameSlot(Frame::kContextSlot); | 514 return LinkageLocation::ForCalleeFrameSlot(Frame::kContextSlot, |
| 515 MachineType::AnyTagged()); |
| 520 } | 516 } |
| 521 } | 517 } |
| 522 | 518 |
| 523 | 519 |
| 524 } // namespace compiler | 520 } // namespace compiler |
| 525 } // namespace internal | 521 } // namespace internal |
| 526 } // namespace v8 | 522 } // namespace v8 |
| OLD | NEW |