| 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/compiler/js-operator.h" | 5 #include "src/compiler/js-operator.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "src/base/lazy-instance.h" | 9 #include "src/base/lazy-instance.h" |
| 10 #include "src/compiler/opcodes.h" | 10 #include "src/compiler/opcodes.h" |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 V(CreateScriptContext, Operator::kNoProperties, 2, 1) | 247 V(CreateScriptContext, Operator::kNoProperties, 2, 1) |
| 248 | 248 |
| 249 | 249 |
| 250 struct JSOperatorGlobalCache FINAL { | 250 struct JSOperatorGlobalCache FINAL { |
| 251 #define CACHED(Name, properties, value_input_count, value_output_count) \ | 251 #define CACHED(Name, properties, value_input_count, value_output_count) \ |
| 252 struct Name##Operator FINAL : public Operator { \ | 252 struct Name##Operator FINAL : public Operator { \ |
| 253 Name##Operator() \ | 253 Name##Operator() \ |
| 254 : Operator(IrOpcode::kJS##Name, properties, "JS" #Name, \ | 254 : Operator(IrOpcode::kJS##Name, properties, "JS" #Name, \ |
| 255 value_input_count, Operator::ZeroIfPure(properties), \ | 255 value_input_count, Operator::ZeroIfPure(properties), \ |
| 256 Operator::ZeroIfPure(properties), value_output_count, \ | 256 Operator::ZeroIfPure(properties), value_output_count, \ |
| 257 Operator::ZeroIfPure(properties), 0) {} \ | 257 Operator::ZeroIfPure(properties), \ |
| 258 Operator::ZeroIfNoThrow(properties)) {} \ |
| 258 }; \ | 259 }; \ |
| 259 Name##Operator k##Name##Operator; | 260 Name##Operator k##Name##Operator; |
| 260 CACHED_OP_LIST(CACHED) | 261 CACHED_OP_LIST(CACHED) |
| 261 #undef CACHED | 262 #undef CACHED |
| 262 | 263 |
| 263 template <LanguageMode kLanguageMode> | 264 template <LanguageMode kLanguageMode> |
| 264 struct StorePropertyOperator FINAL : public Operator1<LanguageMode> { | 265 struct StorePropertyOperator FINAL : public Operator1<LanguageMode> { |
| 265 StorePropertyOperator() | 266 StorePropertyOperator() |
| 266 : Operator1<LanguageMode>(IrOpcode::kJSStoreProperty, | 267 : Operator1<LanguageMode>(IrOpcode::kJSStoreProperty, |
| 267 Operator::kNoProperties, "JSStoreProperty", 3, | 268 Operator::kNoProperties, "JSStoreProperty", 3, |
| 268 1, 1, 0, 1, 0, kLanguageMode) {} | 269 1, 1, 0, 1, 2, kLanguageMode) {} |
| 269 }; | 270 }; |
| 270 StorePropertyOperator<SLOPPY> kStorePropertySloppyOperator; | 271 StorePropertyOperator<SLOPPY> kStorePropertySloppyOperator; |
| 271 StorePropertyOperator<STRICT> kStorePropertyStrictOperator; | 272 StorePropertyOperator<STRICT> kStorePropertyStrictOperator; |
| 272 }; | 273 }; |
| 273 | 274 |
| 274 | 275 |
| 275 static base::LazyInstance<JSOperatorGlobalCache>::type kCache = | 276 static base::LazyInstance<JSOperatorGlobalCache>::type kCache = |
| 276 LAZY_INSTANCE_INITIALIZER; | 277 LAZY_INSTANCE_INITIALIZER; |
| 277 | 278 |
| 278 | 279 |
| 279 JSOperatorBuilder::JSOperatorBuilder(Zone* zone) | 280 JSOperatorBuilder::JSOperatorBuilder(Zone* zone) |
| 280 : cache_(kCache.Get()), zone_(zone) {} | 281 : cache_(kCache.Get()), zone_(zone) {} |
| 281 | 282 |
| 282 | 283 |
| 283 #define CACHED(Name, properties, value_input_count, value_output_count) \ | 284 #define CACHED(Name, properties, value_input_count, value_output_count) \ |
| 284 const Operator* JSOperatorBuilder::Name() { \ | 285 const Operator* JSOperatorBuilder::Name() { \ |
| 285 return &cache_.k##Name##Operator; \ | 286 return &cache_.k##Name##Operator; \ |
| 286 } | 287 } |
| 287 CACHED_OP_LIST(CACHED) | 288 CACHED_OP_LIST(CACHED) |
| 288 #undef CACHED | 289 #undef CACHED |
| 289 | 290 |
| 290 | 291 |
| 291 const Operator* JSOperatorBuilder::CallFunction(size_t arity, | 292 const Operator* JSOperatorBuilder::CallFunction(size_t arity, |
| 292 CallFunctionFlags flags) { | 293 CallFunctionFlags flags) { |
| 293 CallFunctionParameters parameters(arity, flags); | 294 CallFunctionParameters parameters(arity, flags); |
| 294 return new (zone()) Operator1<CallFunctionParameters>( // -- | 295 return new (zone()) Operator1<CallFunctionParameters>( // -- |
| 295 IrOpcode::kJSCallFunction, Operator::kNoProperties, // opcode | 296 IrOpcode::kJSCallFunction, Operator::kNoProperties, // opcode |
| 296 "JSCallFunction", // name | 297 "JSCallFunction", // name |
| 297 parameters.arity(), 1, 1, 1, 1, 0, // inputs/outputs | 298 parameters.arity(), 1, 1, 1, 1, 2, // inputs/outputs |
| 298 parameters); // parameter | 299 parameters); // parameter |
| 299 } | 300 } |
| 300 | 301 |
| 301 | 302 |
| 302 const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id, | 303 const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id, |
| 303 size_t arity) { | 304 size_t arity) { |
| 304 CallRuntimeParameters parameters(id, arity); | 305 CallRuntimeParameters parameters(id, arity); |
| 305 const Runtime::Function* f = Runtime::FunctionForId(parameters.id()); | 306 const Runtime::Function* f = Runtime::FunctionForId(parameters.id()); |
| 306 DCHECK(f->nargs == -1 || f->nargs == static_cast<int>(parameters.arity())); | 307 DCHECK(f->nargs == -1 || f->nargs == static_cast<int>(parameters.arity())); |
| 307 return new (zone()) Operator1<CallRuntimeParameters>( // -- | 308 return new (zone()) Operator1<CallRuntimeParameters>( // -- |
| 308 IrOpcode::kJSCallRuntime, Operator::kNoProperties, // opcode | 309 IrOpcode::kJSCallRuntime, Operator::kNoProperties, // opcode |
| 309 "JSCallRuntime", // name | 310 "JSCallRuntime", // name |
| 310 parameters.arity(), 1, 1, f->result_size, 1, 0, // inputs/outputs | 311 parameters.arity(), 1, 1, f->result_size, 1, 2, // inputs/outputs |
| 311 parameters); // parameter | 312 parameters); // parameter |
| 312 } | 313 } |
| 313 | 314 |
| 314 | 315 |
| 315 const Operator* JSOperatorBuilder::CallConstruct(int arguments) { | 316 const Operator* JSOperatorBuilder::CallConstruct(int arguments) { |
| 316 return new (zone()) Operator1<int>( // -- | 317 return new (zone()) Operator1<int>( // -- |
| 317 IrOpcode::kJSCallConstruct, Operator::kNoProperties, // opcode | 318 IrOpcode::kJSCallConstruct, Operator::kNoProperties, // opcode |
| 318 "JSCallConstruct", // name | 319 "JSCallConstruct", // name |
| 319 arguments, 1, 1, 1, 1, 0, // counts | 320 arguments, 1, 1, 1, 1, 2, // counts |
| 320 arguments); // parameter | 321 arguments); // parameter |
| 321 } | 322 } |
| 322 | 323 |
| 323 | 324 |
| 324 const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name, | 325 const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name, |
| 325 const VectorSlotPair& feedback, | 326 const VectorSlotPair& feedback, |
| 326 ContextualMode contextual_mode) { | 327 ContextualMode contextual_mode) { |
| 327 LoadNamedParameters parameters(name, feedback, contextual_mode); | 328 LoadNamedParameters parameters(name, feedback, contextual_mode); |
| 328 return new (zone()) Operator1<LoadNamedParameters>( // -- | 329 return new (zone()) Operator1<LoadNamedParameters>( // -- |
| 329 IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode | 330 IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode |
| 330 "JSLoadNamed", // name | 331 "JSLoadNamed", // name |
| 331 1, 1, 1, 1, 1, 0, // counts | 332 1, 1, 1, 1, 1, 2, // counts |
| 332 parameters); // parameter | 333 parameters); // parameter |
| 333 } | 334 } |
| 334 | 335 |
| 335 | 336 |
| 336 const Operator* JSOperatorBuilder::LoadProperty( | 337 const Operator* JSOperatorBuilder::LoadProperty( |
| 337 const VectorSlotPair& feedback) { | 338 const VectorSlotPair& feedback) { |
| 338 LoadPropertyParameters parameters(feedback); | 339 LoadPropertyParameters parameters(feedback); |
| 339 return new (zone()) Operator1<LoadPropertyParameters>( // -- | 340 return new (zone()) Operator1<LoadPropertyParameters>( // -- |
| 340 IrOpcode::kJSLoadProperty, Operator::kNoProperties, // opcode | 341 IrOpcode::kJSLoadProperty, Operator::kNoProperties, // opcode |
| 341 "JSLoadProperty", // name | 342 "JSLoadProperty", // name |
| 342 2, 1, 1, 1, 1, 0, // counts | 343 2, 1, 1, 1, 1, 2, // counts |
| 343 parameters); // parameter | 344 parameters); // parameter |
| 344 } | 345 } |
| 345 | 346 |
| 346 | 347 |
| 347 const Operator* JSOperatorBuilder::StoreProperty(LanguageMode language_mode) { | 348 const Operator* JSOperatorBuilder::StoreProperty(LanguageMode language_mode) { |
| 348 if (is_strict(language_mode)) { | 349 if (is_strict(language_mode)) { |
| 349 return &cache_.kStorePropertyStrictOperator; | 350 return &cache_.kStorePropertyStrictOperator; |
| 350 } else { | 351 } else { |
| 351 return &cache_.kStorePropertySloppyOperator; | 352 return &cache_.kStorePropertySloppyOperator; |
| 352 } | 353 } |
| 353 UNREACHABLE(); | 354 UNREACHABLE(); |
| 354 return nullptr; | 355 return nullptr; |
| 355 } | 356 } |
| 356 | 357 |
| 357 | 358 |
| 358 const Operator* JSOperatorBuilder::StoreNamed(LanguageMode language_mode, | 359 const Operator* JSOperatorBuilder::StoreNamed(LanguageMode language_mode, |
| 359 const Unique<Name>& name) { | 360 const Unique<Name>& name) { |
| 360 StoreNamedParameters parameters(language_mode, name); | 361 StoreNamedParameters parameters(language_mode, name); |
| 361 return new (zone()) Operator1<StoreNamedParameters>( // -- | 362 return new (zone()) Operator1<StoreNamedParameters>( // -- |
| 362 IrOpcode::kJSStoreNamed, Operator::kNoProperties, // opcode | 363 IrOpcode::kJSStoreNamed, Operator::kNoProperties, // opcode |
| 363 "JSStoreNamed", // name | 364 "JSStoreNamed", // name |
| 364 2, 1, 1, 0, 1, 0, // counts | 365 2, 1, 1, 0, 1, 2, // counts |
| 365 parameters); // parameter | 366 parameters); // parameter |
| 366 } | 367 } |
| 367 | 368 |
| 368 | 369 |
| 369 const Operator* JSOperatorBuilder::DeleteProperty(LanguageMode language_mode) { | 370 const Operator* JSOperatorBuilder::DeleteProperty(LanguageMode language_mode) { |
| 370 return new (zone()) Operator1<LanguageMode>( // -- | 371 return new (zone()) Operator1<LanguageMode>( // -- |
| 371 IrOpcode::kJSDeleteProperty, Operator::kNoProperties, // opcode | 372 IrOpcode::kJSDeleteProperty, Operator::kNoProperties, // opcode |
| 372 "JSDeleteProperty", // name | 373 "JSDeleteProperty", // name |
| 373 2, 1, 1, 1, 1, 0, // counts | 374 2, 1, 1, 1, 1, 2, // counts |
| 374 language_mode); // parameter | 375 language_mode); // parameter |
| 375 } | 376 } |
| 376 | 377 |
| 377 | 378 |
| 378 const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index, | 379 const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index, |
| 379 bool immutable) { | 380 bool immutable) { |
| 380 ContextAccess access(depth, index, immutable); | 381 ContextAccess access(depth, index, immutable); |
| 381 return new (zone()) Operator1<ContextAccess>( // -- | 382 return new (zone()) Operator1<ContextAccess>( // -- |
| 382 IrOpcode::kJSLoadContext, Operator::kNoWrite, // opcode | 383 IrOpcode::kJSLoadContext, // opcode |
| 383 "JSLoadContext", // name | 384 Operator::kNoWrite | Operator::kNoThrow, // flags |
| 384 1, 1, 0, 1, 1, 0, // counts | 385 "JSLoadContext", // name |
| 385 access); // parameter | 386 1, 1, 0, 1, 1, 0, // counts |
| 387 access); // parameter |
| 386 } | 388 } |
| 387 | 389 |
| 388 | 390 |
| 389 const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) { | 391 const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) { |
| 390 ContextAccess access(depth, index, false); | 392 ContextAccess access(depth, index, false); |
| 391 return new (zone()) Operator1<ContextAccess>( // -- | 393 return new (zone()) Operator1<ContextAccess>( // -- |
| 392 IrOpcode::kJSStoreContext, Operator::kNoRead, // opcode | 394 IrOpcode::kJSStoreContext, // opcode |
| 393 "JSStoreContext", // name | 395 Operator::kNoRead | Operator::kNoThrow, // flags |
| 394 2, 1, 1, 0, 1, 0, // counts | 396 "JSStoreContext", // name |
| 395 access); // parameter | 397 2, 1, 1, 0, 1, 0, // counts |
| 398 access); // parameter |
| 396 } | 399 } |
| 397 | 400 |
| 398 | 401 |
| 399 const Operator* JSOperatorBuilder::CreateCatchContext( | 402 const Operator* JSOperatorBuilder::CreateCatchContext( |
| 400 const Unique<String>& name) { | 403 const Unique<String>& name) { |
| 401 return new (zone()) Operator1<Unique<String>>( // -- | 404 return new (zone()) Operator1<Unique<String>>( // -- |
| 402 IrOpcode::kJSCreateCatchContext, Operator::kNoProperties, // opcode | 405 IrOpcode::kJSCreateCatchContext, Operator::kNoProperties, // opcode |
| 403 "JSCreateCatchContext", // name | 406 "JSCreateCatchContext", // name |
| 404 2, 1, 1, 1, 1, 0, // counts | 407 2, 1, 1, 1, 1, 2, // counts |
| 405 name); // parameter | 408 name); // parameter |
| 406 } | 409 } |
| 407 | 410 |
| 408 } // namespace compiler | 411 } // namespace compiler |
| 409 } // namespace internal | 412 } // namespace internal |
| 410 } // namespace v8 | 413 } // namespace v8 |
| OLD | NEW |