From 0b7a29e4d187c4b34159118f65411c3f90763fed Mon Sep 17 00:00:00 2001
From: Mick Jordan <mick.jordan@oracle.com>
Date: Thu, 11 Feb 2016 11:15:20 -0800
Subject: [PATCH] fix debug(f) error when f is duplicated

---
 .../r/nodes/function/FunctionDefinitionNode.java      | 11 ++++++++---
 .../truffle/r/nodes/instrument/RInstrument.java       |  8 +++++---
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionDefinitionNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionDefinitionNode.java
index b156a78e61..d4d5b08c15 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionDefinitionNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionDefinitionNode.java
@@ -91,7 +91,7 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo
      * unknown.
      */
     private String description;
-    private final FunctionUID uuid;
+    private FunctionUID uuid;
     private boolean instrumented = false;
 
     @Child private FrameSlotNode onExitSlot;
@@ -163,9 +163,14 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo
     @Override
     public RRootNode duplicateWithNewFrameDescriptor() {
         FrameDescriptor frameDesc = new FrameDescriptor();
+        FunctionUID thisUuid = uuid;
         FrameSlotChangeMonitor.initializeFunctionFrameDescriptor(description != null && !description.isEmpty() ? description : "<function>", frameDesc);
-        return new FunctionDefinitionNode(getSourceSection(), frameDesc, (BodyNode) body.unwrap().deepCopy(), getFormalArguments(), description, substituteFrame, argPostProcess == null ? null
-                        : argPostProcess.deepCopyUnconditional());
+        FunctionDefinitionNode result = new FunctionDefinitionNode(getSourceSection(), frameDesc, (BodyNode) body.unwrap().deepCopy(), getFormalArguments(), description, substituteFrame,
+                        argPostProcess == null ? null
+                                        : argPostProcess.deepCopyUnconditional());
+        // Instrumentation depends on this copy having same uuid
+        result.uuid = thisUuid;
+        return result;
     }
 
     private static boolean containsAnyDispatch(BodyNode body) {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/instrument/RInstrument.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/instrument/RInstrument.java
index eed2ebdcb5..43b772dbf7 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/instrument/RInstrument.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/instrument/RInstrument.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -216,8 +216,10 @@ public class RInstrument {
     public static void registerFunctionDefinition(FunctionDefinitionNode fdn) {
         FunctionUID uid = fdn.getUID();
         FunctionData fd = functionMap.get(uid);
-        assert fd == null;
-        functionMap.put(uid, new FunctionData(uid, fdn));
+        // Owing to FDN duplication, fdn may be registered multiple times
+        if (fd == null) {
+            functionMap.put(uid, new FunctionData(uid, fdn));
+        }
     }
 
     public static FunctionIdentification getFunctionIdentification(FunctionUID uid) {
-- 
GitLab