Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 1663323003: [fullcode] Change fullcode to compile finally using the token approach. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address review comments Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/full-codegen/arm/full-codegen-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/ast-graph-builder.h" 5 #include "src/compiler/ast-graph-builder.h"
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/compiler.h" 8 #include "src/compiler.h"
9 #include "src/compiler/ast-loop-assignment-analyzer.h" 9 #include "src/compiler/ast-loop-assignment-analyzer.h"
10 #include "src/compiler/control-builders.h" 10 #include "src/compiler/control-builders.h"
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 int context_length() const { return context_length_; } 199 int context_length() const { return context_length_; }
200 int stack_height() const { return stack_height_; } 200 int stack_height() const { return stack_height_; }
201 201
202 private: 202 private:
203 AstGraphBuilder* builder_; 203 AstGraphBuilder* builder_;
204 ControlScope* outer_; 204 ControlScope* outer_;
205 int context_length_; 205 int context_length_;
206 int stack_height_; 206 int stack_height_;
207 }; 207 };
208 208
209
210 // Helper class for a try-finally control scope. It can record intercepted 209 // Helper class for a try-finally control scope. It can record intercepted
211 // control-flow commands that cause entry into a finally-block, and re-apply 210 // control-flow commands that cause entry into a finally-block, and re-apply
212 // them after again leaving that block. Special tokens are used to identify 211 // them after again leaving that block. Special tokens are used to identify
213 // paths going through the finally-block to dispatch after leaving the block. 212 // paths going through the finally-block to dispatch after leaving the block.
214 class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject { 213 class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject {
215 public: 214 public:
216 explicit DeferredCommands(AstGraphBuilder* owner) 215 explicit DeferredCommands(AstGraphBuilder* owner)
217 : owner_(owner), deferred_(owner->local_zone()) {} 216 : owner_(owner),
217 deferred_(owner->local_zone()),
218 return_token_(nullptr),
219 throw_token_(nullptr) {}
218 220
219 // One recorded control-flow command. 221 // One recorded control-flow command.
220 struct Entry { 222 struct Entry {
221 Command command; // The command type being applied on this path. 223 Command command; // The command type being applied on this path.
222 Statement* statement; // The target statement for the command or {nullptr}. 224 Statement* statement; // The target statement for the command or {nullptr}.
223 Node* token; // A token identifying this particular path. 225 Node* token; // A token identifying this particular path.
224 }; 226 };
225 227
226 // Records a control-flow command while entering the finally-block. This also 228 // Records a control-flow command while entering the finally-block. This also
227 // generates a new dispatch token that identifies one particular path. 229 // generates a new dispatch token that identifies one particular path.
228 Node* RecordCommand(Command cmd, Statement* stmt, Node* value) { 230 Node* RecordCommand(Command cmd, Statement* stmt, Node* value) {
229 Node* token = NewPathTokenForDeferredCommand(); 231 Node* token = nullptr;
232 switch (cmd) {
233 case CMD_BREAK:
234 case CMD_CONTINUE:
235 token = NewPathToken(dispenser_.GetBreakContinueToken());
236 break;
237 case CMD_THROW:
238 if (throw_token_) return throw_token_;
239 token = NewPathToken(TokenDispenserForFinally::kThrowToken);
240 throw_token_ = token;
241 break;
242 case CMD_RETURN:
243 if (return_token_) return return_token_;
244 token = NewPathToken(TokenDispenserForFinally::kReturnToken);
245 return_token_ = token;
246 break;
247 }
248 DCHECK_NOT_NULL(token);
230 deferred_.push_back({cmd, stmt, token}); 249 deferred_.push_back({cmd, stmt, token});
231 return token; 250 return token;
232 } 251 }
233 252
234 // Returns the dispatch token to be used to identify the implicit fall-through 253 // Returns the dispatch token to be used to identify the implicit fall-through
235 // path at the end of a try-block into the corresponding finally-block. 254 // path at the end of a try-block into the corresponding finally-block.
236 Node* GetFallThroughToken() { return NewPathTokenForImplicitFallThrough(); } 255 Node* GetFallThroughToken() { return NewPathTokenForImplicitFallThrough(); }
237 256
238 // Applies all recorded control-flow commands after the finally-block again. 257 // Applies all recorded control-flow commands after the finally-block again.
239 // This generates a dynamic dispatch on the token from the entry point. 258 // This generates a dynamic dispatch on the token from the entry point.
240 void ApplyDeferredCommands(Node* token, Node* value) { 259 void ApplyDeferredCommands(Node* token, Node* value) {
241 SwitchBuilder dispatch(owner_, static_cast<int>(deferred_.size())); 260 SwitchBuilder dispatch(owner_, static_cast<int>(deferred_.size()));
242 dispatch.BeginSwitch(); 261 dispatch.BeginSwitch();
243 for (size_t i = 0; i < deferred_.size(); ++i) { 262 for (size_t i = 0; i < deferred_.size(); ++i) {
244 Node* condition = NewPathDispatchCondition(token, deferred_[i].token); 263 Node* condition = NewPathDispatchCondition(token, deferred_[i].token);
245 dispatch.BeginLabel(static_cast<int>(i), condition); 264 dispatch.BeginLabel(static_cast<int>(i), condition);
246 dispatch.EndLabel(); 265 dispatch.EndLabel();
247 } 266 }
248 for (size_t i = 0; i < deferred_.size(); ++i) { 267 for (size_t i = 0; i < deferred_.size(); ++i) {
249 dispatch.BeginCase(static_cast<int>(i)); 268 dispatch.BeginCase(static_cast<int>(i));
250 owner_->execution_control()->PerformCommand( 269 owner_->execution_control()->PerformCommand(
251 deferred_[i].command, deferred_[i].statement, value); 270 deferred_[i].command, deferred_[i].statement, value);
252 dispatch.EndCase(); 271 dispatch.EndCase();
253 } 272 }
254 dispatch.EndSwitch(); 273 dispatch.EndSwitch();
255 } 274 }
256 275
257 protected: 276 protected:
258 Node* NewPathTokenForDeferredCommand() { 277 Node* NewPathToken(int token_id) {
259 return owner_->jsgraph()->Constant(static_cast<int>(deferred_.size())); 278 return owner_->jsgraph()->Constant(token_id);
260 } 279 }
261 Node* NewPathTokenForImplicitFallThrough() { 280 Node* NewPathTokenForImplicitFallThrough() {
262 return owner_->jsgraph()->Constant(-1); 281 return NewPathToken(TokenDispenserForFinally::kFallThroughToken);
263 } 282 }
264 Node* NewPathDispatchCondition(Node* t1, Node* t2) { 283 Node* NewPathDispatchCondition(Node* t1, Node* t2) {
265 // TODO(mstarzinger): This should be machine()->WordEqual(), but our Phi 284 // TODO(mstarzinger): This should be machine()->WordEqual(), but our Phi
266 // nodes all have kRepTagged|kTypeAny, which causes representation mismatch. 285 // nodes all have kRepTagged|kTypeAny, which causes representation mismatch.
267 return owner_->NewNode(owner_->javascript()->StrictEqual(), t1, t2); 286 return owner_->NewNode(owner_->javascript()->StrictEqual(), t1, t2);
268 } 287 }
269 288
270 private: 289 private:
290 TokenDispenserForFinally dispenser_;
271 AstGraphBuilder* owner_; 291 AstGraphBuilder* owner_;
272 ZoneVector<Entry> deferred_; 292 ZoneVector<Entry> deferred_;
293 Node* return_token_;
294 Node* throw_token_;
273 }; 295 };
274 296
275 297
276 // Control scope implementation for a BreakableStatement. 298 // Control scope implementation for a BreakableStatement.
277 class AstGraphBuilder::ControlScopeForBreakable : public ControlScope { 299 class AstGraphBuilder::ControlScopeForBreakable : public ControlScope {
278 public: 300 public:
279 ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target, 301 ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target,
280 ControlBuilder* control) 302 ControlBuilder* control)
281 : ControlScope(owner), target_(target), control_(control) {} 303 : ControlScope(owner), target_(target), control_(control) {}
282 304
(...skipping 1197 matching lines...) Expand 10 before | Expand all | Expand 10 after
1480 // - ReturnStatement: It represents the return value being returned. 1502 // - ReturnStatement: It represents the return value being returned.
1481 // - ThrowStatement: It represents the exception being thrown. 1503 // - ThrowStatement: It represents the exception being thrown.
1482 // - BreakStatement/ContinueStatement: Filled with the hole. 1504 // - BreakStatement/ContinueStatement: Filled with the hole.
1483 // - Falling through into finally-block: Filled with the hole. 1505 // - Falling through into finally-block: Filled with the hole.
1484 Node* result = try_control.GetResultValueNode(); 1506 Node* result = try_control.GetResultValueNode();
1485 Node* token = try_control.GetDispatchTokenNode(); 1507 Node* token = try_control.GetDispatchTokenNode();
1486 1508
1487 // The result value, dispatch token and message is expected on the operand 1509 // The result value, dispatch token and message is expected on the operand
1488 // stack (this is in sync with FullCodeGenerator::EnterFinallyBlock). 1510 // stack (this is in sync with FullCodeGenerator::EnterFinallyBlock).
1489 Node* message = NewNode(javascript()->LoadMessage()); 1511 Node* message = NewNode(javascript()->LoadMessage());
1490 environment()->Push(token); // TODO(mstarzinger): Cook token! 1512 environment()->Push(token);
1491 environment()->Push(result); 1513 environment()->Push(result);
1492 environment()->Push(message); 1514 environment()->Push(message);
1493 1515
1494 // Clear message object as we enter the finally block. 1516 // Clear message object as we enter the finally block.
1495 Node* the_hole = jsgraph()->TheHoleConstant(); 1517 Node* the_hole = jsgraph()->TheHoleConstant();
1496 NewNode(javascript()->StoreMessage(), the_hole); 1518 NewNode(javascript()->StoreMessage(), the_hole);
1497 1519
1498 // Evaluate the finally-block. 1520 // Evaluate the finally-block.
1499 Visit(stmt->finally_block()); 1521 Visit(stmt->finally_block());
1500 try_control.EndFinally(); 1522 try_control.EndFinally();
1501 1523
1502 // The result value, dispatch token and message is restored from the operand 1524 // The result value, dispatch token and message is restored from the operand
1503 // stack (this is in sync with FullCodeGenerator::ExitFinallyBlock). 1525 // stack (this is in sync with FullCodeGenerator::ExitFinallyBlock).
1504 message = environment()->Pop(); 1526 message = environment()->Pop();
1505 result = environment()->Pop(); 1527 result = environment()->Pop();
1506 token = environment()->Pop(); // TODO(mstarzinger): Uncook token! 1528 token = environment()->Pop();
1507 NewNode(javascript()->StoreMessage(), message); 1529 NewNode(javascript()->StoreMessage(), message);
1508 1530
1509 // Dynamic dispatch after the finally-block. 1531 // Dynamic dispatch after the finally-block.
1510 commands->ApplyDeferredCommands(token, result); 1532 commands->ApplyDeferredCommands(token, result);
1511 1533
1512 // TODO(mstarzinger): Remove bailout once everything works. 1534 // TODO(mstarzinger): Remove bailout once everything works.
1513 if (!FLAG_turbo_try_finally) SetStackOverflow(); 1535 if (!FLAG_turbo_try_finally) SetStackOverflow();
1514 } 1536 }
1515 1537
1516 1538
(...skipping 2825 matching lines...) Expand 10 before | Expand all | Expand 10 after
4342 // Phi does not exist yet, introduce one. 4364 // Phi does not exist yet, introduce one.
4343 value = NewPhi(inputs, value, control); 4365 value = NewPhi(inputs, value, control);
4344 value->ReplaceInput(inputs - 1, other); 4366 value->ReplaceInput(inputs - 1, other);
4345 } 4367 }
4346 return value; 4368 return value;
4347 } 4369 }
4348 4370
4349 } // namespace compiler 4371 } // namespace compiler
4350 } // namespace internal 4372 } // namespace internal
4351 } // namespace v8 4373 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/full-codegen/arm/full-codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698